Captcha OCR API (1.0.0)

Download OpenAPI specification:

Solve numeric and arithmetic captchas (also alphanumeric and Hindi-number). ₹25 per 1,000; pay only for reliable answers.

Send a captcha image, get back the text to type, a confidence score, and a reliable flag that says whether it is worth submitting.

Two ways to call it.

  • Call and wait: POST /v1/solve returns the answer in the same request, in about 25 ms for text and 6 ms for math captchas. POST /v1/solve_batch does up to 256 at once.
  • Submit, then fetch: POST /v1/submit returns a task id immediately and solves the captcha in the background. GET /v1/result/{id} returns processing, then ready with the answer. Add ?wait=10 to hold the request until the answer is ready (up to 30 s) instead of polling. Results are kept 48 hours.
Options Engine Reads
(default), or numeric: true ocr numeric codes (482915) and alphanumeric text
math: true math arithmetic captchas (14 + 9 = ? → 23)
math: true, hindi: true hindi_math Hindi number words (इकतीस + 6 = ?); returns the answer

Pricing. ₹25 per 1,000 solves (packs from ₹100), and only answers with reliable: true are charged. Unreadable images and low-confidence reads are free.

Balance and alerts. GET /v1/balance returns your credits. Set one low-balance alert with PUT /v1/alert: when your credits drop below its threshold, we POST your JSON payload to your URL.

Authentication. Authorization: Bearer <API key> (or X-API-Key: <API key>). Create keys on the dashboard.

Quickstart

  1. Sign up on the website. New accounts get 500 free credits.
  2. Create an API key on the dashboard (API keys → New key). The key is shown once.
  3. Send a captcha:
curl -s https://captchaocr.allvoraz.com/v1/solve \
  -H "Authorization: Bearer $CAPTCHA_API_KEY" \
  -H 'Content-Type: application/json' \
  -d "{\"image\": \"$(base64 < captcha.png | tr -d '\n')\", \"numeric\": true, \"length\": 6}"
# {"text":"482915","confidence":0.99,"reliable":true,"engine":"ocr","raw":"482915",
#  "expression":null,"error":null,"id":184467,"charged":true}

Official SDKs: Python, TypeScript/JavaScript, Go, Java, Kotlin, C#, PHP, Ruby, Rust, Swift and Dart. Every operation below shows each language's call.

Two ways to call

Call and wait Submit, then fetch
Endpoints POST /v1/solve (or /v1/solve_batch) POST /v1/submit, then GET /v1/result/{id}
First response the answer {"id": 184467, "status": "processing"}, at once
Use it when you need the answer to continue (most form fills) you queue captchas, or your HTTP client must not block

Both take the same body and options, cost the same, and return the same answer object.

Submit, then fetch. POST /v1/submit reserves a credit, stores the task, and returns its id with HTTP 202 before solving. The captcha is solved in the background, usually within 0.1 s. GET /v1/result/{id} returns:

status Meaning
processing Not done yet. Ask again in ~0.5 s, or pass ?wait=10.
ready result holds the answer (same fields as /v1/solve). Check result.reliable.
failed The solver couldn't run. error says why; the credit was returned. Submit again.

?wait=N (0-30) holds the request until the task finishes or N seconds pass, so one request usually returns the answer without a polling loop. Results are kept 48 hours; another key's task ids return 404. A key may have up to 256 unfinished tasks (429 beyond that).

curl -s https://captchaocr.allvoraz.com/v1/submit -H "Authorization: Bearer $CAPTCHA_API_KEY" \
  -H 'Content-Type: application/json' -d '{"image": "<base64>", "numeric": true, "length": 6}'
# {"id": 184467, "status": "processing"}
curl -s "https://captchaocr.allvoraz.com/v1/result/184467?wait=10" -H "Authorization: Bearer $CAPTCHA_API_KEY"
# {"id": 184467, "status": "ready", "result": {"text": "482915", "reliable": true, ...}, "error": null}

Authentication

Send your API key with every request, either as Authorization: Bearer <key> or as X-API-Key: <key>. Keys are created and revoked on the dashboard. A revoked key stops working within 30 seconds. Keep keys on your server: anyone holding a key can spend its credits.

Pricing and billing

  • 1 credit = 1 reliable answer. A captcha costs a credit only when the response has reliable: true. Undecodable images (error) and low-confidence reads are returned free.
  • Credits are prepaid in packs (₹100, ₹1,000, ₹5,000) by card, UPI (Google Pay, PhonePe, Paytm) or netbanking. They work out to ₹25, ₹22 and ₹20 per 1,000 solves.
  • Every response carries an X-Credits-Remaining header. GET /v1/balance returns the balance.
  • A request needs enough credits for all of its images up front (402 insufficient_credits otherwise). The uncharged ones are returned before the response is sent; for /v1/submit, when the task finishes.

Choosing options

Describe the captcha, not the answer you want. Each option you set removes wrong readings the model could otherwise make.

Captcha looks like Send
482915, always 6 digits numeric: true, length: 6
14 + 9 = ? (answer: 23) math: true
PUKLX8, capitals and digits uppercase: true, numeric: true
hyi5ag, site ignores case lowercase: true, numeric: true
7rX2Yx, mixed case, case matters nothing (case is kept as read)
बयालीस - 6 = ? (answer: 36) math: true, hindi: true
  • numeric alone also turns look-alike letters into digits (O → 0, l → 1, S → 5).
  • uppercase or lowercase alone folds the other case into it, and turns look-alike digits into letters (0 → O).
  • length is enforced by the decoder: it returns the most likely reading of exactly that many characters. Set it whenever the site's captchas have a fixed length.
  • math returns the computed answer in text and the expression it computed in expression.

Acting on the result

if result.error:          the image couldn't be decoded (not charged): re-download it
elif result.reliable:     submit result.text (charged)
else:                     refresh the captcha and solve the new one (not charged)

confidence is the probability of the least certain character. reliable combines it with engine-specific checks: the length matched, a math answer is non-negative, a Hindi number word was read exactly.

Balance and low-balance alert

GET /v1/balance returns {"credits": N, "alert_threshold": T} (alert_threshold is null without an alert). Every solve response also carries the balance in the X-Credits-Remaining header.

Each account can have one low-balance alert. When a solve leaves your credits below its threshold, we POST your JSON payload to your url, so your team hears about it before captchas start failing with 402.

curl -s -X PUT https://captchaocr.allvoraz.com/v1/alert -H "Authorization: Bearer $CAPTCHA_API_KEY" \
  -H 'Content-Type: application/json' -d '{
    "threshold": 500,
    "url": "https://hooks.example.org/captcha-credits",
    "payload": {"text": "Captcha credits low: {{credits}} left (alert at {{threshold}})"},
    "headers": {"Authorization": "Bearer my-hook-secret"}
  }'
Field Meaning
threshold Fire when credits drop below this (1 or more).
url Your HTTPS endpoint. It must resolve to a public address.
payload Optional JSON object, up to 8 KB. In strings, {{credits}}, {{threshold}} and {{time}} are filled in; a value that is exactly "{{credits}}" becomes a number. Default: {"event": "low_balance", "credits": N, "threshold": T}.
headers Optional, up to 10, e.g. Authorization so your endpoint can check the call is ours.

How it behaves:

  • It fires once per drop below the threshold, then armed becomes false. Buying credits that bring the balance back to the threshold or above re-arms it.
  • We POST with Content-Type: application/json and X-CaptchaOCR-Event: low_balance, and treat any 2xx as delivered. Otherwise we retry after 10 s and 60 s. Redirects are not followed.
  • PUT /v1/alert replaces your alert and arms it. GET /v1/alert shows it with the last delivery (last_fired_at, last_status, last_error). DELETE /v1/alert removes it.
  • POST /v1/alert/test sends it right now with your current balance and returns {"delivered": true, "status": 200, "error": null}, without changing armed.

Wrong answers and refunds

If a site rejects an answer that was reliable, call POST /v1/report with the answer's id (from /v1/solve, or the task id from /v1/submit) within 48 hours, and the credit is returned. Refunds per day are capped at 10% of that day's charged solves (plus 5).

Batches

POST /v1/solve_batch takes up to 256 images, solves them in parallel, and returns results in request order. The top-level options apply to every image. An item can override any of them:

{
  "numeric": true,
  "images": [
    {"image": "<base64>"},
    {"image": "<base64>", "length": 5},
    {"image": "<base64>", "math": true}
  ]
}

A plain base64 string works as shorthand for {"image": "<base64>"}. A bad image fails only its own slot.

Errors

Status Body What to do
200 with error: "invalid_image" Solved The image can't be decoded. Not charged. Re-download it.
401 {"detail": "invalid_api_key"} Check the key; it may have been revoked.
402 {"detail": "insufficient_credits", "credits": N} Buy credits on the dashboard.
422 HTTPValidationError Invalid options (unknown field, hindi without math, length outside 1-32, >256 images). Fix the request; don't retry.
404 {"detail": "unknown_task"} / "no_alert" /v1/result: no such task for this key, or older than 48 hours. /v1/alert: none set.
429 {"detail": "too_many_concurrent_requests"} More than 32 requests in flight (or 256 unfinished submitted tasks) on one key. Retry after Retry-After.
503 {"detail": "solver_unavailable"} Temporary. Retry with backoff. Credits were returned.

Task API

Besides /v1, the API offers task-style endpoints for normal (image) captchas, the createTask / getTaskResult shape many captcha integrations already use. Point such a client at this API's host and send your key as clientKey.

Endpoint / field Behaviour
POST /createTask with ImageToTextTask returns a taskId at once; solved in the background
POST /getTaskResult status: "processing", then "ready" (usually within 0.1 s)
POST /getBalance balance is in credits
POST /reportIncorrect / reportCorrect refunds as above
numeric 1 / 2 digits only / letters only
minLength = maxLength exact length
math: true arithmetic; add "languagePool": "hi" (or task.hindi: true) for Hindi number words

Low-confidence reads come back as ERROR_CAPTCHA_UNSOLVABLE and are not charged.

Limits

  • About 25 ms per text captcha and 6 ms per math captcha, plus network time.
  • Up to 32 concurrent requests per key, 256 unfinished submitted tasks per key, 256 images per batch, 5 MB per image.
  • Reuse one SDK client (HTTP keep-alive) rather than creating one per call.

Versioning

The API and every SDK share one semantic version. Adding fields is a minor release, and clients must ignore unknown response fields. Removing or renaming a field is a major release.

solve

Read captchas. Each reliable answer costs 1 credit.

Solve one captcha

Read one captcha. Check reliable before submitting the answer: only reliable answers are charged, and the others are returned free so you can decide.

Authorizations:
bearerAuthapiKeyHeader
Request Body schema: application/json
required
math
boolean (Math)
Default: false

Arithmetic captcha ("14 - 10 = ?"); text is the computed answer.

hindi
boolean (Hindi)
Default: false

Operands are Hindi number words ("इकतीस + 6 = ?"). Requires math.

numeric
boolean (Numeric)
Default: false

The captcha may contain digits 0-9.

uppercase
boolean (Uppercase)
Default: false

The captcha may contain letters A-Z. Alone, lowercase readings are folded to uppercase.

lowercase
boolean (Lowercase)
Default: false

The captcha may contain letters a-z. Alone, uppercase readings are folded to lowercase.

Length (integer) or Length (null) (Length)

Exact number of characters. The decoder returns the most likely reading of exactly this length. Ignored when math is set.

image
required
string (Image) [ 1 .. 7000000 ] characters

Base64-encoded captcha image: PNG, JPEG, GIF, WebP, TIFF, BMP or SVG, detected by content. A data:image/...;base64, prefix is accepted.

Responses

Request samples

Content type
application/json
{
  • "image": "iVBORw0KGgoAAAANSUhEUgAA...",
  • "length": 6,
  • "numeric": true
}

Response samples

Content type
application/json
{
  • "confidence": 0.97,
  • "engine": "ocr",
  • "raw": "A9D411",
  • "reliable": true,
  • "text": "A9D411"
}

Solve many captchas

Up to 256 images in parallel; top-level options apply to every image and each item may override them. Credits for every image are reserved first (402 if the balance can't cover the batch), then the unreliable ones are returned.

Authorizations:
bearerAuthapiKeyHeader
Request Body schema: application/json
required
math
boolean (Math)
Default: false

Arithmetic captcha ("14 - 10 = ?"); text is the computed answer.

hindi
boolean (Hindi)
Default: false

Operands are Hindi number words ("इकतीस + 6 = ?"). Requires math.

numeric
boolean (Numeric)
Default: false

The captcha may contain digits 0-9.

uppercase
boolean (Uppercase)
Default: false

The captcha may contain letters A-Z. Alone, lowercase readings are folded to uppercase.

lowercase
boolean (Lowercase)
Default: false

The captcha may contain letters a-z. Alone, uppercase readings are folded to lowercase.

Length (integer) or Length (null) (Length)

Exact number of characters. The decoder returns the most likely reading of exactly this length. Ignored when math is set.

required
Array of objects (Images) [ 1 .. 256 ] items

1-256 images, solved in parallel; results come back in the same order. A plain base64 string is accepted as shorthand for {"image": ...}.

Responses

Request samples

Content type
application/json
{
  • "images": [
    ],
  • "numeric": true
}

Response samples

Content type
application/json
{
  • "results": [
    ]
}

Submit a captcha (background)

Same body as /v1/solve, but returns a task id at once and solves in the background. Get the answer with GET /v1/result/{id}. A credit is reserved now (402 if there is none) and returned if the answer turns out unreliable or the task fails. Up to 256 unfinished tasks per key (429).

Authorizations:
bearerAuthapiKeyHeader
Request Body schema: application/json
required
math
boolean (Math)
Default: false

Arithmetic captcha ("14 - 10 = ?"); text is the computed answer.

hindi
boolean (Hindi)
Default: false

Operands are Hindi number words ("इकतीस + 6 = ?"). Requires math.

numeric
boolean (Numeric)
Default: false

The captcha may contain digits 0-9.

uppercase
boolean (Uppercase)
Default: false

The captcha may contain letters A-Z. Alone, lowercase readings are folded to uppercase.

lowercase
boolean (Lowercase)
Default: false

The captcha may contain letters a-z. Alone, uppercase readings are folded to lowercase.

Length (integer) or Length (null) (Length)

Exact number of characters. The decoder returns the most likely reading of exactly this length. Ignored when math is set.

image
required
string (Image) [ 1 .. 7000000 ] characters

Base64-encoded captcha image: PNG, JPEG, GIF, WebP, TIFF, BMP or SVG, detected by content. A data:image/...;base64, prefix is accepted.

Responses

Request samples

Content type
application/json
{
  • "image": "iVBORw0KGgoAAAANSUhEUgAA...",
  • "length": 6,
  • "numeric": true
}

Response samples

Content type
application/json
{
  • "id": 0,
  • "status": "processing"
}

Get a submitted captcha's answer

processing until the captcha is solved, then ready with the same answer object /v1/solve returns. With wait, the request returns as soon as the task finishes (or after wait seconds).

Authorizations:
bearerAuthapiKeyHeader
path Parameters
task_id
required
integer <int64> (Task Id) [ 0 .. 9223372036854776000 ]

The id from /v1/submit.

query Parameters
wait
integer (Wait) [ 0 .. 30 ]
Default: 0

Seconds to hold the request while the task is processing (0 = answer now).

Responses

Request samples

# Without wait: "processing" until the answer is ready, then "ready" (or "failed").
curl -s https://captchaocr.allvoraz.com/v1/result/184467 -H "Authorization: Bearer $CAPTCHA_API_KEY"
# {"id": 184467, "status": "processing", "result": null, "error": null}

Response samples

Content type
application/json
{
  • "id": 0,
  • "status": "processing",
  • "result": {
    },
  • "error": "string"
}

account

Balance and refunds.

Credits left

Your credit balance. Every solve response also carries it in the X-Credits-Remaining header.

Authorizations:
bearerAuthapiKeyHeader

Responses

Request samples

curl -s https://captchaocr.allvoraz.com/v1/balance -H "Authorization: Bearer $CAPTCHA_API_KEY"
# {"credits": 4321}

Response samples

Content type
application/json
{
  • "credits": 0,
  • "alert_threshold": 0
}

Get your low-balance alert

Authorizations:
bearerAuthapiKeyHeader

Responses

Response samples

Content type
application/json
{
  • "threshold": 0,
  • "url": "string",
  • "payload": { },
  • "headers": {
    },
  • "armed": true,
  • "last_fired_at": "2019-08-24T14:15:22Z",
  • "last_status": 0,
  • "last_error": "string",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Set your low-balance alert

One alert per account; this replaces any existing one and arms it. When a solve leaves your credits below threshold, we POST payload (JSON) to url with your headers, once, retrying for about a minute if your endpoint fails. It re-arms when you add credits above the threshold. Use POST /v1/alert/test to check delivery now.

Authorizations:
bearerAuthapiKeyHeader
Request Body schema: application/json
required
threshold
required
integer (Threshold) [ 1 .. 1000000000 ]

Call url when your credits drop below this number.

url
required
string (Url) <= 2048 characters

Your HTTPS endpoint. We POST payload to it as JSON.

Payload (object) or Payload (null) (Payload)

The JSON object to send (up to 8 KB). In string values, {{credits}}, {{threshold}} and {{time}} are replaced; a value that is exactly {{credits}} or {{threshold}} becomes a number. Default: {"event": "low_balance", "credits": N, "threshold": T}.

Headers (object) or Headers (null) (Headers)

Extra request headers, e.g. Authorization for your endpoint. Up to 10.

Responses

Request samples

Content type
application/json
{
  • "threshold": 1,
  • "url": "string",
  • "payload": { },
  • "headers": {
    }
}

Response samples

Content type
application/json
{
  • "threshold": 0,
  • "url": "string",
  • "payload": { },
  • "headers": {
    },
  • "armed": true,
  • "last_fired_at": "2019-08-24T14:15:22Z",
  • "last_status": 0,
  • "last_error": "string",
  • "updated_at": "2019-08-24T14:15:22Z"
}

Remove your low-balance alert

Authorizations:
bearerAuthapiKeyHeader

Responses

Response samples

Content type
application/json
{
  • "detail": "string",
  • "credits": 0
}

Send your alert now (test)

Sends the alert once, right now, with your current balance, and reports what your endpoint answered. Doesn't change whether the alert is armed. One test per 10 seconds.

Authorizations:
bearerAuthapiKeyHeader

Responses

Response samples

Content type
application/json
{
  • "delivered": true,
  • "status": 0,
  • "error": "string"
}

Report a wrong answer

The site rejected a reliable answer? Report its id within 48 hours and the credit comes back. Refunds per day are capped at 10% of that day's charged solves (plus 5).

Authorizations:
bearerAuthapiKeyHeader
Request Body schema: application/json
required
id
required
integer <int64> (Id)

The id of a solve from the last 48 hours.

Responses

Request samples

Content type
application/json
{
  • "id": 0
}

Response samples

Content type
application/json
{
  • "refunded": true,
  • "reason": "string",
  • "credits": 0
}

tasks

Task API: createTask / getTaskResult / getBalance / reportIncorrect (ImageToTextTask).

createTask (ImageToTextTask)

{"clientKey": KEY, "task": {"type": "ImageToTextTask", "body": BASE64, "numeric": 1, ...}}. Returns a taskId at once; the captcha is solved in the background (usually within 0.1 s). Poll getTaskResult. Low-confidence reads come back as ERROR_CAPTCHA_UNSOLVABLE and are free: get a new captcha and try again.

Request Body schema: application/json
required
property name*
additional property
any

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{ }

getTaskResult

Request Body schema: application/json
required
property name*
additional property
any

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{ }

getBalance (credits)

Request Body schema: application/json
required
property name*
additional property
any

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{ }

reportIncorrect (refund)

Request Body schema: application/json
required
property name*
additional property
any

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{ }

reportCorrect

Request Body schema: application/json
required
property name*
additional property
any

Responses

Request samples

Content type
application/json
{ }

Response samples

Content type
application/json
{ }

service

Operational endpoints.

Service health

Responses

Request samples

curl -s https://captchaocr.allvoraz.com/health
# {"status":"ok","solver":{"status":"ok","engines":{"ocr":true,"math":true,"hindi_math":true}}}

Response samples

Content type
application/json
{
  • "status": "ok",
  • "solver": { }
}