Skip to main content
Every request goes to 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 its return_schema) with HTTP 200:
A failed call returns a non-2xx status with an error envelope. The HTTP code tells you the category of failure, and the body carries a machine-readable status plus detail:
The status field is the most useful signal — it maps 1:1 to the HTTP code:
502 is not a Parse outage and should not be auto-retried. It means the target site answered the scraper with a non-2xx (e.g. a 404 for an ID that doesn’t exist, a 401 for bad upstream credentials, a transient site 500). Read upstream_status_code and snippet to see what the site actually said before deciding whether to retry.

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’s input_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:
Decide based on 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_after present (and a Retry-After header) → transient; retry after that many seconds.
  • retry_after: null (and no Retry-After header) → kind is antibot_unsolvable or ip_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.
Fix: revise the API — 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_after is seconds until the next token.
  • limit_type: "daily" — you hit your daily cap. retry_after is seconds until UTC midnight.
Every execution response carries rate-limit headers so you can pace yourself before getting a 429: 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 invalid API-Snapshot-Version header, or session_id/encryption_key sent 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 valid pmx_… key in X-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 returns 404 rather than reveal another account’s resource. Use the scraper_id from your completed task’s generated_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-Id response header from the failing call and include it; it lets us trace your exact request.