How a task works
More
A task is one request to solve one challenge: a Turnstile widget, or a Cloudflare challenge page. This page follows a task from the moment you create it to the moment its token is deleted, and says what your balance does at each step. It is the same whichever format you create the task in.
The life of a task
Section titled “The life of a task”- Created: the task is
queued, its price held. - Taken on: a solver node starts an attempt, and the task is
running. - Ended: solved, it is
succeeded; not solved with attempts and time left, it goes back toqueuedfor another attempt; not solved after its last attempt, it isfailed; still unsolved at its deadline, queued or running, it isexpired.
status |
What it means | Final |
|---|---|---|
queued |
Waiting for a solver with room. A task being retried is back here. | No |
running |
A solver node is working on it. | No |
succeeded |
Solved. The token is in the task while it is valid, and the price is charged. | Yes |
failed |
Not solved: every attempt failed, or a check before an attempt refused it. Nothing is charged. | Yes |
expired |
Not solved before its deadline. Nothing is charged. | Yes |
Only these moves happen: queued to running, running back to queued for a retry, and
queued or running to one of the three final states. A final state never changes.
Timing
Section titled “Timing”- The deadline. Every task has one, in its
deadlinefield: 150 seconds after it was created, by default. A task still unsolved then expires withERROR_TASK_TIMEOUT. - Attempts. A task gets up to 3 solve attempts by default (its
maxAttempts), andattemptssays how many it has had. An attempt counts once a solver node took the work on; time spent waiting for a node with room counts toward the deadline, not the attempts. A task is not retried with less than 5 seconds left before its deadline. - Checks before each attempt. Before every attempt the page’s domain is checked against the
blocklist, the account against suspension, and a proxy’s name is resolved again and must still
be public. A task that fails one of these ends
failedwithERROR_DOMAIN_BLOCKED,ERROR_ACCOUNT_SUSPENDEDorERROR_PROXY_NOT_ALLOWED. An owner who deletes the account cancels its queued tasks at once, withERROR_ACCOUNT_DELETED. - How long it takes. It depends on the site and the solvers’ load; the status page shows the median time to a token over the last 24 hours. Read the task every 2 seconds, or have us call you back.
The token
Section titled “The token”A solved task carries its result in solution:
| Task | solution.token |
Valid for |
|---|---|---|
| Turnstile | The token for the page’s cf-turnstile-response field or the widget’s callback |
300 seconds from tokenIssuedAt, once: Cloudflare accepts each token one time |
| Challenge page | The cf_clearance cookie’s value, with solution.userAgent and solution.cookie |
As long as the site’s Challenge Passage allows (30 minutes by default); we serve it for 30 minutes |
tokenExpiresAt says until when the token is served. tokenState says where it stands:
tokenState |
Meaning |
|---|---|
pending |
The task has not finished yet. |
available |
Solved, and the token is valid: reading the task returns it. |
expired |
Solved, but its lifetime has passed. The task stays charged. |
deleted |
Solved, and the token was deleted, 10 minutes after it expired. |
none |
The task failed or expired, so there is no token. |
Use a token as soon as you have it. A Turnstile token read after it expired cannot be renewed: the
REST API shows tokenState: "expired" and no solution, and getTaskResult answers
ERROR_TOKEN_EXPIRED. Either way, the task succeeded and stays charged.
What is charged, and when
Section titled “What is charged, and when”| When | Your balance |
|---|---|
| You create a task | Its price is held: available goes down by the price, held goes up by it. |
| It succeeds | The hold becomes a charge, once. cost on the task becomes its price. |
| It fails or expires | The hold is released in full. cost stays 0.000000. |
| A request is refused | Nothing is held or charged, whatever the code. |
- A task is charged the price in effect when it was created, which the task shows as
price. Prices are public atGET /v1/pricesand on the pricing page. - A task your balance cannot cover is refused before it starts, with
insufficient_funds. Prices held for running tasks count against your balance. - A key with a daily spend cap counts what its tasks hold or were charged that UTC day.
- Each task settles exactly once: a solver that answers twice, or a worker that restarts, can never charge a task twice or release it after it was charged.
Creating the same task twice
Section titled “Creating the same task twice”Send an Idempotency-Key header with every create, one new value per task. If a reply is lost and
you send the same request again with the same key within 24 hours, you get the first reply, with
the same task, instead of a second task and a second charge. See
Errors and retries.
How long tasks are kept
Section titled “How long tasks are kept”Tasks stay in your task log and in the API for about 90 days: records are deleted a month at a time, once the month they were created in ended more than 90 days ago. A proxy’s password is deleted as soon as its task finishes, and a token 10 minutes after it expires. Your monthly usage totals stay.