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

# Errors

> HTTP status codes, error response format, and how to handle failures.

The Memic API uses conventional HTTP status codes. `2xx` means success, `4xx`
means the request had a problem (fix it and retry), `5xx` means Memic had a
problem (retry with backoff).

## Error response format

Error responses are JSON with a stable shape:

```json theme={null}
{
  "detail": "File not found",
  "code": "file_not_found",
  "request_id": "req_01J9..."
}
```

* **`detail`** — human-readable error message
* **`code`** — stable machine-readable error code (use this for programmatic handling)
* **`request_id`** — opaque ID for support tickets; include it when filing issues

## HTTP status codes

| Code            | Meaning                                                         | What to do                                                         |
| --------------- | --------------------------------------------------------------- | ------------------------------------------------------------------ |
| **200**         | Success                                                         | —                                                                  |
| **201**         | Created                                                         | —                                                                  |
| **204**         | No content (e.g. after DELETE)                                  | —                                                                  |
| **400**         | Bad request — invalid input                                     | Fix the request body or query params and retry                     |
| **401**         | Unauthorized — missing or invalid API key                       | Check `X-API-Key` header                                           |
| **403**         | Forbidden — key valid but not authorized for this resource      | Verify the key is bound to the correct environment                 |
| **404**         | Not found — resource doesn't exist or isn't in your environment | Check the resource ID                                              |
| **409**         | Conflict — e.g. duplicate resource                              | Inspect the error; usually non-retryable                           |
| **422**         | Unprocessable — request shape is valid but values are rejected  | Read the `detail` field                                            |
| **429**         | Rate limited                                                    | Back off and retry — see [Rate limits](/api-reference/rate-limits) |
| **500**         | Internal server error                                           | Retry with exponential backoff; file an issue if persistent        |
| **502/503/504** | Gateway/service issue                                           | Retry with exponential backoff                                     |

## Common error codes

| Code                    | Status | Description                                         |
| ----------------------- | ------ | --------------------------------------------------- |
| `invalid_api_key`       | 401    | The API key is missing, malformed, or deleted       |
| `file_not_found`        | 404    | The file ID doesn't exist in this environment       |
| `prompt_not_found`      | 404    | No prompt with that name has a live version         |
| `file_still_processing` | 409    | File is not yet `ready` — poll `/files/{id}/status` |
| `invalid_file_type`     | 400    | Unsupported file extension                          |
| `file_too_large`        | 413    | File exceeds the upload size limit                  |
| `rate_limit_exceeded`   | 429    | Too many requests — back off                        |

## Retry strategy

For `5xx` responses and `429`, use exponential backoff with jitter:

```python theme={null}
import time
import random

def call_with_retry(fn, max_attempts=5):
    for attempt in range(max_attempts):
        try:
            return fn()
        except TransientError as e:
            if attempt == max_attempts - 1:
                raise
            delay = (2 ** attempt) + random.uniform(0, 1)
            time.sleep(delay)
```

The Python SDK does this automatically for transient errors.

## Reporting issues

If you hit a `5xx` error that doesn't resolve with retry, include the
`request_id` from the error response when you report it. This lets us find
the exact request in our logs.

## Related

<CardGroup cols={2}>
  <Card title="Rate limits" icon="gauge" href="/api-reference/rate-limits">
    Limits and 429 response behavior.
  </Card>

  <Card title="Authentication" icon="key" href="/api-reference/authentication">
    How API keys work.
  </Card>
</CardGroup>
