# HTTP API

<!-- Generated by scripts/docs/generate.ts. Do not edit by hand. -->

All browser routes live under `/api/v1` unless noted. Health and auth routes are
public; the rest require a session cookie or a bearer token. Cookie mutations
also require the `x-csrf-token` header.

| Method   | Path                                  | Auth                       |
| -------- | ------------------------------------- | -------------------------- |
| `POST`   | `/api/v1/ai/evaluations`              | Session or bearer          |
| `GET`    | `/api/v1/api-keys`                    | Session or bearer          |
| `POST`   | `/api/v1/api-keys`                    | Session or bearer          |
| `DELETE` | `/api/v1/api-keys/:id`                | Session or bearer          |
| `POST`   | `/api/v1/auth/logout`                 | Public                     |
| `POST`   | `/api/v1/auth/magic-link`             | Public                     |
| `POST`   | `/api/v1/auth/setup`                  | Public                     |
| `GET`    | `/api/v1/auth/status`                 | Public                     |
| `POST`   | `/api/v1/auth/verify`                 | Public                     |
| `DELETE` | `/api/v1/cards/:id`                   | Session or bearer          |
| `GET`    | `/api/v1/cards/:id`                   | Session or bearer          |
| `PATCH`  | `/api/v1/cards/:id`                   | Session or bearer          |
| `POST`   | `/api/v1/cards/:id/restore`           | Session or bearer          |
| `POST`   | `/api/v1/cards/:id/resume`            | Session or bearer          |
| `POST`   | `/api/v1/cards/:id/suspend`           | Session or bearer          |
| `GET`    | `/api/v1/collections`                 | Session or bearer          |
| `POST`   | `/api/v1/collections`                 | Session or bearer          |
| `DELETE` | `/api/v1/collections/:id`             | Session or bearer          |
| `PATCH`  | `/api/v1/collections/:id`             | Session or bearer          |
| `GET`    | `/api/v1/decks`                       | Session or bearer          |
| `POST`   | `/api/v1/decks`                       | Session or bearer          |
| `DELETE` | `/api/v1/decks/:id`                   | Session or bearer          |
| `GET`    | `/api/v1/decks/:id`                   | Session or bearer          |
| `PATCH`  | `/api/v1/decks/:id`                   | Session or bearer          |
| `GET`    | `/api/v1/decks/:id/cards`             | Session or bearer          |
| `POST`   | `/api/v1/decks/:id/cards`             | Session or bearer          |
| `GET`    | `/api/v1/decks/:id/export`            | Session or bearer          |
| `POST`   | `/api/v1/decks/:id/import`            | Session or bearer          |
| `GET`    | `/api/v1/decks/:id/study-options`     | Session or bearer          |
| `GET`    | `/api/v1/health`                      | Public                     |
| `GET`    | `/api/v1/me`                          | Session or bearer          |
| `PATCH`  | `/api/v1/me`                          | Session or bearer          |
| `GET`    | `/api/v1/media/:id`                   | Session or bearer          |
| `POST`   | `/api/v1/media/:id/complete`          | Session or bearer          |
| `GET`    | `/api/v1/media/:id/content`           | Session or bearer          |
| `PUT`    | `/api/v1/media/:id/content`           | Session or bearer          |
| `POST`   | `/api/v1/media/intent`                | Session or bearer          |
| `DELETE` | `/api/v1/sessions`                    | Session or bearer          |
| `GET`    | `/api/v1/sessions`                    | Session or bearer          |
| `DELETE` | `/api/v1/sessions/:id`                | Session or bearer          |
| `GET`    | `/api/v1/stats/decks/:id`             | Session or bearer          |
| `POST`   | `/api/v1/study/preview`               | Session or bearer          |
| `GET`    | `/api/v1/study/recommendation`        | Session or bearer          |
| `GET`    | `/api/v1/study/sessions`              | Session or bearer          |
| `POST`   | `/api/v1/study/sessions`              | Session or bearer          |
| `GET`    | `/api/v1/study/sessions/:id`          | Session or bearer          |
| `POST`   | `/api/v1/study/sessions/:id/abandon`  | Session or bearer          |
| `POST`   | `/api/v1/study/sessions/:id/complete` | Session or bearer          |
| `POST`   | `/api/v1/study/sessions/:id/reviews`  | Session or bearer          |
| `GET`    | `/api/v1/tags`                        | Session or bearer          |
| `POST`   | `/mcp`                                | API key, session, or OAuth |
| `GET`    | `/media/:id`                          | Session or bearer          |
| `GET`    | `/oauth/authorize`                    | Public                     |
| `POST`   | `/oauth/authorize`                    | Public                     |

## Envelopes

Success:

```json
{ "data": {}, "meta": {} }
```

Paginated lists use `{ "data": [], "meta": { "nextCursor": "…", "hasMore": true } }`.

Failure:

```json
{ "error": { "code": "FORBIDDEN", "message": "…", "details": null } }
```

## Notes

- `POST /api/v1/auth/magic-link` returns the raw token only when
  `ENVIRONMENT=development`.
- `/mcp` is a Streamable HTTP endpoint, not a JSON REST route. It accepts API
  keys, session cookies, and OAuth bearers.
- `/media/:id` is the authenticated R2 read proxy.
- This table is generated from the route modules; it lists the mounted paths,
  not every middleware branch.
