Skip to content

Cloudflare Turnstile

Submit a Cloudflare Turnstile Token: Form Fields and Callbacks

Where a solved Turnstile token goes: the cf-turnstile-response field, the widget's callback, or a JSON body. With examples for forms, fetch and browsers.

3 min readPublished Updated

A solved task gives you a token. The site will only accept it if it arrives the way the page itself would have sent it: in the right field, in the right request, while it is still valid. This guide covers the three ways sites collect Turnstile tokens and how to submit a solved token in each case.

1. A plain form: cf-turnstile-response

With Turnstile’s implicit rendering, the widget adds a hidden input to the form it sits in:

<input type="hidden" name="cf-turnstile-response" value="0.xT4…">

When the visitor submits the form, the browser posts the token with the other fields. The site’s server reads cf-turnstile-response and verifies it with Cloudflare’s siteverify endpoint.

To submit a solved token from an HTTP client, post the form fields yourself and include the token under that name:

import requests
session = requests.Session()
response = session.post(
"https://shop.example.com/login",
data={
"email": "user@example.com",
"password": "…",
"cf-turnstile-response": token,
},
timeout=15,
)

Some sites rename the field with the widget’s data-response-field-name option, and some forms also carry a CSRF token that must come from the same session. Load the form page first with the same client, copy any hidden fields, then post.

2. A widget callback

With explicit rendering, the page passes a callback to turnstile.render(), and the widget calls it with the token:

turnstile.render("#captcha", {
sitekey: "0x4AAAAAAAB1cD2eF3gH4iJ5",
callback: (token) => {
document.querySelector("#login").dataset.token = token;
enableSubmit();
},
});

In a browser you drive with Playwright, Puppeteer or Selenium, you can hand the solved token to the page the same way: set the hidden input, or call the function the callback would have called. The Playwright and Puppeteer pages show both, step by step.

await page.evaluate((token) => {
const input = document.querySelector('input[name="cf-turnstile-response"]');
if (input) input.value = token;
}, token);
await page.click('button[type="submit"]');

3. A JSON request from the page’s code

Single-page apps often send the token in a JSON body or a header, under a name of their choosing, such as captchaToken or turnstile. There is no standard. The reliable way to find it is to submit the form once by hand with the browser’s developer tools open, find the request in the Network tab, and copy its shape.

await fetch("https://shop.example.com/api/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, password, captchaToken: token }),
});

Getting the token in the first place

Every example above assumes you already have token. With ZeroCaptcha you get it by creating a task with the page URL and sitekey, then polling getTaskResult until status is ready, and reading solution.token. The quickstart has a complete program in four languages; the Cloudflare Turnstile solver page has samples for ten languages and tools.

If the widget sets an action or cData, send them with the task, or the site may reject the token on verification: see Cloudflare Turnstile action and cData.

Timing

Submit as soon as the token is ready. A token works once and expires 300 seconds after it is issued, and every result tells you when with expiresAt. If the site rejects a submission for another reason, such as a wrong password, get a new token before trying again: the first one has been redeemed. Cloudflare Turnstile token expiry explains why.

When the site still says no

  • The token arrived late. Compare expiresAt with the time you posted the form.
  • The field name is wrong. Check one real submission in the Network tab.
  • The action differs. The site may check that the token was issued for the action it expected.
  • Other fields are missing. CSRF tokens, cookies from the form page, or a required header.

None of these costs you more than the task itself: ZeroCaptcha charges only for tokens it solved, and a task that fails costs nothing.

Questions

What is the cf-turnstile-response field?

It is the hidden form input the Turnstile widget fills with its token. A normal form post sends it to the site's server, which verifies it with Cloudflare.

The site posts JSON instead of a form. Where does the token go?

Wherever the page's own code puts it. Watch one real submission in the browser's Network tab and copy the field name it uses.

Do I need to send the same user agent as the solver?

Turnstile tokens are verified by the site's server with Cloudflare; ZeroCaptcha's result has no user agent to match. Submit the token with your client's normal headers.

Read next

This guide is part of the Cloudflare Turnstile solver hub. Every task is charged only when a token is ready.

Get an API key