↑ ↓ to move ↵ to open

Errors and retries

Every error code, what it means, and which ones to retry.

Every error carries a stable error.code you can branch on, and an error.message written for people. Codes never change; messages may be reworded, so never match on the text.

A call that fails costs nothing.

The shape of an error

A real 422
{  "error": {    "code": "invalid_input",    "message": "query is required",    "fields": {"input": ["query is required"]}  },  "errors": {"input": ["query is required"]},  "request_id": "GN8buUl9sP7R2_0AAH9h"}
  • error.code is what to branch on.

  • error.fields appears on invalid_input and names each field that is wrong.

  • request_id identifies the request. Send it to support if you need help.

An error happens at one of two moments: when Upscrape receives your request, before any job exists, or while the job runs. The two tables below cover each.

When the request is refused

These come back at once, with no job created and nothing charged.

HTTPCodeWhat it meansWhat to do
401unauthorizedThe API key is missing, wrong or revoked.Send Authorization: Bearer with a valid key.
402quota_exhaustedYour balance cannot cover this call.Buy credits, then call again.
402account_inactiveThe account is not active.Buy credits to activate it, or contact support.
403forbiddenThis key may not do this, for example a read-only key that tries to run an endpoint.Use a key with the right access.
403contact_for_accessThe platform is available by request.Contact us to enable it.
404not_foundThe job or monitor does not exist for this account.Check the ID.
405method_not_allowedThe address takes another method; the Allow header names it.Use POST for /execute.
409idempotency_conflictThe Idempotency-Key was already used for a different request.Use a new key for a new request.
422invalid_inputThe body does not fit the endpoint's input; error.fields says where.Fix the input.
422credit_limit_exceededThe price is above your max_credits.Raise max_credits, or change the input.
422api_key_limit_reachedThe account already has 25 active keys.Revoke one first.
422monitor_limit_reachedThe account has as many active monitors as it can.Pause or delete one first.
429rate_limitedToo many requests in a minute.Wait Retry-After, then try again.
451subject_unavailableThe profile's owner asked not to be returned through Upscrape.Nothing; this input will not work.
500internal_errorSomething went wrong on our side.Retry with the same Idempotency-Key.
503temporarily_unavailableThe endpoint cannot run right now.Try again later, not in a tight loop.

When the job fails

A job that fails ends with state: "failed", success: false and the error. You see it when you fetch the job, or at once if you sent Prefer: wait and the job failed in that time; the HTTP status then follows the kind of failure, but the code is what to branch on.

JSON
{  "job_id": "d7ef67f5-8cb8-4989-8b55-8ba67a1aab4f",  "state": "failed",  "success": false,  "error": {    "code": "not_found",    "message": "The requested resource was not found."  }}
CodeWhat it meansTry again?
invalid_inputThe platform did not accept the input, for example an ID in the wrong form.No. Fix the input.
not_foundWhat you asked for does not exist, or no longer does.No.
website_not_foundThe site's host name does not exist.No. Check the URL.
forbiddenThe data is not public. error.reason is account_private for a private account.No.
login_requiredThe platform shows this data only to signed-in visitors.No.
unsupported_contentThe URL is not a page or a document Upscrape can read.No.
response_too_largeThe page is larger than max_body_bytes allows.Raise max_body_bytes, or set allow_truncated.
incomplete_resultThe page did not hold what the call needs; for an extraction, the message names the fields it could not find.Not unchanged. Check the input or the fields you asked for.
blockedThe platform is refusing requests for a while.Yes, after a pause.
upstream_rate_limitedThe platform is limiting requests for a while.Yes, after a pause.
timeoutThe call took longer than the endpoint's run time.Yes.
upstream_timeoutThe platform did not answer in time.Yes, after a pause.
upstream_errorThe platform's answer could not be read this time.Yes, after a pause.
schema_changedThe platform changed the format of what it returns.Later. We fix the endpoint; tell us if it lasts.
temporarily_unavailableThe endpoint could not run right now.Yes, later.
execution_lostThe job ended without a result. Nothing was stored or charged.Yes. Send a new request.
result_unavailableThe job finished but its result cannot be returned.No. Contact support with the job_id.
cancelledThe job was cancelled.Send a new request if you still need it.
internal_errorSomething went wrong on our side.Yes.

Retry safely

  • Retry only the codes marked yes above, and rate_limited after its Retry-After.

  • Wait longer between attempts each time, for example 1, 2, 4, 8 seconds, and give up at a deadline you choose.

  • Retry a request with its original Idempotency-Key, so a retry after a lost response never runs or charges twice.

  • To wait for a slow job, fetch it with GET /jobs/{id}; don't send the request again.

  • Never retry a key, balance, input or idempotency error unchanged: it fails the same way.

Validation messages

invalid_input says exactly what is wrong: the missing field, the accepted alternatives, the expected type, and an example when the endpoint gives one. REST, MCP and the console show the same messages.

The response also carries the field map at the top level as errors. That is the original shape of this response, kept so older integrations keep working; read error.fields in new code.

Something missing or unclear? Ask the team that builds the endpoints.