Getting started
Errors
Every error code the API can return, what it means and what to do. Generated from the spec.
Errors share one shape, always with credits_used: 0:
{
"success": false,
"error": {
"code": "capacity_exceeded",
"message": "Browser capacity is exhausted; retry shortly.",
"retry_after_ms": 2000
},
"credits_used": 0,
"request_id": "req_01J9V3M2A1"
}Branch on error.code, not on the HTTP status or the message: codes are stable, messages are for humans. Retryable errors carry retry_after_ms (and a Retry-After header).
Error codes#
This table is generated from the Error schema in the OpenAPI spec, so it's never out of date.
invalid_requestHTTP 4000 creditsMeansThe body or query failed validation.messagenames the offending field.DoCheck the field against the reference. Unknown fields are rejected, so watch for typos likeonlyMainContnet.forbiddenHTTP 4030 creditsMeansThe key is valid but your plan or organisation can't use this feature.DoUpgrade the plan, or ask an owner to enable the feature.not_foundHTTP 4040 creditsMeansThe route or resource (usually a crawl id) doesn't exist, or belongs to another organisation.DoDouble-check the id. Crawl results are kept for 30 days.not_implementedHTTP 5010 creditsMeansThe endpoint exists in the spec but isn't live on this deployment yet.DoNothing to fix on your side. Watch the changelog; it costs 0 credits in the meantime.rate_limitedHTTP 429retryable0 creditsMeansRequests per minute or concurrent requests exceeded for your plan.DoWaitretry_after_ms(also sent asRetry-After), then retry. The SDKs do this for you.insufficient_creditsHTTP 4020 creditsMeansYour balance can't cover the request and the plan has no overage (Free), or overage is disabled.DoBuy a top-up or upgrade in Dashboard → Billing.spend_cap_reachedHTTP 4020 creditsMeansYour own monthly spend cap stopped the request. Working as intended.DoRaise or remove the cap in Dashboard → Billing, or wait for the next cycle.blocked_urlHTTP 4000 creditsMeansThe URL resolves to a private, local or otherwise disallowed address (SSRF guard), or robots.txt forbids it.DoUse a public URL. For robots-protected pages on sites you own, crawl withignoreRobots: true.fetch_failedHTTP 502retryable0 creditsMeansThe origin was unreachable, reset the connection or returned an error we couldn't recover from.DoRetry later; check the site loads in a browser. Free.blocked_by_siteHTTP 502retryable0 creditsMeansThe site's bot protection won even after escalation.DoRetry withtier: "premium"(orallowPremium: true) if your plan includes it. Free.timeoutHTTP 504retryable0 creditsMeansThe page didn't finish withintimeout(default 30s).DoRaisetimeout(max 60000) or drop slowactions. Free.unsupported_contentHTTP 4150 creditsMeansThe URL returned a content type we can't convert (for example a video or an archive).DoPoint at an HTML page, PDF or text document instead. Free.capacity_exceededHTTP 503retryable0 creditsMeansOur browser fleet is momentarily full. The site did not block you.DoRetry afterretry_after_ms. SDKs retry automatically. Free.not_configuredHTTP 5010 creditsMeansThe requested tier or feature (premium proxies, search, extract…) has no provider on this deployment.DoUse a different tier (for exampletier: "auto"without premium) or try again once the feature is enabled. Free.extract_failedHTTP 4220 creditsMeansThe model couldn't produce JSON matching your schema, even after one retry.DoLoosen the schema (fewer required fields), add apromptthat explains edge cases, or pass more relevant URLs. Free.internalHTTP 500retryable0 creditsMeansSomething broke on our side. It's been logged with yourrequest_id.DoRetry with backoff. If it persists, send us therequest_id. Free.
Errors inside successful responses#
Some failures are per-item rather than per-request:
- Crawls return
failedcounts, and a crawl that stops early carrieserror: { code, message }in its status. - Extract lists each URL in
sourceswithok: falsefor the ones that failed (and weren't charged). - Search results that couldn't be scraped simply have no
document.
In the SDKs#
Every SDK raises a typed error carrying code, status, message, retryAfterMs and requestId, so you can write if (err.code === "blocked_by_site") instead of parsing strings. See each SDK page for the exact class names.