# Errors

> Crius API error format, HTTP status codes and every error code with its meaning and what to do about it.

Source: https://crius.sh/docs/errors/

Errors return a non-2xx HTTP status and a JSON body:

```json
{
  "error": {
    "code": "plan_required",
    "message": "this endpoint needs the free plan or higher"
  }
}
```

Match on `error.code` (stable, machine-readable); `message` is for humans and may change.

## Authentication and access

| Status | Code | Meaning | What to do |
|---|---|---|---|
| 401 | `key_required` | This endpoint needs a key and none was sent | Send `x-api-key` |
| 401 | `invalid_key` | The key doesn't exist or the secret is wrong | Check for typos or a truncated key |
| 401 | `key_rotated` | The key was rotated and its grace period ended | Use the new key |
| 401 | `key_revoked` | The key was revoked | Create a new key |
| 401 | `key_expired` | The key passed its expiry date | Create a new key |
| 403 | `account_suspended` | The account is suspended | Contact support@crius.sh |
| 403 | `plan_required` | Your plan doesn't include this endpoint | Upgrade, see [plans](https://crius.sh/docs/plans-and-limits/) |
| 403 | `scope_required` | The key lacks the scope (`stream`, `simulate`) | Edit the key's scopes |
| 403 | `ip_not_allowed` | The client IP isn't in the key's allow-list | Update the allow-list |
| 403 | `origin_not_allowed` | The browser origin isn't allowed for this key | Add the origin to the key |
| 403 | `session_required` | Account management needs a dashboard session | Use the dashboard |
| 403 | `session_not_api_key` | A dashboard session was used on a data endpoint | Use an API key |

## Limits

| Status | Code | Meaning | What to do |
|---|---|---|---|
| 429 | `rate_limited` | Over your requests-per-second limit | Wait `retry-after` seconds, then retry |
| 429 | `quota_exceeded` | Monthly credits used up | Upgrade or wait for the next month |
| 429 | `auth_banned` | Too many failed authentications from this IP | Wait 60 s and fix the key |
| 503 | `busy` | Too many heavy analytics requests in flight | Retry shortly with backoff |

## Requests

| Status | Code | Meaning |
|---|---|---|
| 400 | `invalid_address` | Not a valid `0x` address |
| 400 | `invalid_pool` | Not a valid pool address or v4 pool id |
| 400 | `invalid_interval` | Unsupported candle interval |
| 400 | `invalid_window` | Unsupported stats window |
| 400 | `invalid_cursor` | The cursor is malformed or from another list |
| 400 | `invalid_at` | The point in time (`at`, `from`, `to`) couldn't be parsed |
| 400 | `invalid_list`, `invalid_sort`, `invalid_tz` | An unsupported option |
| 400 | `too_many_tokens` | More than 100 tokens in a batch |
| 400 | `window_too_large` | The requested time window is too large for this endpoint |
| 400 | `token_too_active` | The token has too much history for this query (holder history) |
| 400 | `invalid_request` | Malformed query string or body |
| 413 | `payload_too_large` | Request body over 256 KB |

## Not found

| Status | Code | Meaning |
|---|---|---|
| 404 | `chain_not_found` | Unknown chain slug or id |
| 404 | `token_not_found` | We have no token at this address |
| 404 | `pool_not_found` | No such pool |
| 404 | `wallet_not_found`, `dev_not_found` | No activity for this address |
| 404 | `hook_not_found`, `launch_not_found`, `launchpad_not_found` | No such hook, launch or launchpad |
| 404 | `point_not_found` | The point in time (`mcap:`, `graduation`…) never happened for this token |
| 404 | `not_ready` | The data is still being indexed; retry shortly |
| 404 | `stream_unavailable` | The stream isn't enabled on this node |

## Server

| Status | Code | Meaning |
|---|---|---|
| 500 | `internal` | Something broke on our side; it is logged. Retry, and contact support if it persists |
| 504 | `timeout` | The request took longer than 10 seconds |

Check [status.crius.sh](https://status.crius.sh) for ongoing incidents.
