Cloudflare Turnstile API
EndCaptcha solves Cloudflare Turnstile challenges through the same API used for image CAPTCHAs: you submit the widget details, poll for the result, and receive a token that you then submit on the target page. Start from the API hub if you are new to the service, and see the API reference for the image CAPTCHA endpoints this page builds on.
Before integrating, read what a Turnstile challenge is and what the target page exposes.
How it works
- Send a POST request to http://api.endcaptcha.com/upload with your credentials, type=12 and a turnstile_params JSON payload.
- Read the CAPTCHA id from the upload response.
- Poll http://api.endcaptcha.com/poll/<CAPTCHA_ID> every 3 seconds until the token comes back.
- Submit the returned token on the target page.
POST parameters
- username - your EndCaptcha username.
- password - your EndCaptcha password.
- type - 12, the value that marks this as a Turnstile challenge.
- turnstile_params - a JSON string with the widget details below.
turnstile_params fields
- sitekey - the Turnstile site key of the target site. It is the data-sitekey attribute of the widget, a property in the page script, or part of the widget iframe address.
- pageurl - the full URL of the page that loads the widget, including its path: if the widget is at https://example.com/register, send that address, not the domain root.
- action - optional. The value of the widget action, from data-action or the turnstile.render call.
- proxy and proxytype - optional but recommended, HTTP proxies only. A proxy keeps the address that solves the challenge and the address that submits the form consistent, which avoids rejections by the page.
{
"sitekey": "0x4AAAAAAAGlwMzq_9z6S9Mh",
"pageurl": "https://example.com/register",
"action": "login",
"proxy": "http://user:[email protected]:3128",
"proxytype": "HTTP"
}
Response
The polling call answers with the token when the challenge is solved. Until then it answers ? while a solver is working on it or UNSOLVED_YET while it waits in queue. The token is valid for a single use and expires in about two minutes. Submit it in the input named cf-turnstile-response, in the widget callback, or in g-recaptcha-response when the page runs the widget in reCAPTCHA compatibility mode.
Example
import json
from endcaptcha import HttpClient
client = HttpClient('YOUR_USERNAME', 'YOUR_PASSWORD')
payload = json.dumps({
'sitekey': '0x4AAAAAAAGlwMzq_9z6S9Mh',
'pageurl': 'https://example.com/register',
})
captcha = client.decode(type=12, turnstile_params=payload)
if captcha.get('text'):
print('Turnstile token: %s' % captcha.get('text'))
The same flow works in the official clients shipped from the API documentation page.
Turnstile API FAQ
Where do I find the site key?
In the page source: the widget element carries it as
data-sitekey, the page script exposes it as a property, and the
widget iframe address contains it as well.
Which proxy types are supported?
HTTP proxies only, and only when you send them with the payload.
What does a solved Turnstile cost?
It is charged in credits like every other CAPTCHA, and some types cost
more credits than others. The packages and their credit prices are on
the pricing block of the home page.
Do I pay for a challenge that solved incorrectly?
No. Report it from your account and it is not billed, as described in
the FAQ.

