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

# Error handling

> The error format EDN returns, every status and code, and how to handle each one.

EDN uses standard HTTP status codes. A `2xx` status means the request worked;
anything else means it did not, and the response body says why.

## Error format

Every error returns the same JSON body:

```json theme={"theme":"github-light"}
{
  "detail": "Memory record not found",
  "code": "NOT_FOUND"
}
```

| Field | What it means |
| - | - |
| `detail` | What went wrong, in plain language. Log it rather than showing it to end users |
| `code` | A stable code your app can check. The wording of `detail` may change; `code` does not |

The same `code` is also sent in the `X-EDN-Error-Code` response header.

Validation errors (`422`) also include `errors`, with one entry per problem:

```json theme={"theme":"github-light"}
{
  "detail": "session_id: may only contain letters, digits, '.', '_', ':' and '-'",
  "code": "VALIDATION_ERROR",
  "errors": [
    {
      "field": "session_id",
      "message": "may only contain letters, digits, '.', '_', ':' and '-'"
    }
  ]
}
```

## Status codes

| Status | `code` | Meaning | What to do |
| - | - | - | - |
| `400` | `BAD_REQUEST` | The request could not be processed | Fix the request |
| `400` | `INVALID_DOCUMENT` | The uploaded document is empty or can't be read | Check the file |
| `401` | `UNAUTHORIZED` | The API key is missing, malformed, invalid or revoked | Check the `Authorization` header and your key. See [Authentication](https://docs.tensorpro.ai/authentication.md) |
| `401` | `API_KEY_EXPIRED` | The API key has expired | Create a new key in the Console |
| `401` | `ACCOUNT_PENDING_DELETION` | The account is scheduled for deletion, so its keys no longer work | Contact support if this is unexpected |
| `404` | `NOT_FOUND` | The item does not exist, or is not in your account | Check the ID |
| `409` | `CONFLICT` | The request conflicts with the item's state, for example confirming a memory that doesn't need confirming | Don't retry unchanged |
| `413` | `FILE_TOO_LARGE` | The uploaded file is larger than 10 MB | Upload a smaller file |
| `415` | `UNSUPPORTED_FILE_TYPE` | The file type is not supported (`.pdf`, `.docx`, `.md`, `.txt`) | Convert the file |
| `422` | `VALIDATION_ERROR` | A field is missing or invalid | Fix each field listed in `errors` |
| `429` | `RATE_LIMITED` | You reached the per-minute limit or a daily limit | Wait for the number of seconds in the `Retry-After` header, then retry |
| `500` | `INTERNAL_ERROR` | Something went wrong on EDN's side | Retry later. If it continues, contact support |
| `503` | `SERVICE_UNAVAILABLE` | EDN is temporarily unavailable | Retry after a short wait |

EDN returns `404`, not `403`, for items in another account, so it never
reveals whether an ID exists.

## Retrying safely

* **Retry:** `429` (after `Retry-After`), `500` and `503`, with a growing wait
  between attempts.
* **Don't retry unchanged:** `400`, `401`, `404`, `409`, `413`, `415` and
  `422`. Fix the request first.

```python Python theme={"theme":"github-light"}
import time
import requests

def call_edn(method, url, **kwargs):
    for attempt in range(5):
        resp = requests.request(method, url, **kwargs)
        if resp.status_code == 429:
            time.sleep(int(resp.headers.get("Retry-After", "1")))
        elif resp.status_code in (500, 503):
            time.sleep(2**attempt)
        else:
            return resp
    return resp
```

## Next steps

> [card] [Authentication](https://docs.tensorpro.ai/authentication.md)
>
> API keys and how to send them.

> [card] [API Reference](https://docs.tensorpro.ai/api-reference/overview.md)
>
> The errors each endpoint can return.

> [card] [Quickstart](https://docs.tensorpro.ai/quickstart.md)
>
> A working example.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.