Appearance
Task types
Every createTask call carries a task object whose type selects the CAPTCHA you want solved. This page is the payload reference for every supported task.type: the required fields, the useful optional fields, a copy-pasteable request, and the exact solution shape you get back from getTaskResult.
For the request/response envelope and polling rules see createTask and the Quickstart.
Task type reference
task.type is validated on the way in. A value not in this table is rejected with ERROR_TASK_TYPE_UNSUPPORTED (errorId 5); a supported type that is missing a required field is rejected with ERROR_VALIDATION (errorId 8) before a thread is reserved — see How validation works.
Each task.type maps to an internal solve type. Types in the same solve group return the same solution shape.
task.type | Solve group | Required task.* fields | Own proxy |
|---|---|---|---|
ImageToTextTask | image | body | — |
GridTask | image | body | — |
BlsTask | image | at least one image tile (see BLS) | — |
RecaptchaV2TaskProxyless | reCAPTCHA | websiteURL, websiteKey | — |
RecaptchaV2Task | reCAPTCHA | websiteURL, websiteKey | yes |
RecaptchaV2EnterpriseTaskProxyless | reCAPTCHA | websiteURL, websiteKey | — |
RecaptchaV2EnterpriseTask | reCAPTCHA | websiteURL, websiteKey | yes |
RecaptchaV3TaskProxyless | reCAPTCHA | websiteURL, websiteKey | — |
RecaptchaV3EnterpriseTaskProxyless | reCAPTCHA | websiteURL, websiteKey | — |
RecaptchaV3EnterpriseTask | reCAPTCHA | websiteURL, websiteKey | yes |
HCaptchaTaskProxyless | hCaptcha | websiteURL, websiteKey | — |
HCaptchaTask | hCaptcha | websiteURL, websiteKey | yes |
TurnstileTaskProxyless | Turnstile | websiteURL, websiteKey | — |
TurnstileTask | Turnstile | websiteURL, websiteKey | yes |
AntiCloudflareTask | Cloudflare challenge | websiteURL | yes |
GeeTestTaskProxyless | GeeTest v3 | gt, challenge, websiteURL | — |
GeeTestTask | GeeTest v3 | gt, challenge, websiteURL | yes |
GeeTestV4TaskProxyless | GeeTest v4 | captchaId, websiteURL | — |
GeeTestV4Task | GeeTest v4 | captchaId, websiteURL | yes |
FunCaptchaTaskProxyless | FunCaptcha | websitePublicKey, websiteURL | — |
FunCaptchaTask | FunCaptcha | websitePublicKey, websiteURL | yes |
*Proxyless variants solve on our infrastructure. The plain (*Task) variants let you supply your own proxy — see Using your own proxy.
Solution shapes at a glance
| Solve group | solution field(s) |
|---|---|
image (ImageToTextTask, GridTask, BlsTask) | text |
| reCAPTCHA (v2 / v3, standard / enterprise) | gRecaptchaResponse |
| hCaptcha | token |
| Turnstile | token |
| FunCaptcha | token |
| GeeTest v3 / v4 | challenge, validate, seccode |
| Cloudflare challenge | cookies, token |
How validation works
Required fields are checked before your task is queued, so a bad request fails fast and does not consume a thread. A missing field returns:
json
{
"errorId": 8,
"errorCode": "ERROR_VALIDATION",
"errorDescription": "`websiteURL` is required for TurnstileTaskProxyless."
}The full list of ERROR_* codes and retry guidance is on the Errors page.
The examples below truncate base64 image data to iVBORw0KGgo...<snip>. Send the full base64 string (no data-URI prefix) in real requests.
Image to text
Classic distorted-text image. Put the raw base64 of the image in body.
Required: body.
Request — POST /createTask:
json
{
"clientKey": "cai_YOUR_KEY",
"task": {
"type": "ImageToTextTask",
"body": "iVBORw0KGgo...<snip>"
}
}Result — POST /getTaskResult once status is ready:
json
{
"errorId": 0,
"status": "ready",
"taskId": "tsk_0190a1b2-c3d4-7abc",
"solution": {
"text": "w8kT2"
},
"createTime": 1752300000,
"endTime": 1752300007
}Grid
A grid image (for example a "select all squares with…" challenge). Send the full challenge image in body, exactly like Image to text. The solver returns the selected tiles as text.
Required: body.
Request — POST /createTask:
json
{
"clientKey": "cai_YOUR_KEY",
"task": {
"type": "GridTask",
"body": "iVBORw0KGgo...<snip>"
}
}Result:
json
{
"errorId": 0,
"status": "ready",
"taskId": "tsk_0190a1b2-c3d4-7abc",
"solution": {
"text": "[1, 5, 9]"
}
}BLS (numbered image tiles)
BLS challenges present several image tiles and an instruction; you get back the tile numbers that match. This is how real clients send it: one base64 field per tile, named image_base64_1, image_base64_2, … up to image_base64_9, plus the instructions value (the target the tiles are matched against).
Required: at least one image tile. A request is accepted when it contains any of image_base64_1, an images array, or an imagesBase64 array; the numbered image_base64_N form shown here is what the solver consumes. Omitting all of them returns ERROR_VALIDATION — `images` is required for BlsTask.
Optional: instructions (the target, e.g. a number the tiles must contain), expected_image_count.
Request — POST /createTask:
json
{
"clientKey": "cai_YOUR_KEY",
"task": {
"type": "BlsTask",
"instructions": "546",
"expected_image_count": 9,
"image_base64_1": "iVBORw0KGgo...<snip>",
"image_base64_2": "iVBORw0KGgo...<snip>",
"image_base64_3": "iVBORw0KGgo...<snip>",
"image_base64_4": "iVBORw0KGgo...<snip>",
"image_base64_5": "iVBORw0KGgo...<snip>",
"image_base64_6": "iVBORw0KGgo...<snip>",
"image_base64_7": "iVBORw0KGgo...<snip>",
"image_base64_8": "iVBORw0KGgo...<snip>",
"image_base64_9": "iVBORw0KGgo...<snip>"
}
}Result — the matching tile numbers come back as text:
json
{
"errorId": 0,
"status": "ready",
"taskId": "tsk_0190a1b2-c3d4-7abc",
"solution": {
"text": "[2, 3, 8, 9]"
}
}reCAPTCHA v2
Google reCAPTCHA v2 ("I'm not a robot" / image challenge). Use RecaptchaV2TaskProxyless to solve on our infrastructure, or RecaptchaV2Task with your own proxy.
Required: websiteURL, websiteKey.
Optional: isInvisible (boolean, for invisible reCAPTCHA), recaptchaDataSValue (the data-s token some deployments require).
Request — POST /createTask:
json
{
"clientKey": "cai_YOUR_KEY",
"task": {
"type": "RecaptchaV2TaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
}
}Result — the token to submit as g-recaptcha-response:
json
{
"errorId": 0,
"status": "ready",
"taskId": "tsk_0190a1b2-c3d4-7abc",
"solution": {
"gRecaptchaResponse": "03AGdBq26..."
},
"createTime": 1752300000,
"endTime": 1752300019
}To solve through your own proxy, use RecaptchaV2Task and add the proxy fields:
json
{
"clientKey": "cai_YOUR_KEY",
"task": {
"type": "RecaptchaV2Task",
"websiteURL": "https://example.com/login",
"websiteKey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"isInvisible": true,
"proxyType": "HTTP",
"proxyAddress": "203.0.113.10",
"proxyPort": 8080,
"proxyLogin": "user",
"proxyPassword": "pass"
}
}reCAPTCHA v2 Enterprise
Same fields and same gRecaptchaResponse solution as reCAPTCHA v2; billed and metered separately. Use RecaptchaV2EnterpriseTaskProxyless, or RecaptchaV2EnterpriseTask with your own proxy.
Required: websiteURL, websiteKey.
Request — POST /createTask:
json
{
"clientKey": "cai_YOUR_KEY",
"task": {
"type": "RecaptchaV2EnterpriseTaskProxyless",
"websiteURL": "https://example.com/checkout",
"websiteKey": "6Lc_aCMTAAAAABc..."
}
}Result:
json
{
"errorId": 0,
"status": "ready",
"taskId": "tsk_0190a1b2-c3d4-7abc",
"solution": {
"gRecaptchaResponse": "03AGdBq26..."
}
}reCAPTCHA v3
Score-based reCAPTCHA v3. Only the proxyless variant RecaptchaV3TaskProxyless is available for standard v3; if you need a proxied v3 solve, use reCAPTCHA v3 Enterprise.
Required: websiteURL, websiteKey.
Optional: pageAction (the action name your site sets, e.g. verify), minScore (the minimum score to accept, e.g. 0.3).
Request — POST /createTask:
json
{
"clientKey": "cai_YOUR_KEY",
"task": {
"type": "RecaptchaV3TaskProxyless",
"websiteURL": "https://example.com/",
"websiteKey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"pageAction": "verify",
"minScore": 0.3
}
}Result:
json
{
"errorId": 0,
"status": "ready",
"taskId": "tsk_0190a1b2-c3d4-7abc",
"solution": {
"gRecaptchaResponse": "03AGdBq26..."
}
}reCAPTCHA v3 Enterprise
Enterprise reCAPTCHA v3, metered separately. Use RecaptchaV3EnterpriseTaskProxyless, or RecaptchaV3EnterpriseTask with your own proxy. Same required fields and gRecaptchaResponse solution as reCAPTCHA v3.
Required: websiteURL, websiteKey.
Request — POST /createTask:
json
{
"clientKey": "cai_YOUR_KEY",
"task": {
"type": "RecaptchaV3EnterpriseTaskProxyless",
"websiteURL": "https://example.com/",
"websiteKey": "6Lc_aCMTAAAAABc...",
"pageAction": "login",
"minScore": 0.5
}
}hCaptcha
hCaptcha. Use HCaptchaTaskProxyless, or HCaptchaTask with your own proxy.
Required: websiteURL, websiteKey.
Optional: data (the rqdata string some hCaptcha deployments require).
Request — POST /createTask:
json
{
"clientKey": "cai_YOUR_KEY",
"task": {
"type": "HCaptchaTaskProxyless",
"websiteURL": "https://example.com/signup",
"websiteKey": "10000000-ffff-ffff-ffff-000000000001"
}
}Result — the token to submit as h-captcha-response:
json
{
"errorId": 0,
"status": "ready",
"taskId": "tsk_0190a1b2-c3d4-7abc",
"solution": {
"token": "P0_eyJ0eXAiOiJKV1Qi..."
}
}Cloudflare Turnstile
Cloudflare Turnstile. Use TurnstileTaskProxyless, or TurnstileTask with your own proxy.
Required: websiteURL, websiteKey.
Optional: action (the action name configured on the widget).
Request — POST /createTask:
json
{
"clientKey": "cai_YOUR_KEY",
"task": {
"type": "TurnstileTaskProxyless",
"websiteURL": "https://example.com/",
"websiteKey": "0x4AAAAAAABkMYinukE8nzYS",
"action": "login"
}
}Result:
json
{
"errorId": 0,
"status": "ready",
"taskId": "tsk_0190a1b2-c3d4-7abc",
"solution": {
"token": "0.KfM3f..."
}
}Cloudflare Challenge
The full Cloudflare "Checking your browser" interstitial (not the Turnstile widget). Use AntiCloudflareTask. Only websiteURL is required, but a proxy is strongly recommended — Cloudflare binds the returned clearance to the solving IP, so pass the same proxy your client will use.
Required: websiteURL.
Optional: proxy fields.
Request — POST /createTask:
json
{
"clientKey": "cai_YOUR_KEY",
"task": {
"type": "AntiCloudflareTask",
"websiteURL": "https://example.com/",
"proxyType": "HTTP",
"proxyAddress": "203.0.113.10",
"proxyPort": 8080,
"proxyLogin": "user",
"proxyPassword": "pass"
}
}Result — the clearance cookie plus token:
json
{
"errorId": 0,
"status": "ready",
"taskId": "tsk_0190a1b2-c3d4-7abc",
"solution": {
"cookies": {
"cf_clearance": "hR2s...<snip>"
},
"token": "hR2s...<snip>"
}
}GeeTest v3
GeeTest v3 slider/click. Use GeeTestTaskProxyless, or GeeTestTask with your own proxy. gt and challenge come from the target site's GeeTest init call.
Required: gt, challenge, websiteURL.
Optional: geetestApiServerSubdomain (the GeeTest API subdomain some sites use).
Request — POST /createTask:
json
{
"clientKey": "cai_YOUR_KEY",
"task": {
"type": "GeeTestTaskProxyless",
"websiteURL": "https://example.com/",
"gt": "f1ab2cdefa3456789012345678901234",
"challenge": "12345678abc90123456ab789012345ab"
}
}Result — the three GeeTest validation fields:
json
{
"errorId": 0,
"status": "ready",
"taskId": "tsk_0190a1b2-c3d4-7abc",
"solution": {
"challenge": "12345678abc90123456ab789012345ab",
"validate": "cbe98a7d6f5e4c3b2a1908f7e6d5c4b3",
"seccode": "cbe98a7d6f5e4c3b2a1908f7e6d5c4b3|jordan"
}
}GeeTest v4
GeeTest v4. Use GeeTestV4TaskProxyless, or GeeTestV4Task with your own proxy. v4 identifies the widget by captchaId (no gt/challenge).
Required: captchaId, websiteURL.
Request — POST /createTask:
json
{
"clientKey": "cai_YOUR_KEY",
"task": {
"type": "GeeTestV4TaskProxyless",
"websiteURL": "https://example.com/",
"captchaId": "e392e1d7fd421dc63325744d5a2b9c73"
}
}Result — same three-field shape as GeeTest v3:
json
{
"errorId": 0,
"status": "ready",
"taskId": "tsk_0190a1b2-c3d4-7abc",
"solution": {
"challenge": "e392e1d7fd421dc63325744d5a2b9c73",
"validate": "cbe98a7d6f5e4c3b2a1908f7e6d5c4b3",
"seccode": "cbe98a7d6f5e4c3b2a1908f7e6d5c4b3|jordan"
}
}FunCaptcha
Arkose Labs FunCaptcha. Use FunCaptchaTaskProxyless, or FunCaptchaTask with your own proxy. The site key is passed as websitePublicKey.
Required: websitePublicKey, websiteURL.
Optional: funcaptchaApiJSSubdomain (the FunCaptcha service subdomain some deployments use).
Request — POST /createTask:
json
{
"clientKey": "cai_YOUR_KEY",
"task": {
"type": "FunCaptchaTaskProxyless",
"websiteURL": "https://example.com/",
"websitePublicKey": "69A21A01-CC7B-B9C6-0F9A-E7FA06677FFC"
}
}Result — the token to submit as fc-token / arkoselabs response:
json
{
"errorId": 0,
"status": "ready",
"taskId": "tsk_0190a1b2-c3d4-7abc",
"solution": {
"token": "3126f0b4c4e3a...|r=us-east-1|..."
}
}Using your own proxy
The plain (*Task) variants — and AntiCloudflareTask — accept your own proxy so the CAPTCHA is solved from your IP. Add these fields to the task object:
| Field | Required | Notes |
|---|---|---|
proxyType | yes | HTTP, HTTPS, SOCKS4, or SOCKS5 |
proxyAddress | yes | Proxy host or IP |
proxyPort | yes | Proxy port |
proxyLogin | no | Username, if the proxy needs auth |
proxyPassword | no | Password, if the proxy needs auth |
json
{
"proxyType": "HTTP",
"proxyAddress": "203.0.113.10",
"proxyPort": 8080,
"proxyLogin": "user",
"proxyPassword": "pass"
}The *Proxyless variants ignore proxy fields — the solve runs on our infrastructure.
Migrating from CaptchaAI v1
If you already send tasks to CaptchaAI v1 (the 2captcha-style in.php/res.php flow), the field names change in the v2 native task object. The mapping:
| v1 (2captcha) param | v2 native task.* field |
|---|---|
method=userrecaptcha + googlekey | type + websiteKey |
sitekey (hCaptcha / Turnstile) | websiteKey |
publickey (FunCaptcha) | websitePublicKey |
pageurl | websiteURL |
captcha_id (GeeTest v4) | captchaId |
gt, challenge (GeeTest v3) | gt, challenge (unchanged) |
min_score | minScore |
action (reCAPTCHA v3) | pageAction |
action (Turnstile) | action (unchanged) |
data-s | recaptchaDataSValue |
invisible=1 | isInvisible: true |
api_server (GeeTest) | geetestApiServerSubdomain |
surl (FunCaptcha) | funcaptchaApiJSSubdomain |
image_base64_1..9 (BLS) | image_base64_1..9 (unchanged) |
proxy / proxyaddress + proxyport | proxyAddress + proxyPort + proxyType |
v1 returns a single flat string; v2 returns a structured solution object — use the field named in Solution shapes at a glance for each type.