# Errors and versions

> The error envelope and its codes, warnings on partial success, and how the API is versioned.

## The error envelope

Every error has the same shape and an HTTP status that matches its code:

```json
{
  "error": {
    "code": "forbidden",
    "message": "This API token lacks the scope docs:write",
    "hint": "Optional advice on what to do next",
    "details": { "required": ["docs:write"], "granted": ["docs:read"] }
  }
}
```

`message` is written for people and may change. Branch on `code`. `hint` and `details` are
optional.

| Status | Code                | Meaning                                                                                               |
| ------ | ------------------- | ----------------------------------------------------------------------------------------------------- |
| 400    | `invalid_input`     | The input does not match the schema. `details` may list the problems.                                 |
| 401    | `unauthenticated`   | No token, or the token was revoked or has expired.                                                    |
| 403    | `forbidden`         | You lack access to the page, the token lacks a scope, or the operation needs a signed-in session.     |
| 404    | `not_found`         | It does not exist, or you cannot see it.                                                              |
| 404    | `unknown_operation` | No such operation.                                                                                    |
| 409    | `conflict`          | The data changed since you read it (`expectedVersion`), or the change clashes with the current state. |
| 429    | `rate_limited`      | Too many attempts. Wait for the `Retry-After` seconds.                                                |
| 500    | `internal`          | Our fault. Retry later.                                                                               |

## Warnings

Some operations succeed partly. A body edit that matched nothing is skipped while the other edits
apply. The result then lists `warnings`, and the response also carries them in the
`Lydie-Warnings` header as a JSON array.

## Versions

The API is versioned by date. The current version is `2026-11-12`. Pin the version you built
against by sending it with each request:

```http
Lydie-Version: 2026-11-12
```

The [OpenAPI document](https://developers.lydie.co/openapi.json) always describes the current version.
