Reference
Errors
Every error_class, its HTTP status, and whether retrying helps.
A failed run returns ok: false and names what happened:
{
"ok": false,
"error_class": "timeout",
"error_detail": "timed out after 15000ms",
"retryable": true,
"url": "https://example.com/orders",
"elapsed_ms": 15002
}
Branch on error_class. It is a stable identifier. error_detail is a
human-readable message meant for your logs and your on-call, and its wording can
change — do not match on it.
retryable says whether the same request could succeed later. It is not a
promise, it is a signal: retry the retryable ones with backoff, and surface the
rest.
API errors
Raised before or around the scrape itself.
error_class | HTTP | What it means |
|---|---|---|
auth_failed | 401 | Missing or wrong credential. Check you sent the right one — Authentication. |
forbidden | 403 | Authenticated, but not allowed to do this. |
bad_request | 400 | The body broke a rule: mutually exclusive fields, a malformed id, proxy_session_lifetime without proxy_session. |
not_found | 404 | No such job, schedule, account or session. |
unknown_provider | 400 | No proxy provider serves that type, country, or stacking combination. |
insufficient_credits | 402 | Out of credits. Not retryable — top up first. |
concurrency_limit_exceeded | 429 | At your plan’s in-flight cap. Retryable after a wait. |
queue_timeout | 504 | No browser context came free in time, or no engine is live. |
queue_unavailable | 503 | The control plane is unreachable. |
engine_unavailable | 503 | No engine could take the request. |
session_busy | 409 | That session_id is already in flight. |
account_unavailable | 409 | The account has no healthy logged-in session. |
account_busy | 409 | All of the account’s healthy sessions are in use. |
Engine errors
Raised while fetching the page.
error_class | HTTP | Retryable | What it means |
|---|---|---|---|
timeout | 502 | yes | The target did not answer in time. |
navigation_timeout | 502 | yes | The browser never reached a loaded state. |
proxy_error | 502 | yes | The proxy hop failed. |
network / network_error | 502 | yes | Connection failed. |
pool_exhausted | 429 | yes | The engine is at capacity. |
browser_crash | 502 | yes | The browser died mid-page. |
shutting_down | 503 | yes | The engine is draining. Retry lands elsewhere. |
tls_error | 502 | no | TLS negotiation failed. |
redirect_error | 502 | no | A redirect chain was invalid or too long. |
decoding_error | 502 | no | The body could not be decoded. |
unknown | 500 | no | Unclassified. Tell us — this one is a bug. |
Things that are not errors
blocked: true means the response looks like an anti-bot challenge rather
than your page. ok is still true, block_reason says which rule matched,
and the run is charged — we did the work. Usually the fix is
proxy_type: "premium" or a different country, not a retry.
Retrying
Retry retryable classes with exponential backoff and a cap. Do not retry
insufficient_credits, bad_request, auth_failed or the non-retryable engine
errors — the same request will fail the same way.
Failed runs on our side cost nothing, so a retry loop is not a billing risk. Credits sets out exactly what is charged.