> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.aurasos.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.aurasos.com/_mcp/server.

# Errors & status codes

The Panic API uses standard HTTP status codes to indicate the result of a
request: `2xx` for success, `4xx` for client errors, and `5xx` for server
errors.

## Error body shape

Error bodies are **not uniform** across routes. Depending on the endpoint you
may receive any of:

* `{"message": "..."}` — a string description (most routes).
* `{"errors": ...}` — a string, an array of strings, or an object (some routes
  serialise the underlying error).
* `{"error": "..."}` — used by a few routes, including rate limiting.

Parse defensively: check `message`, then `errors`, then `error`, and log the
raw body for anything unexpected.

## Status codes

| Code                        | Meaning                                                                                                                                                                                                                            |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `200` OK                    | The request succeeded. Creates and deletes also return `200` (not `201`/`204`).                                                                                                                                                    |
| `285`                       | Panic API custom code: a location update was sent for a **closed** callout. The update is not processed, but the body still carries the latest callout state — use it as the signal to stop polling/streaming.                     |
| `400` Bad Request           | The request was malformed — missing fields, bad formatting, or invalid values. Note some lookup failures surface as `400` rather than `404` (for example an unknown `externalReferenceId` when creating a fixed-location callout). |
| `401` Unauthorized          | Authentication is missing or invalid. Check the `clientId`, `clientSecret`, or bearer token. Also returned when a callout-scoped token is used outside the callout flow.                                                           |
| `403` Forbidden             | Authenticated, but not permitted — for example, creating a callout for a customer without an active subscription.                                                                                                                  |
| `404` Not Found             | The resource doesn't exist or isn't visible to your customer source. Check the path and identifiers.                                                                                                                               |
| `409` Conflict              | Returned by subscription creation when the request conflicts with current state (e.g. an already-active subscription).                                                                                                             |
| `429` Too Many Requests     | Rate limited. `GET /panic-api/v2/customers/{customerId}/subscriptions` allows \~50 requests per 10 seconds per customer source; the response carries `RateLimit-*` headers and an `error` body.                                    |
| `500` Internal Server Error | An unexpected server-side error.                                                                                                                                                                                                   |
| `502` Bad Gateway           | An upstream service returned an invalid response; retry shortly.                                                                                                                                                                   |

## Handling errors

* Read the body (see shapes above) for a human-readable explanation.
* Treat `5xx` (and `502`) as transient — retry with backoff.
* Treat `4xx` as actionable — fix the request or the resource state before retrying.
* Honour `429` by backing off until the `RateLimit-Reset` window passes.