2Captcha format API
More
2Captcha's in.php and res.php for Turnstile, so a 2Captcha client works after changing only its base URL and key. Priced and charged as the other dialects are. Every reply is HTTP 200, as plain text or, with `json=1`, JSON; only a failure outside the endpoint is a problem document.
Every operation of the API reference is generated from the contract the API serves, version 0.1.0. Replace YOUR_API_KEY in the samples with your key.
Submit a task (2Captcha)
GET/in.php
2Captcha's in.php for Cloudflare Turnstile: method=turnstile with sitekey and pageurl, and optionally action, data, proxy and pingback. The reply is OK|<task id>, or {"status": 1, "request": "<task id>"} with json=1; poll res.php with the ID. Priced, held and charged as POST /v1/tasks is; an Idempotency-Key header works as it does there.
Authentication: None: anyone may call it, within a budget per client address where the description says so.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
key required | query | string | Your API key, |
method required | query | string |
|
sitekey required | query | string | The widget's site key. |
pageurl required | query | string | The page the widget is on: a public http or https page, as |
action | query | string | The widget's action, if it sets one. |
data | query | string | The widget's cData, if it sets one. |
pingback | query | string | Where to POST the result once the task ends: 2Captcha's pingback form, |
json | query | integer |
|
proxy | query | string | Your proxy as |
proxytype | query | string |
|
soft_id | query | string | Accepted and ignored. |
header_acao | query | integer | Accepted and ignored: this service sends no CORS headers. |
pagedata | query | string | Accepted and ignored: Cloudflare challenge pages are not supported. |
userAgent | query | string | Accepted and ignored. |
Idempotency-Key | header | string | Your ID for this task, 1 to 255 visible ASCII characters, as on |
Responses
| Status | Meaning | Body |
|---|---|---|
| 200 OK |
| text/plain, TwoCaptchaReply (application/json) |
| Any other status | Only a failure outside the dialect, as RFC 9457 problem details: a body over the size limit (413), a request that ran out of time (504), this instance shedding load (503, with | Problem (application/problem+json) |
Error codes
ERROR_ZERO_BALANCE. The errors reference says what each means, whether a retry helps and what it costs.
Sample
curl https://api.zerocaptcha.io/in.php?key=key&method=method&sitekey=sitekey&pageurl=pageurl \ -H "Idempotency-Key: order-4521-attempt-1"const response = await fetch("https://api.zerocaptcha.io/in.php?key=key&method=method&sitekey=sitekey&pageurl=pageurl", { headers: { "Idempotency-Key": "order-4521-attempt-1", },});console.log(response.status, await response.text());import requests
response = requests.get( "https://api.zerocaptcha.io/in.php?key=key&method=method&sitekey=sitekey&pageurl=pageurl", headers={"Idempotency-Key": "order-4521-attempt-1"}, timeout=30,)print(response.status_code, response.text)Submit a task by POST (2Captcha)
POST/in.php
in.php as a POST, the way 2Captcha's own clients send it: the parameters as a form (application/x-www-form-urlencoded or multipart/form-data) or a JSON object, and any in the query string too, which win. The replies are those of GET /in.php.
Authentication: None: anyone may call it, within a budget per client address where the description says so.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Your ID for this task, 1 to 255 visible ASCII characters, as on |
Responses
| Status | Meaning | Body |
|---|---|---|
| 200 OK |
| text/plain, TwoCaptchaReply (application/json) |
| Any other status | Only a failure outside the dialect, as RFC 9457 problem details: a body over the size limit (413), a request that ran out of time (504), this instance shedding load (503, with | Problem (application/problem+json) |
Error codes
ERROR_ZERO_BALANCE. The errors reference says what each means, whether a retry helps and what it costs.
Sample
curl -X POST https://api.zerocaptcha.io/in.php \ -H "Idempotency-Key: order-4521-attempt-1"const response = await fetch("https://api.zerocaptcha.io/in.php", { method: "POST", headers: { "Idempotency-Key": "order-4521-attempt-1", },});console.log(response.status, await response.text());import requests
response = requests.post( "https://api.zerocaptcha.io/in.php", headers={"Idempotency-Key": "order-4521-attempt-1"}, timeout=30,)print(response.status_code, response.text)Get a result or the balance (2Captcha)
GET/res.php
2Captcha's res.php. action=get&id=<task id> answers CAPCHA_NOT_READY while the task runs, then OK|<token>, or an error code such as ERROR_CAPTCHA_UNSOLVABLE (nothing charged) or ERROR_TOKEN_EXPIRED; action=get2 adds the price, OK|<token>|<price>. action=get&ids=<id>,<id>,… reads up to 100 tasks at once: each one's token, CAPCHA_NOT_READY or error code, in order, joined by |. action=reportbad or reportgood with id records whether the site took the token (OK_REPORT_RECORDED): recorded for our staff, never refunded, as tasks are final. action=getbalance answers the available balance in US dollars, such as 12.3456. With json=1, each as {"status": …, "request": …}. Reads share their budgets with REST; over one, the reply is ERROR: 1005 with Retry-After.
Authentication: None: anyone may call it, within a budget per client address where the description says so.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
key required | query | string | Your API key, as for in.php. |
action required | query | string |
|
id | query | string | The task's ID, as in.php gave it, for |
ids | query | string | With |
json | query | integer |
|
Responses
| Status | Meaning | Body |
|---|---|---|
| 200 OK | The token, | text/plain, TwoCaptchaReply (application/json) |
| Any other status | Only a failure outside the dialect, as RFC 9457 problem details: a body over the size limit (413), a request that ran out of time (504), this instance shedding load (503, with | Problem (application/problem+json) |
Error codes
ERROR_CAPTCHA_UNSOLVABLE, ERROR_TOKEN_EXPIRED. The errors reference says what each means, whether a retry helps and what it costs.
Sample
curl https://api.zerocaptcha.io/res.php?key=key&action=actionconst response = await fetch("https://api.zerocaptcha.io/res.php?key=key&action=action");console.log(response.status, await response.text());import requests
response = requests.get( "https://api.zerocaptcha.io/res.php?key=key&action=action", timeout=30,)print(response.status_code, response.text)