https://api.parse.bot. This page is the definitive reference for what each status code means — especially for executing endpoints (POST /scraper/{scraper_id}/{endpoint_name}), where Parse wraps the outcome in a structured envelope so you can tell whose fault a failure is: yours, the target site’s, or the scraper’s.
The execution envelope
A successful call returns the endpoint’s own JSON (the shape described by itsreturn_schema) with HTTP 200:
error envelope. The HTTP code tells you the category of failure, and the body carries a machine-readable status plus detail:
status field is the most useful signal — it maps 1:1 to the HTTP code:
422 — stale_input (your input is the problem)
The scraper rejected your input before or during the upstream call — wrong type, missing required field, or a resource the site says is gone.
kind: "input_format_invalid"— a parameter is malformed. Fix it against the endpoint’sinput_params.kind: "input_not_found"— the specific thing you named (a job ID, a product SKU) was confirmed gone by the site (often a 410). Not retryable with the same input.
502 — upstream_error (the target site failed)
The scraper reached the site, but the site returned a non-2xx. The body tells you exactly what came back:
upstream_status_code: a 404/410 usually means your input pointed at nothing (don’t retry); a 5xx from the site may be transient (retry with backoff); a 401/403 may mean the API’s stored credentials need attention (revise the API).
503 — blocked (anti-bot stopped us)
Parse rotated through proxies and every attempt hit the site’s bot protection.
retry_afterpresent (and aRetry-Afterheader) → transient; retry after that many seconds.retry_after: null(and noRetry-Afterheader) →kindisantibot_unsolvableorip_burned; retrying soon won’t help. If it persists, the API may need a revision.
500 — error (the scraper bugged out)
The scraper crashed or detected an internal fault. This is the API’s problem, not yours.
POST /dispatch/tasks/{task_id}/revise with a description (e.g. “the get_paper endpoint 500s on valid IDs”). If it’s a marketplace/canonical API, the revision improves it for everyone.
429 — rate limited
limit_type: "burst"— you exceeded the short-term token bucket.retry_afteris seconds until the next token.limit_type: "daily"— you hit your daily cap.retry_afteris seconds until UTC midnight.
Authenticated login endpoints have a stricter cap (3 attempts/hour per API) — see Authenticated APIs.
400 / 401 / 404 — request problems
400— a malformed request: an invalidAPI-Snapshot-Versionheader, orsession_id/encryption_keysent only one of the pair. Body:{"error": "<reason>", "status_code": 400}.401—{"error": "Missing X-API-Key header" | "Invalid API key" | "API key expired", "status_code": 401}. Send a validpmx_…key inX-API-Key(header name is case-insensitive; the value is not). See Authentication.404—{"error": "Scraper with ID '…' not found", "status_code": 404}. The scraper or pinned version doesn’t exist, or isn’t yours — Parse returns404rather than reveal another account’s resource. Use thescraper_idfrom your completed task’sgenerated_api.
A bare JSON
{"detail":"Not Found"} (note: detail, not error) means the path doesn’t exist, not the scraper. Check you’re calling POST /scraper/{scraper_id}/{endpoint_name} exactly, on https://api.parse.bot.Build failures (task status: "failed")
A dispatch/revision task can finish failed rather than completed; the task’s error field says why. Retry with a clearer task description, revise it, or — if may_require_auth was true — build it as an Authenticated API from the dashboard.
Still stuck?
- Confirm the base URL:
https://api.parse.bot. - Verify your key with a cheap call:
GET /dispatch/tasks. - Reach out to support from the dashboard — click the chat icon in the bottom-right corner to start a conversation with us. Grab the
X-Railway-Request-Idresponse header from the failing call and include it; it lets us trace your exact request.