Errors
// conventional HTTP status codes + a typed error body
Read the solve status as well as the HTTP status. 202 returns a pending solve after async submission or when the synchronous HTTP wait ends; 200 can return a solved result, a retrieved pending or failed result, or an idempotent replay. Non-2xx responses carry error.code; a proxy error can be 502. Poll a pending solve's id rather than submitting another request.
| Status | error.code | Meaning |
|---|---|---|
| 200 | — | Solve returned. Check status before using token. |
| 202 | — | Solve pending, including after the synchronous HTTP wait ends. Retrieve its id until status leaves pending. |
| 401 | invalid_key | Missing or revoked API key. |
| 402 | balance_empty | Out of credit. Top up from the dashboard. |
| 402 | pass_expired | The unlimited pass this key is attached to has ended. Renew the pass, or switch the key back to credit metering, in the dashboard. Expiry is a hard stop — we never quietly spend your credit balance instead. |
| 403 | forbidden_target | This target host isn't permitted by our acceptable-use policy. |
| 422 | unknown_sitekey | The sitekey/url pair didn't resolve to a live gate. |
| 429 | rate_limited | Above your workspace's req/s limit. Back off and retry. |
| 502 | user_proxy_error | The proxy you supplied refused or dropped the connection to the target. Check its credentials, allowlist and egress region — or omit proxy to use our pool. Not billed. |
| 503 | maintenance | Solving is paused for platform maintenance. Not billed — retry shortly. |
| 503 | target_unavailable | Too many of your recent solves for this target failed, so attempts are paused briefly. Check the target and your proxy, then retry. Not billed. |
| 504 | solve_timeout | The solve failed to clear the gate within its budget. Not billed. The failed solve stays terminal; a new submission starts new work. |
{
"error": {
"code": "unknown_sitekey",
"message": "No live Turnstile gate at that sitekey + url.",
"billed": false
}
}These are our codes. The strings Cloudflare's own widget reports to your error-callback — 300030, 600010, 110200 — are a separate namespace that never reaches this API; they are indexed at the Turnstile error reference. If a 5xx repeats for one target, or a 4xx arrives with an error.code the table above does not list, that is ours to explain rather than yours to work around — send us the solve id and we will trace it.
Ready to pour through the gate?
// free sandbox keys · no card required to start