Errors
Failed requests return a non-200 status and an error object:
{
"target_url": "https://example.com",
"error": {
"code": "INVALID_SELECTOR",
"message": "field #0: invalid CSS selector \"a[\": Expected name, found "
}
}| Field | Description |
|---|---|
error.code | Stable machine-readable code, listed below. Branch on this, not on the message |
error.message | Human-readable explanation. May change |
error.status | For HTTP_ERROR only: the status the target site returned |
error.blocked_by | For HTTP_ERROR only, when an anti-bot wall answered: cloudflare, datadome, akamai, perimeterx, imperva, or unknown for a bare 403/429. See Anti-bot protection |
error.attempts | When the target site was reached: requests made before giving up, more than 1 with retries or fallbacks |
warnings | Next to error, when the API adapted something before failing: the same warnings as a successful response |
error.strategy | With error.attempts: the last strategy tried, 0 for the main request. See Fallback strategies |
Codes
Scraping
| HTTP status | error.code | Cause | What to do |
|---|---|---|---|
400 | BAD_REQUEST | Body isn't a JSON object, Content-Type isn't application/json, target_url or fields is missing or malformed, or the body is over 6 MB | Read error.message, fix the body |
400 | INVALID_VARIABLE | In steps, a variable points at nothing, or at an array or object without | json | Check the step name and path, and that the step it reads succeeded |
400 | INVALID_URL | target_url can't be parsed, isn't http(s), or contains credentials | Fix the URL |
499 | CANCELLED | You stopped waiting for the answer (closed the connection): the request was stopped | Nothing: send it again when you need it |
400 | NO_SAVED_PROXIES | "list": "saved", and no proxies are saved | Save them in Developers → Proxies, or send the list |
400 | NOTHING_TO_CONTINUE | A step with "continue": true follows a step that failed | Fix the step before it, or don't continue |
422 | ACTION_FAILED | An action failed in the browser: its element didn't appear in time. The message names it | Fix the selector, mark the action optional, or add a fallback |
400 | INVALID_SELECTOR | A field's selector isn't valid CSS. The message names the field | Fix the selector |
403 | HOST_NOT_ALLOWED | The page redirected to another domain | Request the final URL directly |
404 | NOT_FOUND | Unknown endpoint | Check the path |
405 | METHOD_NOT_ALLOWED | Wrong HTTP method (/scrape needs POST) | Use POST |
502 | HTTP_ERROR | The target site answered with a non-2xx status, or a redirect without a destination | See error.status. For 429 or 5xx, set options.retry. With blocked_by, see Anti-bot protection |
502 | NETWORK_ERROR | DNS, connection or TLS failure reaching the site | Check the URL, or set options.retry |
502 | TOO_MANY_REDIRECTS | The site redirected more than max_redirects times | Raise options.max_redirects, or request the final URL |
502 | RESPONSE_TOO_LARGE | The page is over 10 MB | Target a smaller page |
503 | PROXY_UNAVAILABLE | No proxy available in the requested country, or proxies aren't configured | Try another country, or a fallback with "proxy": false |
503 | BROWSER_UNAVAILABLE | The browser engine isn't installed, couldn't start, or strict refused a substitution | Use another engine, or drop strict |
504 | TIMEOUT | The site took longer than the timeout (15 s by default) | Set options.retry |
500 | UNKNOWN | Unexpected server error | Retry; report it if it persists |
Account and platform
| HTTP status | error.code | Cause | What to do |
|---|---|---|---|
401 | UNAUTHORIZED | Missing, revoked or invalid API key | Check the key |
402 | INSUFFICIENT_CREDITS | Your balance is empty (demo pages stay free) | Add credits |
403 | TERMS_NOT_ACCEPTED | The account hasn't accepted the terms of service | Accept them in the dashboard |
403 | BANNED | The account is suspended | Contact us |
403 | SIGN_IN_REQUIRED | Signed out, the playground runs on the demo pages only (no proxies, exports or captchas) | Sign in |
400 | TARGET_NOT_ALLOWED | The target is a private or internal address | Scrape public sites only |
403 | DOMAIN_BLOCKED | The site can't be scraped on this platform: government and public administration (their open data and APIs are allowed), banks, insurers, illegal content, or a site whose owner asked us to. Checked on redirects and on every page the browser loads too | See the acceptable use policy |
403 | ROBOTS_DISALLOWED | The platform follows robots.txt for every page, and this site's disallows the URL | Pick a URL the site allows |
403 | PLAN_LIMIT | A crawl or batch asks for more pages than your plan runs at once | Ask for fewer, or see Plans |
504 | REQUEST_TOO_LONG | The request ran longer than your plan allows and was stopped | Split it, or see Plans |
400 | UNKNOWN_SECRET | A secret the request names doesn't exist | Create it |
400 | UNKNOWN_CONFIG | A saved config id (or version) that isn't on your account | Check the id in Developers → AI configs |
400 | UNKNOWN_DESTINATION | An export destination that doesn't exist | Check its name |
413 | PAYLOAD_TOO_LARGE | The request body is over 1 MB | Send less, or split it into a batch |
429 | RATE_LIMITED | Over 60 requests a minute on this key (or, in the dashboard, over 300 a minute from your address) | Slow down |
429 | TOO_MANY_CONCURRENT_REQUESTS | Free plan: a request is already running | Wait for it, or see Plans |
429 | QUEUE_FULL | Your plan's waiting line is full | Slow down |
503 | QUEUE_TIMEOUT | The request waited 2 minutes for a slot: nothing ran, nothing billed | Retry, or send an async job |
502 | ENGINE_UNAVAILABLE | The scraping service couldn't run the request | Retry in a moment |
422 | TEMPLATE_NOT_LEARNED | The AI couldn't write fields that work on every check of a template | Change the prompt or the page |
503 | TEMPLATE_LEARNING | The template is still learning on another request | Retry in a moment |
A selector that matches nothing is not an error: you get 200 and that value is null (or [] with "multiple": true).