
# OpenAPI

Sovrium describes its HTTP API as standard **OpenAPI 3.1** documents, generated from the same Zod request/response schemas (`src/domain/models/api/`) that validate live traffic. Because the OpenAPI documents expose the full API shape, they are served **admin-only** at runtime — never to unauthenticated or non-admin callers.

:::callout
**Admin-only by design.** Exposing the API schema to the public would leak the internal surface. Sovrium gates all OpenAPI endpoints behind the `admin` role. When `app.auth` is not configured, the endpoints are not registered at all (every path returns 404).
:::

## What is generated

Two OpenAPI documents plus one interactive explorer, served by a running Sovrium instance.

| Endpoint                     | Returns          | Description                                 |
| ---------------------------- | ---------------- | ------------------------------------------- |
| `GET /api/openapi.json`      | OpenAPI 3.1 JSON | The application API (tables, records, etc.) |
| `GET /api/auth/openapi.json` | OpenAPI 3.1 JSON | The Better Auth API surface                 |
| `GET /api/scalar`            | HTML (Scalar UI) | Unified interactive explorer for both       |

The application document is produced by an internal `getOpenAPIDocument(app)` helper; the auth document is generated by Better Auth's `generateOpenAPISchema()`. The Scalar UI mounts both as switchable sources ("API" and "Auth").

## Access control

All three endpoints share one admin guard.

| Caller                       | `/api/openapi.json` | Reason                                                |
| ---------------------------- | ------------------- | ----------------------------------------------------- |
| Unauthenticated              | `401 UNAUTHORIZED`  | No session (standard HTTP authn semantics)            |
| Authenticated, non-admin     | `404 NOT_FOUND`     | Anti-enumeration: authz denial looks like "not found" |
| Authenticated admin          | `200` + document    | Full access                                           |
| Any caller, `app.auth` unset | `404 NOT_FOUND`     | Routes never registered                               |

The 401/404 envelopes follow the [canonical error contract](/en/docs/api-reference#error-response-contract).

## Fetching the documents

From a running instance, an admin can fetch the raw documents (session cookie or `Authorization: Bearer <token>` required):

```bash
# Application API schema
curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:3000/api/openapi.json

# Better Auth API schema
curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:3000/api/auth/openapi.json
```

Save a document to disk to feed it to external tooling:

```bash
curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:3000/api/openapi.json -o app.openapi.json
```

:::callout
**Served at runtime, fetched by an admin.** The OpenAPI documents are generated and served by the running server at the admin-only routes above. To produce a static file, fetch the route as an admin and redirect to a file (shown above). There is no `sovrium openapi` CLI subcommand. The JSON Schema, by contrast, _does_ have a dedicated command — see [`sovrium schema`](/en/docs/json-schema#generating-the-schema).
:::

## Scalar API explorer

Visit `/api/scalar` in a browser while signed in as an admin to browse, search, and try out every endpoint. The explorer renders both the application and Better Auth documents from a single page.

```
http://localhost:3000/api/scalar
```

It surfaces request/response schemas, status codes, and the canonical error envelope, and lets you issue authenticated requests directly from the page.

## External tool integration

Because the documents are standard OpenAPI 3.1, any compatible tool can consume them once you have fetched the JSON as an admin.

| Tool               | How to use the document                                            |
| ------------------ | ------------------------------------------------------------------ |
| Postman            | Import → File → select `app.openapi.json` to generate a collection |
| Insomnia           | Import / Export → Import Data → From File                          |
| openapi-typescript | Generate typed clients from `app.openapi.json`                     |
| Redoc / Swagger UI | Point the viewer at the fetched JSON file                          |

For client-side TypeScript types of the _config_ (not the API), prefer [`@sovrium/types`](/en/docs/json-schema#typescript-autocompletion-with-sovriumtypes); for API client generation, use the OpenAPI document above.

## How it stays in sync

The application OpenAPI document is derived from the same Zod schemas the routes use for validation, and the auth document is generated by Better Auth at request time. There is no separately maintained spec file to drift — adding or changing an endpoint's request/response schema updates the generated document automatically. See the [API Reference](/en/docs/api-reference) for the human-readable endpoint map.
