Skip to content

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:

json
{
  "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 credits
    MeansThe body or query failed validation. message names the offending field.DoCheck the field against the reference. Unknown fields are rejected, so watch for typos like onlyMainContnet.
  • unauthorizedHTTP 4010 credits
    MeansMissing, malformed, revoked or expired API key.DoSend Authorization: Bearer vmn_live_…. Rotate the key in the dashboard if it leaked.
  • forbiddenHTTP 4030 credits
    MeansThe 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 credits
    MeansThe 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 credits
    MeansThe 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 credits
    MeansRequests per minute or concurrent requests exceeded for your plan.DoWait retry_after_ms (also sent as Retry-After), then retry. The SDKs do this for you.
  • insufficient_creditsHTTP 4020 credits
    MeansYour 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 credits
    MeansYour 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 credits
    MeansThe 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 with ignoreRobots: true.
  • fetch_failedHTTP 502retryable0 credits
    MeansThe 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 credits
    MeansThe site's bot protection won even after escalation.DoRetry with tier: "premium" (or allowPremium: true) if your plan includes it. Free.
  • timeoutHTTP 504retryable0 credits
    MeansThe page didn't finish within timeout (default 30s).DoRaise timeout (max 60000) or drop slow actions. Free.
  • unsupported_contentHTTP 4150 credits
    MeansThe 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 credits
    MeansOur browser fleet is momentarily full. The site did not block you.DoRetry after retry_after_ms. SDKs retry automatically. Free.
  • not_configuredHTTP 5010 credits
    MeansThe requested tier or feature (premium proxies, search, extract…) has no provider on this deployment.DoUse a different tier (for example tier: "auto" without premium) or try again once the feature is enabled. Free.
  • extract_failedHTTP 4220 credits
    MeansThe model couldn't produce JSON matching your schema, even after one retry.DoLoosen the schema (fewer required fields), add a prompt that explains edge cases, or pass more relevant URLs. Free.
  • internalHTTP 500retryable0 credits
    MeansSomething broke on our side. It's been logged with your request_id.DoRetry with backoff. If it persists, send us the request_id. Free.

Errors inside successful responses#

Some failures are per-item rather than per-request:

  • Crawls return failed counts, and a crawl that stops early carries error: { code, message } in its status.
  • Extract lists each URL in sources with ok: false for 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.