Skip to documentation
Browse documentation

Errors and retries

Handle stable error codes and retry only safe failures.

View raw

Public REST errors use a stable machine-readable error.code and a human-readable error.message. Branch on the code or HTTP status, not on message text.

Canonical errors

HTTP Code Meaning Retry unchanged?
401 unauthorized Bearer token is missing or invalid No
402 account_inactive The account is not active. A prepaid account becomes active with its first credit purchase; a suspended account needs support No
402 quota_exhausted The account does not have enough credits for this request (on a legacy subscription: no request quota remains in the period) No, buy credits first
403 forbidden The API key is not authorized for this operation No
422 credit_limit_exceeded The published job price exceeds the requested max_credits No, raise max_credits
422 monitor_limit_reached The account is at its active monitor limit No
404 not_found The requested job does not exist for this account No
405 method_not_allowed The endpoint takes another method; the Allow header names it (POST for /execute) No, change the method
451 subject_unavailable The input names a profile whose owner asked not to be returned through Upscrape; no job was created No
409 idempotency_conflict The key was used for different input No
422 credentials_required The capability needs stored upstream credentials No
422 api_key_limit_reached The account already has the maximum number of active API keys (25); revoke one first No
429 rate_limited The account or key exceeded its current rate Yes, after delay
500 internal_error Upscrape encountered an unexpected failure Usually, with idempotency
500 result_unavailable The result is unavailable No; contact support with the job ID
422 invalid_input The request failed validation; error.fields names each field No, fix the request
503 temporarily_unavailable The capability cannot be served right now; no job was created Not immediately; try again later or use another capability
503 execution_lost The request ended without a result Yes, submit a new job

Failed jobs return reviewed public error codes and messages. Diagnostic details are not included. When Prefer: wait=N returns a failed job inline, its HTTP status reflects the known failure class:

HTTP Terminal job codes
403 forbidden, auth_failed, auth_session_expired
404 not_found
413 payload_too_large
422 invalid_input, unsupported_capability, incomplete_result
424 upstream_error, upstream_http_error
429 upstream_blocked
503 worker_unavailable, worker_saturated, execution_lost, execution_interrupted, ocr_unavailable
504 upstream_timeout, execution_timeout_exceeded

An unrecognized terminal code returns HTTP 500; HTTP 200 is reserved for completed work and idempotent replay envelopes.

Validation errors

A request that fails validation returns HTTP 422 with the standard envelope. error.fields maps each failed field to its messages, and error.message summarises them.

{
  "error": {
    "code": "invalid_input",
    "message": "request validation failed: input $.value must be string",
    "fields": {"input": ["$.value must be string"]}
  },
  "errors": {"input": ["$.value must be string"]},
  "request_id": "request_id"
}

The top-level errors object is the original shape of this response. It is retained for compatibility, carries the same field map as error.fields, and will not be removed. New integrations should read error, as they do for every other failure.

Rate limits

HTTP 429 includes a Retry-After header in seconds and error.retry_after_ms in the JSON body. Wait at least that long and add jitter before retrying.

{
  "error": {
    "code": "rate_limited",
    "message": "rate limit exceeded",
    "retry_after_ms": 1250
  }
}

Safe retry policy

  • Retry rate limits after the advertised delay.
  • Retry transient transport failures and internal errors only with the original idempotency key.
  • Poll an existing pending job instead of resubmitting it.
  • If a terminal job reports execution_lost, submit a new job; the failed job has no stored result and is not charged.
  • Do not retry authentication, billing, credential, validation, or idempotency-conflict failures unchanged.
  • Put a total deadline and attempt limit around every retry loop.

Redaction

Job failure messages are sanitized before they enter the public response. Even so, applications should avoid copying entire upstream responses into their own logs without an additional data-sensitivity review.

Credit prices and plans: Upscrape pricing