# API errors and status codes

> What each HTTP status and error code from the Alya Books API means and how to react.

Source: /help/en/api/error-handling

Every API error is a JSON body with the same shape, so one handler covers them all:

```json
{ "code": "E_VALIDATION", "statusCode": 400, "message": "…", "field": "items", "extra": { … } }
```

`code` is the machine-readable reason, `field` points to the offending input when there is one, and `extra` carries details such as PINT AE errors or batch results.

## Status codes

| Status | Code | Meaning | What to do |
|---|---|---|---|
| 400 | `E_VALIDATION` | The payload is invalid or the invoice fails PINT AE | Fix the field named in `field`; read `extra.errors` for business terms |
| 401 | `UNAUTHORIZED` | Missing, malformed, unknown, revoked or expired key | See the 401 article |
| 403 | `FORBIDDEN` | Key lacks the scope, or `X-Organization-Id` is not a managed client | Create a key with the right scopes |
| 404 | `NOT_FOUND` | No such invoice, import, customer or file | Check the id |
| 409 | `CONFLICT` | The action is not allowed in the current state, for example deleting an accepted invoice or reusing a SKU | Change the state first (archive instead of delete) |
| 413 | `PAYLOAD_TOO_LARGE` | Uploaded file over 20 MB | Split or compress |
| 422 | `E_VALIDATION` | A received document failed validation on import | The import is logged; read `extra.validation` |
| 429 | `RATE_LIMITED` | More than 600 requests per minute for this key | Wait for the seconds in `Retry-After` |
| 503 | `SERVICE_UNAVAILABLE` | A PDF of a received invoice's visualisation was requested where no HTML-to-PDF service is configured (invoice, credit note, debit note and proforma PDFs always work) | Request `?format=html` or `xml` |
| 500 | `INTERNAL_SERVER_ERROR` | Unexpected failure | Retry; contact support@alyabooks.ai with `X-Request-Id` |

## Batches

When one invoice in a batch fails, the response takes the status of the first failure (usually 400) and `extra.results` lists every element with `index`, `success` and its own error. Elements with `success: true` were created; retry only the others.

## Good to know

- Every response carries `X-Request-Id`, and error bodies repeat it as `requestId`. The **Recent requests** tab on the API access page shows the same id under each request, with status and timing.
- Webhook deliveries retry after at least 1 min, 5 min, 30 min, 2 h and 12 h (retries are sent by a job that runs every 5 minutes); the deliveries dialog shows attempts and lets you retry by hand.

## Related

- [Why do I get 401 on API calls?](/help/en/api/401-troubleshooting)
- [Required fields when creating invoices through the API](/help/en/api/required-fields)
