CAPTCHA types · turnstile
Cloudflare Turnstile Solver API
Create authorized Cloudflare Turnstile tasks with the SolveHub solver API: send websiteURL and websiteKey, optional cdata/action and proxy, poll the task and receive a response token. Compare this with official test keys first.
For authorized QA automation and browser integration. Use only on websites and workflows you have permission to test.
POST /v1/tasks with Authorization: Bearer <API_KEY>, Content-Type: application/json and an Idempotency-Key. Check availability in live prices first; see the quick start for the full create-and-poll flow.This page is the field reference for the Turnstile solver API. Creating a task exercises a real Turnstile challenge on a page you are authorized to test; it is not the same as testing your own widget. If you only need to verify your own form or CI flow, use Cloudflare's official test sitekey and test secret instead — see how to test Cloudflare Turnstile for the comparison, and check live prices before creating a paid task.
Requires the full target page address websiteURL and the page's Turnstile websiteKey (usually the widget's sitekey). Include cdata or action only when the page explicitly uses them; both are optional strings. A custom HTTP proxy is optional; if provided, you must supply the address, a string port, and optional credentials together.
Browser selection
Optional useragent (512 bytes maximum) selects Chrome/Chromium or Firefox and a Windows, macOS, Linux, Android or iOS profile. Turnstile selects family and platform; the service chooses the version. Supplying this field or a custom proxy uses a dedicated browser. The result remains a token in solution.value.
Request fields
The outer type and task are required; all task.* paths below are inside the task object. Field names are case-sensitive. Length limits are measured in UTF-8 bytes.
| Field | Type | Required | Limit | Description |
|---|---|---|---|---|
type |
String | Yes | Must be turnstile |
Platform task type. |
task |
JSON object | Yes | ≤ 7 MiB | Task parameters for this type. |
task.type |
String | No | Must be turnstile if provided |
Compatibility with the legacy request format; can be omitted in new integrations. |
task.websiteURL |
HTTP(S) URL | Yes | ≤ 2048 bytes | Full URL of the target page to solve, without username or password. |
task.websiteKey |
String | Yes | ≤ 256 bytes | Turnstile sitekey of the target widget. |
task.cdata |
String | No | ≤ 4096 bytes | The widget's cdata, if the target widget provides one. |
task.action |
String | No | ≤ 4096 bytes | The widget's action, if the target widget provides one. |
task.useragent |
String | No | ≤ 512 bytes | Browser selector; replay cookies with the returned solution.useragent. |
task.proxyType |
String | No | http only |
Proxy protocol; must be http if provided. |
task.proxyAddress |
String | No | ≤ 256 bytes | Proxy IP or hostname; must be provided together with proxyPort. |
task.proxyPort |
String | No | 1–5 bytes, value 1–65535 | Proxy port; must be a quoted numeric string. |
task.proxyLogin |
String | No | ≤ 256 bytes | Username if the proxy requires authentication; must not be provided without the address and port. |
task.proxyPassword |
String | No | ≤ 256 bytes | Password if the proxy requires authentication; must not be provided without the address and port. |
Create request example
{
"type": "turnstile",
"task": {
"websiteURL": "https://example.com/login",
"websiteKey": "0x4AAAAAAA_EXAMPLE"
}
}
cURL call
Replace the Key, site information, and proxy in the example with your actual values; keep the Idempotency-Key unchanged for the same business request.
curl -sS -X POST 'https://www.tiam.codes/v1/tasks' \
-H 'Authorization: Bearer sh_REPLACE_ME' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: example-turnstile-0001' \
--data-binary @- <<'JSON'
{
"type": "turnstile",
"task": {
"websiteURL": "https://example.com/login",
"websiteKey": "0x4AAAAAAA_EXAMPLE"
}
}
JSON
Create response and polling
A successful creation returns HTTP 202, and the initial status is usually queued. Save the taskId and call GET /v1/tasks/{taskId} roughly every 2–3 seconds. The soft processing time limit for this type is 180 seconds; after the soft limit the task may enter uncertain. Results of accepted tasks can still be verified; clients should not blindly recreate the task with a new Idempotency-Key.
Result fields
Read solution only when status=completed; the table below lists common fields, and the actual fields are those in the task's response.
| Field | Type | How to read |
|---|---|---|
solution.value |
String | Turnstile token that can be submitted to the target's verification flow. |
After completed, take the response token from solution.value, for example {"value":"0.EXAMPLE_TOKEN"}. Pass the token to your own site's backend to complete verification or subsequent business requests; do not treat the token as a cookie. If the target widget has an action or cdata, the values submitted must match the target page's actual values.
Failures and troubleshooting
A missing sitekey, an invalid URL, or unpaired proxy fields return 400 INVALID_TASK; if the target widget uses action/cdata, submit the page's real values.
Common errors on create requests are 400 INVALID_TASK, 402 INSUFFICIENT_BALANCE, 429 TASK_LIMIT_EXCEEDED, and 503 TYPE_UNAVAILABLE. When a created task fails, the public error code is TASK_FAILED or TASK_TIMEOUT; uncertain corresponds to TASK_UNCERTAIN. See the Platform API reference for details.
The processing window starts after task creation is confirmed; queue waiting does not consume it. The current node timeout is approximately 130 seconds; the platform allows a 180-second soft window for transport and result polling.
Related documentation
Last updated: