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

# Error Handling

> Understand Zerion API error responses, HTTP status codes, rate limits, and best practices for retry logic.

The Zerion API uses standard HTTP status codes and returns structured error responses. This page covers what to expect and how to handle errors gracefully.

## Error response format

All errors return a JSON object with an `errors` array:

```json theme={null}
{
  "errors": [
    {
      "title": "Short error description",
      "detail": "A longer explanation of what went wrong"
    }
  ]
}
```

## HTTP status codes

| Status | Meaning           | When it happens                                                                         |
| ------ | ----------------- | --------------------------------------------------------------------------------------- |
| `200`  | Success           | Request completed successfully                                                          |
| `400`  | Bad Request       | Malformed parameters — check filter values, missing required fields, or invalid formats |
| `401`  | Unauthorized      | Missing or invalid API key                                                              |
| `404`  | Not Found         | The requested resource doesn't exist (single-resource endpoints only)                   |
| `429`  | Too Many Requests | Rate limit exceeded                                                                     |
| `500`  | Server Error      | Unexpected error on Zerion's side — safe to retry with backoff                          |

### 400 — Bad Request

Returned when query parameters are malformed or invalid. Check the `detail` field for specifics.

```json theme={null}
{
  "errors": [
    {
      "title": "Malformed parameter was sent",
      "detail": "chain {invalidchain} is not supported"
    }
  ]
}
```

**Common causes:**

* Invalid `filter[chain_ids]` value (e.g., a chain ID that doesn't exist)
* `page[size]` outside the allowed range (the maximum varies by endpoint)
* Missing required parameters (e.g., `filter[references]` on the NFTs endpoint)
* Malformed `filter[min_mined_at]` timestamp (must be exactly 13 digits, in milliseconds)

### 401 — Unauthorized

Returned when the API key is missing, invalid, or incorrectly encoded.

```json theme={null}
{
  "errors": [
    {
      "title": "Unauthorized Error",
      "detail": "The API key is invalid, please, make sure that you are using a valid key"
    }
  ]
}
```

**Common causes:**

* Missing `Authorization` header
* API key not Base64-encoded correctly — remember to append a colon: `base64("your_key:")`
* Expired or revoked API key

<Tip>
  Test your encoding: `echo -n "your_api_key:" | base64` should produce the value you pass after `Basic `.
</Tip>

### 404 — Not Found

Returned on single-resource endpoints when the ID doesn't match any record.

```json theme={null}
{
  "errors": [
    {
      "title": "Requested fungible was not found",
      "detail": "You have requested fungible which does not exist"
    }
  ]
}
```

This only applies to endpoints like `/v1/fungibles/{fungible_id}` or `/v1/nfts/{nft_id}`. List endpoints return an empty `data` array instead of a 404.

### 429 — Too Many Requests

Returned when you exceed your plan's rate limit.

```json theme={null}
{
  "errors": [
    {
      "title": "Too many requests",
      "detail": "Your request had been throttled"
    }
  ]
}
```

Implement exponential backoff when retrying. For header details and retry guidance, see [Rate Limits](/rate-limits). If you're hitting limits consistently, see [Pricing](/pricing) to compare plans or upgrade in the [Dashboard](https://dashboard.zerion.io).

### 500 — Server Error

Returned when something unexpected goes wrong on Zerion's side.

```json theme={null}
{
  "errors": [
    {
      "title": "Internal Server Error",
      "detail": "An unexpected error occurred"
    }
  ]
}
```

These errors are safe to retry. Use exponential backoff (e.g., 1s, 2s, 4s) and cap your retries. If the error persists, reach out to support.

## Best practices

* **Retry on `429` and `500` only.** Do not retry `400` or `401` — these require fixing the request itself.
* **Use exponential backoff.** When retrying, increase the delay between attempts exponentially (e.g., 1s, 2s, 4s) to avoid overwhelming the API.
* **Validate parameters before sending.** Check that `page[size]` is within the endpoint's allowed range, timestamps are 13-digit milliseconds, and chain IDs match the [supported chains](/supported-blockchains). This avoids unnecessary `400` errors.
* **Use webhooks instead of polling.** If you need to monitor wallet activity, use [transaction subscriptions](/api-reference/subscriptions-to-transactions/create-subscription) instead of polling. This reduces API usage and gives you faster notifications.
