Skip to content

Create a task

POST https://api.noptcha.com/v1/tasks

Native API (v1). Guide. Operation ID createTask.

Creates a task. A task that is already final (solved or failed) is returned with 200; a task that is still processing with 202. Both carry Location: /v1/tasks/{id}.

Synchronous waiting. With Prefer: wait=N (or ?wait=N), the request waits up to N seconds (at most 90) for the result: 200 if the task completes in time, otherwise 202 and you poll GET /v1/tasks/{id}. Preference-Applied: wait=N confirms the wait (N capped at 90). Types solved synchronously return the result at once anyway. When an organization already has too many waiting requests, the request returns 202 without waiting and without Preference-Applied.

Idempotency. With Idempotency-Key (1–64 visible ASCII characters, kept for 24 hours per organization), retrying the same request returns the same task instead of creating and charging a new one; replayed responses carry Idempotent-Replayed: true. The same key with a body that is not byte-for-byte identical (serialize once, resend the same bytes) is 409 idempotency_conflict; so is a retry while the first request with that key is still being admitted (retry shortly). When the first request did not create a task (insufficient balance, no capacity, invalid parameters…) the key is released and can be reused. After the task's result has expired (10 minutes after completion) a replay is 404 not_found: the task is not created again, use a new key.

Failures. A task that cannot be solved is a successful request: 200 with status: "failed", error.code and zero cost. 503 service_unavailable means no solver could take the task right now; nothing was created or charged.

Callbacks. With callback_url, the final result is also POSTed there as a task.solved or task.failed event (see Webhooks). An invalid URL is 422 invalid_params with pointer /callback_url and no task is created; a callback_url that is not a string is 400 invalid_request. null and "" mean no callback.

Every response passes through the per-key create limit and carries RateLimit-Policy and RateLimit (when rate limiting is enabled), including errors after authentication.

Request

Authentication: Authorization: Bearer <key> (Keys).

ParameterInDescription
Prefer
optional
header

wait=N: wait up to N seconds (capped at 90) for the result, RFC 7240.

string · e.g. wait=60
wait
optional
query

Seconds to wait for the result (capped at 90). Takes precedence over Prefer: wait. Values that are not a non-negative integer are ignored.

integer · ≥ 0
Idempotency-Key
optional
header

1–64 visible ASCII characters (! to ~, no spaces), unique per logical request; kept for 24 hours. Anything else is 400 invalid_request.

string · pattern: ^[!-~]{1,64}$ · e.g. 3f6c2b9e-8d41-4a7f-b0c5-1e2d3a4b5c6d

Body (application/json, required):

One of (selected by type):

  • CreateCloudflareChallengeTaskRequest — Cloudflare challenge page (cloudflare.challenge, family cloudflare, active). Variants: proxy (params.proxy is required). Tasks not solved within 120 seconds fail with timeout.
  • CreateFuncaptchaTaskRequest — FunCaptcha (Arkose Labs) (funcaptcha, family arkose, beta). Variants: proxyless, proxy (the proxy variant when params.proxy is given). Tasks not solved within 180 seconds fail with timeout.
  • CreateHcaptchaTaskRequest — hCaptcha (hcaptcha, family hcaptcha, active). Variants: proxyless, proxy (the proxy variant when params.proxy is given). Tasks not solved within 120 seconds fail with timeout.
  • CreateImageFuncaptchaTaskRequest — FunCaptcha image (image.funcaptcha, family image, beta). Variants: proxyless. Tasks not solved within 60 seconds fail with timeout.
  • CreateImageGridAwsTaskRequest — AWS WAF image grid (image.grid.aws, family image, beta). Variants: proxyless. Tasks not solved within 60 seconds fail with timeout.
  • CreateImageGridHcaptchaTaskRequest — hCaptcha image grid (image.grid.hcaptcha, family image, active). Variants: proxyless. Tasks not solved within 60 seconds fail with timeout.
  • CreateImageGridRecaptchaTaskRequest — reCAPTCHA image grid (image.grid.recaptcha, family image, active). Variants: proxyless. Tasks not solved within 60 seconds fail with timeout.
  • CreateImageTextTaskRequest — Image to text (image.text, family image, active). Variants: proxyless. Tasks not solved within 60 seconds fail with timeout.
  • CreateRecaptchaV2TaskRequest — reCAPTCHA v2 (recaptcha.v2, family recaptcha, active). Variants: proxyless, proxy (the proxy variant when params.proxy is given). Tasks not solved within 120 seconds fail with timeout.
  • CreateRecaptchaV2EnterpriseTaskRequest — reCAPTCHA v2 Enterprise (recaptcha.v2.enterprise, family recaptcha, active). Variants: proxyless, proxy (the proxy variant when params.proxy is given). Tasks not solved within 120 seconds fail with timeout.
  • CreateRecaptchaV3TaskRequest — reCAPTCHA v3 (recaptcha.v3, family recaptcha, active). Variants: proxyless. Tasks not solved within 120 seconds fail with timeout.
  • CreateRecaptchaV3EnterpriseTaskRequest — reCAPTCHA v3 Enterprise (recaptcha.v3.enterprise, family recaptcha, active). Variants: proxyless. Tasks not solved within 120 seconds fail with timeout.
  • CreateTurnstileTaskRequest — Cloudflare Turnstile (turnstile, family cloudflare, active). Variants: proxyless, proxy (the proxy variant when params.proxy is given). Tasks not solved within 120 seconds fail with timeout.
Example
{
"metadata": {
"order": "A-17"
},
"params": {
"website_key": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-",
"website_url": "https://example.com/login"
},
"type": "recaptcha.v2"
}

Responses

200

The task is final (solved or failed).

Headers: Idempotent-Replayed (optional), Location (optional), Noptcha-Request-Id, Preference-Applied (optional), RateLimit (optional), RateLimit-Policy (optional).

Content: application/json

FieldTypeDescription
completed_at
optional
string

When the task became final; absent while processing.

format: date-time · pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z$
cost
required
object

What the task cost (zero unless solved and charged).

cost.amount
required
string

Decimal US dollars with 6 places.

pattern: ^-?[0-9]+\.[0-9]{6}$
cost.currency
required
const "USD"
created_at
required
stringformat: date-time · pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z$
error
required
one of | null

Why the task failed when status is failed, else null.

one of: TaskError
id
required
string

Task ID (a 53-bit integer as a string).

pattern: ^[0-9]+$
metadata
optional
object

Your own key-value pairs, returned with the task. At most 16 keys; keys 1–64 characters, values strings of at most 256 characters (Unicode code points, as JSON Schema counts them). A value that is not a string is 422 invalid_params with pointer /metadata/<key>.

max 16 keys
metadata.<any key>
optional
stringmax length 256
params
required
object | null

The task's parameters with secrets removed (proxy login and password, cookies where the type marks them sensitive) and strings longer than 256 bytes (images) replaced by "[N bytes]". null when not available.

sandbox
optional
const true

Present (true) on tasks created with a test key.

solution
required
one of | null

The answer when status is solved, else null. Its shape depends on type.

one of: Solution
status
required
enumone of "processing", "solved", "failed"
type
required
string

Canonical task type, e.g. recaptcha.v2 (see CreateTaskRequest).

202

The task is still processing; poll Location.

Headers: Idempotent-Replayed (optional), Location (optional), Noptcha-Request-Id, Preference-Applied (optional), RateLimit (optional), RateLimit-Policy (optional).

Content: application/json

FieldTypeDescription
completed_at
optional
string

When the task became final; absent while processing.

format: date-time · pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z$
cost
required
object

What the task cost (zero unless solved and charged).

cost.amount
required
string

Decimal US dollars with 6 places.

pattern: ^-?[0-9]+\.[0-9]{6}$
cost.currency
required
const "USD"
created_at
required
stringformat: date-time · pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z$
error
required
one of | null

Why the task failed when status is failed, else null.

one of: TaskError
id
required
string

Task ID (a 53-bit integer as a string).

pattern: ^[0-9]+$
metadata
optional
object

Your own key-value pairs, returned with the task. At most 16 keys; keys 1–64 characters, values strings of at most 256 characters (Unicode code points, as JSON Schema counts them). A value that is not a string is 422 invalid_params with pointer /metadata/<key>.

max 16 keys
metadata.<any key>
optional
stringmax length 256
params
required
object | null

The task's parameters with secrets removed (proxy login and password, cookies where the type marks them sensitive) and strings longer than 256 bytes (images) replaced by "[N bytes]". null when not available.

sandbox
optional
const true

Present (true) on tasks created with a test key.

solution
required
one of | null

The answer when status is solved, else null. Its shape depends on type.

one of: Solution
status
required
enumone of "processing", "solved", "failed"
type
required
string

Canonical task type, e.g. recaptcha.v2 (see CreateTaskRequest).

400

invalid_request: the body is not valid JSON or misses a field, a parameter is wrong, callback_url is not a string, the result would be too large (usage). unsupported_type: the task type does not exist or is not available.

Headers: Noptcha-Request-Id, RateLimit (optional), RateLimit-Policy (optional).

Content: application/problem+json

FieldTypeDescription
code
required
string

Machine-readable error code (see the table).

detail
optional
string

Human-readable explanation of this occurrence.

request_id
required
string

Same as the Noptcha-Request-Id header.

status
required
integer

The HTTP status code.

title
required
string
type
required
stringformat: uri

401

unauthorized: the key is malformed, unknown, revoked or expired.

Headers: Noptcha-Request-Id, RateLimit (optional), RateLimit-Policy (optional).

Content: application/problem+json

FieldTypeDescription
code
required
string

Machine-readable error code (see the table).

detail
optional
string

Human-readable explanation of this occurrence.

request_id
required
string

Same as the Noptcha-Request-Id header.

status
required
integer

The HTTP status code.

title
required
string
type
required
stringformat: uri

402

insufficient_balance or budget_exceeded (the key's spending budget for the period is used up).

Headers: Noptcha-Request-Id, RateLimit (optional), RateLimit-Policy (optional).

Content: application/problem+json

FieldTypeDescription
code
required
string

Machine-readable error code (see the table).

detail
optional
string

Human-readable explanation of this occurrence.

request_id
required
string

Same as the Noptcha-Request-Id header.

status
required
integer

The HTTP status code.

title
required
string
type
required
stringformat: uri

403

forbidden: the key lacks the scope this endpoint needs, the client IP is not in the key's allowlist, the key may not use this task type, or the organization is suspended (detail says which). Also returned, without detail, when the request did not pass through our edge network.

Headers: Noptcha-Request-Id, RateLimit (optional), RateLimit-Policy (optional).

Content: application/problem+json

FieldTypeDescription
code
required
string

Machine-readable error code (see the table).

detail
optional
string

Human-readable explanation of this occurrence.

request_id
required
string

Same as the Noptcha-Request-Id header.

status
required
integer

The HTTP status code.

title
required
string
type
required
stringformat: uri

404

not_found: no such task, it expired (results are kept 10 minutes after completion) or it belongs to another organization; or the task created with this Idempotency-Key has expired.

Headers: Noptcha-Request-Id, RateLimit (optional), RateLimit-Policy (optional).

Content: application/problem+json

FieldTypeDescription
code
required
string

Machine-readable error code (see the table).

detail
optional
string

Human-readable explanation of this occurrence.

request_id
required
string

Same as the Noptcha-Request-Id header.

status
required
integer

The HTTP status code.

title
required
string
type
required
stringformat: uri

409

idempotency_conflict: the Idempotency-Key was used with a different body, or the first request with it is still being processed (retry shortly). task_not_solved: feedback for a task that is not solved (still processing, or failed).

Headers: Noptcha-Request-Id, RateLimit (optional), RateLimit-Policy (optional).

Content: application/problem+json

FieldTypeDescription
code
required
string

Machine-readable error code (see the table).

detail
optional
string

Human-readable explanation of this occurrence.

request_id
required
string

Same as the Noptcha-Request-Id header.

status
required
integer

The HTTP status code.

title
required
string
type
required
stringformat: uri

413

request_too_large: the body exceeds the limit (1 MB for image types, 64 KB otherwise). Any request with a body over 1 MB gets this, GET requests included.

Headers: Noptcha-Request-Id, RateLimit (optional), RateLimit-Policy (optional).

Content: application/problem+json

FieldTypeDescription
code
required
string

Machine-readable error code (see the table).

detail
optional
string

Human-readable explanation of this occurrence.

request_id
required
string

Same as the Noptcha-Request-Id header.

status
required
integer

The HTTP status code.

title
required
string
type
required
stringformat: uri

422

invalid_params: params or metadata do not match the schema; errors lists each problem.

Headers: Noptcha-Request-Id, RateLimit (optional), RateLimit-Policy (optional).

Content: application/problem+json

FieldTypeDescription
code
required
string

Machine-readable error code (see the table).

detail
optional
string

Human-readable explanation of this occurrence.

request_id
required
string

Same as the Noptcha-Request-Id header.

status
required
integer

The HTTP status code.

title
required
string
type
required
stringformat: uri
errors
required
array of FieldError

One entry per problem, sorted by pointer. At most 50 entries; when there are more, detail ends with "and N more errors".

max items 50
errors.[item]
optional
object
errors.[item].message
required
string
errors.[item].pointer
required
string

JSON Pointer (RFC 6901) to the offending value, from the root of the request body: /params/website_key, /params/proxy/port, /params for the parameters object itself, /metadata/order, /metadata for the metadata object itself.

errors.[item].reason
optional
enum

Machine-readable kind, present for image problems: image_too_large (over 1,000,000 characters, the pixel or frame limits, or the images of the task together over the per-task limit; the pointer is the image that went over), image_empty, image_base64 (not valid base64), image_format (not a PNG, JPEG, GIF, WebP or BMP image, a multi-picture JPEG, or malformed or truncated). New values may be added.

one of "image_too_large", "image_empty", "image_base64", "image_format"

429

rate_limited: too many tasks created per second by this key, the same task polled too often, the sandbox's per-organization rate, usage queried too often, the catalog fetched too often from this IP, or this IP sent too many invalid keys. concurrency_limited: the organization has too many tasks in flight for this captcha family (or, with a test key, too many sandbox tasks still processing). Wait Retry-After seconds.

Headers: Noptcha-Request-Id, RateLimit (optional), RateLimit-Policy (optional), Retry-After.

Content: application/problem+json

FieldTypeDescription
code
required
string

Machine-readable error code (see the table).

detail
optional
string

Human-readable explanation of this occurrence.

request_id
required
string

Same as the Noptcha-Request-Id header.

status
required
integer

The HTTP status code.

title
required
string
type
required
stringformat: uri

500

internal: an error on our side.

Headers: Noptcha-Request-Id, RateLimit (optional), RateLimit-Policy (optional).

Content: application/problem+json

FieldTypeDescription
code
required
string

Machine-readable error code (see the table).

detail
optional
string

Human-readable explanation of this occurrence.

request_id
required
string

Same as the Noptcha-Request-Id header.

status
required
integer

The HTTP status code.

title
required
string
type
required
stringformat: uri

503

service_unavailable: no capacity right now (all solvers busy or failing, the gateway is overloaded, a dependency is unavailable). For POST /v1/tasks nothing was created or charged. Wait Retry-After.

Headers: Noptcha-Request-Id, RateLimit (optional), RateLimit-Policy (optional), Retry-After.

Content: application/problem+json

FieldTypeDescription
code
required
string

Machine-readable error code (see the table).

detail
optional
string

Human-readable explanation of this occurrence.

request_id
required
string

Same as the Noptcha-Request-Id header.

status
required
integer

The HTTP status code.

title
required
string
type
required
stringformat: uri

Header descriptions and every schema: Schemas. Machine-readable: openapi.json, openapi.yaml.