---
title: Errors and response contracts
description: Stable invocation error codes, HTTP statuses, MCP envelopes and completed job failures.
---

HTTP invocation failures return one structured error:

```json
{
  "error": {
    "code": "CAPACITY_EXCEEDED",
    "message": "Capacity exceeded. Retry shortly.",
    "details": { "retryAfterSeconds": 5 }
  }
}
```

Branch on `error.code`, not the message. Successful REST responses keep their endpoint-specific values: rows, arrays, aggregates or JSON null. There is no success envelope added to REST.

## HTTP codes

| HTTP status | Code | Meaning / details |
|---|---|---|
| 400 | `VALIDATION_ERROR` | Invalid request fields. `details.issues` contains `path`, `code` and a safe `message`. |
| 400 | `MALFORMED_REQUEST` | Malformed request body; also missing/invalid signed webhook input. |
| 400 | `BLOCKED_URL` | URL rejected by the public-address policy before admission. |
| 401 | `UNAUTHENTICATED` | Missing, malformed, invalid or revoked credential. |
| 403 | `FORBIDDEN` | API-key authentication used for a signed-in-user endpoint. |
| 404 | `NOT_FOUND` | Resource missing or outside caller scope; also unconfigured OAuth discovery. |
| 405 | `METHOD_NOT_ALLOWED` | Unsupported MCP HTTP method; `Allow: POST` is included. |
| 402 | `QUOTA_EXCEEDED` | Insufficient credits; details contain `creditsLimit`, `creditsUsed`, `creditsRemaining`. |
| 503 | `CAPACITY_EXCEEDED` | Admission capacity exhausted; details contain `retryAfterSeconds`, with matching `Retry-After` header. |
| 503 | `SERVICE_UNAVAILABLE` | Readiness dependency is unavailable. |
| 502 | `UPSTREAM_ERROR` | Upstream operation failed, such as OAuth metadata retrieval. |
| 500 | `INTERNAL_ERROR` | Unexpected failure. The response contains a fixed message rather than exception diagnostics. |

Validation paths retain schema field names and numeric array indices; dynamic record keys can appear as `*`. Submitted values and raw exception messages are not included. Quota rejection currently reports `creditsRemaining: 0`. Error details depend on the code, so do not assume every error contains them.

MCP HTTP authentication failures retain the `WWW-Authenticate` discovery challenge. Successful Stripe webhook processing returns an empty 204; invalid verification returns 400, while unexpected processing failure returns 500.

## Invocation failure versus job outcome

An accepted scrape can fail at a target URL. That failure is stored in the job/result and is distinct from the invocation error above. A completed HTTP 200 scrape/analyse array can contain successful and failed entries. Map can return usable sitemaps alongside an aggregate `error`. Stored job diagnostics keep their existing `message`, `name`, `stack` and `cause` shape; they are not converted into invocation codes.

HTTP 202 means work was accepted and is still being waited on, or immediate return was requested. Submission responses contain the original jobs. Poll those IDs; do not submit again. Result reads can return JSON null: inspect the job for status. See [Jobs](/docs/api/jobs).

## MCP application envelope

The SDK JSON-RPC result retains its `content` array. Its text item contains JSON:

```json
{ "ok": false, "error": { "code": "NOT_FOUND", "message": "Resource not found." } }
```

Invocation failures set SDK `isError: true`. Successful calls use `{ "ok": true, "data": ... }`. Fetching a failed job or returning mixed per-URL outcomes is a successful invocation. See [MCP response shapes](/docs/mcp#response-shapes) for each tool's `data` value.

Unknown tools use `NOT_FOUND`; invalid tool arguments use `VALIDATION_ERROR` with a safe generic issue. Malformed protocol messages remain JSON-RPC invalid-request errors (`-32600`), and unknown protocol methods remain method-not-found (`-32601`). HTTP parsing and authentication occur before tool dispatch and use the HTTP errors above.

## Public web tools

The anonymous tool page uses a separate operation outcome with `remaining` free runs: `completed`, `failed`, `pending`, or `signup_required`. Pending is HTTP 202 and retains `jobIds`; completed failures and the signup gate are HTTP 200 observations. Invocation failures use the structured error object, with remaining-run metadata under `error.details` when a run was spent. Captcha failures add the web-owned codes `CAPTCHA_REQUIRED` (400) and `CAPTCHA_FAILED` (403).

## Contract change and rollout

This contract replaces string HTTP errors, key mutation receipts and unwrapped MCP application content directly. Clients must read `error.code`, consume returned safe key rows for rename/revoke, and unwrap MCP `ok`/`data` before reading results. No compatibility window or response alias is provided.

Clients should decode the current structured invocation errors and distinguish them from stored job failures. SDK JSON-RPC framing, scrape/analyse/map and job-read success values, and stored job diagnostics retain their documented shapes. Key rename/revoke return safe key rows.
