API Reference
A single endpoint that classifies an incoming request as a genuine visitor or an automated client (crawler or datacenter). An upstream reverse proxy calls it on each request and decides whether to serve the real page or a neutral placeholder.
For every incoming request, the proxy sends a subrequest to the endpoint. The HTTP status is the verdict:
The endpoint runs in two modes. In proxy mode (default) the verdict is the status code, suitable for auth_request / forward_auth. In data mode (?format=json) it returns the verdict as JSON. Both modes set the X-Cloak and X-Cloak-Reason headers.
| Mode | Verdict | Response | Headers |
|---|---|---|---|
| Proxy | Allow | 204 empty body | X-Cloak: 0 |
| Proxy | Block | 403 placeholder page | X-Cloak: 1X-Cloak-Reason |
| Data ?format=json |
Either | 200 { cloak, reason, ip, ua } | X-Cloak: 0|1 |
cloak — boolean verdict. reason — one of null, bot-ua, or datacenter. ip / ua — the values the verdict was evaluated against.
# crawler user-agent
GET /cloak/check?format=json&ua=facebookexternalhit
→ { "cloak": true, "reason": "bot-ua", "ip": "203.0.113.10", "ua": "facebookexternalhit" }
# genuine visitor
→ { "cloak": false, "reason": null, "ip": "203.0.113.10", "ua": "Mozilla/5.0 (iPhone)" }
The IP and user-agent are resolved from the request. The first non-empty source wins, so the endpoint works both as a proxy subrequest and as a direct call. An empty or absent user-agent is treated as a bot.
Set to json to receive the verdict as a JSON body with a 200 status instead of the proxy-mode status code.
Point your reverse proxy at the endpoint. A 2xx lets the request through; a 403 means serve the placeholder.
your-site.com {
forward_auth cloak.mflgrowth.com:443 {
uri /cloak/check
transport http { tls; tls_server_name cloak.mflgrowth.com }
header_up Host cloak.mflgrowth.com
header_up X-Real-IP {remote_host}
copy_headers X-Cloak X-Cloak-Reason
}
reverse_proxy 127.0.0.1:3000 # your real site
}
location / {
auth_request /__cloak;
error_page 403 =200 @cloak_decoy;
proxy_pass http://127.0.0.1:3000; # your real site
}
location = /__cloak {
internal;
proxy_pass https://cloak.mflgrowth.com/cloak/check;
proxy_ssl_server_name on;
proxy_set_header Host cloak.mflgrowth.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
}
location @cloak_decoy {
proxy_pass https://cloak.mflgrowth.com/cloak/decoy;
proxy_ssl_server_name on;
proxy_set_header Host cloak.mflgrowth.com;
}
GET /cloak/decoy returns the placeholder page with a 200 status. nginx discards the auth_request body, so the placeholder is served from there via error_page.