> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pickupbell.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Uniform error shape across REST and MCP.

Every PickupBell error response has the same shape, regardless of status code:

```json theme={null}
{
  "error": {
    "code": "forbidden",
    "message": "missing scope: calls:read",
    "details": { "location_id": "…" }
  }
}
```

## Error codes

| `error.code`   | HTTP | Meaning                                                                                               |
| -------------- | ---- | ----------------------------------------------------------------------------------------------------- |
| `unauthorized` | 401  | Missing, malformed, or revoked Bearer token.                                                          |
| `forbidden`    | 403  | Token is valid but lacks the required scope, or target belongs to another location.                   |
| `not_found`    | 404  | The resource (or the location it belongs to) doesn't exist from this caller's perspective.            |
| `validation`   | 400  | Your request body or query parameter is wrong. `details` may include a field-level reason.            |
| `conflict`     | 409  | The operation would create a duplicate or break an invariant (e.g. removing the sole location owner). |
| `server`       | 500  | Unhandled server-side error. Safe to retry with idempotency.                                          |

## Retries

* `5xx` responses are retry-safe — we return them specifically for transient conditions (database timeouts, upstream provider outages).
* `4xx` responses are **not** retry-safe; fix the request and resubmit.
* All POST endpoints are idempotent over the same payload: retrying the same `POST /leads` with the same body within a short window will not create duplicates.

## MCP errors

MCP uses JSON-RPC 2.0 error codes, mapped from `ServiceError`:

| JSON-RPC code | PickupBell `code`         | Notes                          |
| ------------- | ------------------------- | ------------------------------ |
| -32600        | (malformed request)       | Raw JSON-RPC transport error   |
| -32601        | (method / tool not found) |                                |
| -32602        | `validation`              |                                |
| -32001        | `unauthorized`            | Missing / invalid Bearer token |
| -32002        | `forbidden`               | Scope missing                  |
| -32003        | `not_found`               |                                |
| -32004        | `conflict`                |                                |
| -32603        | `server`                  |                                |

The `error.data.httpStatus` field on JSON-RPC errors carries the matching HTTP status for tools that round-trip through a REST proxy.
