Skip to content

Compatibility API

The compatibility API speaks the anti-captcha compatible JSON protocol used by many captcha solving clients and libraries. Point your client at https://api.noptcha.com, use a Noptcha key as clientKey, and keep your code.

  • Every request is POST with a JSON body. Content-Type is not required; the body is always parsed as JSON.
  • Every response is HTTP 200. errorId is 0 on success and 1 on error; then errorCode and errorDescription say what went wrong (error codes).
  • The key is checked first: an invalid key is reported even when other fields are wrong.
  • Task IDs are integers (53 bits, safe as JavaScript numbers). Times are Unix seconds.
  • Two responses come from the infrastructure, not the protocol: HTTP 403 (a request that did not pass through our edge network) and HTTP 500. Treat both as transient. Unknown paths, and known paths with another method (GET /createTask), are HTTP 404.
Endpoint Body Response
POST /createTask clientKey, task; optional softId / appId taskId; for tasks solved at once also status: "ready", solution, cost
POST /getTaskResult clientKey, taskId status: "processing", or "ready" with solution, cost, createTime, endTime, solveCount, ip
POST /getBalance clientKey balance (US dollars, number)
POST /reportIncorrectRecaptcha, /reportCorrectRecaptcha, /reportIncorrectImageCaptcha clientKey, taskId status: "success"

task.type is a compatibility name such as RecaptchaV2TaskProxyless; the other task fields are that type’s parameters in anti-captcha’s field names (websiteURL, websiteKey, …). Each task type page lists its names, fields and solution fields.

Terminal window
export NOPTCHA_KEY=nop_test_... # your test or live key
# 1. create the task
curl -s -X POST "https://api.noptcha.com/createTask" \
-H 'Content-Type: application/json' \
-d @- <<EOF
{
"clientKey": "$NOPTCHA_KEY",
"task": {
"type": "RecaptchaV2TaskProxyless",
"websiteURL": "https://www.google.com/recaptcha/api2/demo",
"websiteKey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
}
}
EOF
# 2. poll with the taskId from step 1 every few seconds until "status" is "ready"
TASK_ID=...
curl -s -X POST "https://api.noptcha.com/getTaskResult" \
-H 'Content-Type: application/json' \
-d @- <<EOF
{
"clientKey": "$NOPTCHA_KEY",
"taskId": $TASK_ID
}
EOF
  • Polling. Call getTaskResult every 1–3 seconds. Polling one task more than 5 times per second is answered with processing rather than an error, so a fast poller keeps working; it just does not get the answer sooner.
  • Results are kept for 10 minutes after the task completes; after that getTaskResult returns ERROR_NO_SUCH_CAPCHA_ID.
  • Failed tasks come back from getTaskResult as errors (errorId: 1, for example ERROR_CAPTCHA_UNSOLVABLE or a proxy error) and are not charged.
  • Tasks solved at once: some types can be answered while createTask is still open; the response then already has status: "ready" and the solution. If such an immediate attempt fails, createTask returns the error and no task ID; nothing is charged.
  • cost in getTaskResult is a string with 6 decimals ("0.001000"); balance in getBalance is a number.

Names without Proxyless (for example RecaptchaV2Task) need a proxy: proxyType (http, https, socks4, socks5), proxyAddress, proxyPort, and optionally proxyLogin and proxyPassword. Proxyless names ignore proxy fields. See Proxies.

Terminal window
export NOPTCHA_KEY=nop_test_... # your test or live key
curl -s -X POST "https://api.noptcha.com/createTask" \
-H 'Content-Type: application/json' \
-d @- <<EOF
{
"clientKey": "$NOPTCHA_KEY",
"task": {
"type": "RecaptchaV2Task",
"websiteURL": "https://example.com/login",
"websiteKey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"proxyType": "http",
"proxyAddress": "203.0.113.7",
"proxyPort": 8080,
"proxyLogin": "proxyuser",
"proxyPassword": "proxypass"
}
}
EOF
Terminal window
export NOPTCHA_KEY=nop_test_... # your test or live key
curl -s -X POST "https://api.noptcha.com/getBalance" \
-H 'Content-Type: application/json' \
-d @- <<EOF
{
"clientKey": "$NOPTCHA_KEY"
}
EOF

Needs the balance:read scope. balance is the amount available for new tasks: cash plus promotional credit (and any credit limit), minus amounts held for tasks in progress. The native API shows each part (GET /v1/balance).

After using a solution, you can report whether the site accepted it. Reports are accepted for solved tasks within 10 minutes after completion; only the first report per task is recorded. Reports are recorded as a quality signal; they do not refund the task.

Terminal window
export NOPTCHA_KEY=nop_test_... # your test or live key
TASK_ID=7259140378796032 # the task ID you got when creating the task
curl -s -X POST "https://api.noptcha.com/reportIncorrectRecaptcha" \
-H 'Content-Type: application/json' \
-d @- <<EOF
{
"clientKey": "$NOPTCHA_KEY",
"taskId": $TASK_ID
}
EOF

callbackUrl in createTask makes Noptcha POST the final result to your server: the getTaskResult response plus taskId. See Webhooks for signing, retries and the URL rules; an unacceptable URL is ERROR_INCORRECT_SESSION_DATA and no task is created.

  • Idempotent retries: the protocol has no way to express them. A createTask that timed out on the network may have created a task. If that matters, use the native API.
  • Keys are Noptcha keys (nop_live_…, nop_test_…).
  • Rate limits are answered with codes your client already knows (ERROR_NO_SLOT_AVAILABLE when creating too fast, processing when polling too fast), never with HTTP 429. See Rate limits.
  • softId and appId are recorded with the task.