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

# The API contract

> Where openapi.json comes from, and how to generate a client from it.

The OpenAPI document is generated, not written. Zod schemas validate every request at runtime. The
same schemas produce `openapi.json`. One edit moves both, so the document cannot drift from the
server.

<Warning>
  Never hand-edit `openapi.json`, and never hand-edit a generated client package. Change the Zod
  schema, then generate again.
</Warning>

## Where to get the document

| Source                                     | Use it for                                           |
| ------------------------------------------ | ---------------------------------------------------- |
| `https://client-api.lala.ist/openapi.json` | The live document of the deployed server.            |
| `https://client-api.lala.ist/docs`         | A browsable Scalar reference, with a request runner. |
| `openapi.json` in the repository root      | The committed copy. CI fails when it is stale.       |
| `docs/api-reference/openapi.json`          | The copy that this documentation site renders.       |

All four hold the same document. The two files in the repository are written by the same command.

## Regenerate after a route change

```bash theme={null}
npm run openapi:emit
```

```bash theme={null}
npm run openapi:check
```

The first command writes both copies. The second command is what CI runs. It fails when a
committed copy differs from the generated one. Run the first command and commit the result.

## Generate a client

Any generator that reads OpenAPI 3.1 produces a typed client from this document. Point the
generator at the live URL, or at a committed copy.

Named response models exist because the generator hoists reused schemas into
`components/schemas`. You get `MeResponse`, `StudentProfile`, `ChatMessage`, and the three SSE
event models as real classes.

## What the document cannot express

Server-Sent Events. OpenAPI describes the `200` response of `POST /api/chat/send` as a string of
content type `text/event-stream`. The event names and their payloads are not in the machine-readable
part of the document.

The payload models are registered as components, so a generated client still gets the classes:

* `ChatChunkEvent`
* `ChatDoneEvent`
* `ChatErrorEvent`

The framing is described in the endpoint description, and on
[Stream a chat answer](/guides/chat-streaming). Write the stream reader by hand. Do not expect a
generator to produce it.

## Versioning

The document reports version `1.0.0`. There is no version prefix in the paths, and there is no
version header. A breaking change to the wire contract will be announced before it ships.
