# API reference

> For the complete documentation index, see [llms.txt](https://docs.writedocs.io/llms.txt).

Turn an OpenAPI spec into an API reference - a page per endpoint, with parameters, responses, examples and a Try it playground, or Scalar's API reference on one page.

Point a navigation group at an OpenAPI spec, and Writedocs writes the API reference: a page for every endpoint, grouped by tag, with its parameters, request body, responses, code examples and a **Try it** playground. There are no page files to write or keep up to date - change the spec, and the pages follow.

## Set it up

Put the spec in your project, and give a group `openapi` in place of `pages`:

```json
{
  "navigation": [
    "index",
    {
      "group": "API reference",
      "openapi": {
        "src": "openapi.yaml",
        "path": "/api"
      }
    }
  ]
}
```

**`src`** `string` required

The spec's path from the project folder: an OpenAPI 3.0 or 3.1 file, in YAML or JSON.

**`path`** `string` required

The address the pages go under - see [Page addresses](#page-addresses). Each OpenAPI group needs its own.

**`renderer`** `"writedocs" | "scalar"` default: `writedocs`

How readers see the group: `"writedocs"`, a page per endpoint as described on this page, or `"scalar"`, the whole API on one page with Scalar's API reference - see [Scalar's API reference](#scalars-api-reference).

This site's **Example API** group, in this tab's sidebar, is set up exactly like this - its pages are generated from a sample spec.

The spec must be a file in the project - a URL isn't fetched. `writedocs validate` checks every spec in the navigation: a spec that's missing or doesn't parse is an error, and one that parses but isn't valid OpenAPI is a warning.

## Previewing your changes

With [`writedocs dev`](https://docs.writedocs.io/docs/cli/#writedocs-dev) running, save the spec and the open tab reloads with the change, usually within a few seconds - no restart needed:

- A changed `summary`, `description`, parameter, schema or example shows on the endpoint's page; a changed `summary` also renames it in the sidebar.
- An endpoint you add appears in the sidebar, under its tag, and its page is ready. One you remove or rename leaves the sidebar, and its old address shows "Page not found".
- An edit to a file the spec points to with `$ref` - a shared schema in its own file, say - counts as an edit to the spec.
- Pointing a group's `openapi` at another spec, or giving it another `path`, in `writedocs.json` regenerates the pages the same way.

While you're typing, the spec may not parse for a moment. The terminal says where, and every page of the preview shows the same error until the spec parses again; the preview keeps running, and the pages come back on their own once it's fixed:

```text
✗ openapi.yaml:12:5  bad indentation of a mapping entry
```

A [page of your own for an endpoint](https://docs.writedocs.io/docs/openapi/multi-spec-and-overrides/#your-own-page-for-an-endpoint), added while the preview runs, takes the endpoint's place at the next edit to the spec, or when you restart `writedocs dev`.

## What each page shows

- **The endpoint** - its method and path, title (the operation's `summary`) and description. Descriptions are Markdown, as OpenAPI specifies.
- **Authorization** - the security schemes the endpoint accepts.
- **Parameters** - path, query and header parameters, with their type, whether they're required, their default and description.
- **Request body** - every field, with nested objects that open and close.
- **Responses** - each status code, with its fields and an example.
- **Code examples** - the request in several languages, ready to copy, beside the page.
- **Try it** - a playground that sends a real request to your API - see [Try it playground](https://docs.writedocs.io/docs/configuration/api-settings/).

The page also has the **Copy page** menu, and its Markdown copy, `llms-full.txt` and the MCP server include the endpoint written out in full.

## Page addresses

An endpoint's page is served at the group's `path`, then the endpoint's first tag, then its method and path:

| Endpoint | Tags | Address, with `path: "/api"` |
| --- | --- | --- |
| `POST /customers` | `Customers` | `/api/customers/post-customers/` |
| `GET /customers/{id}` | `Customers`, `Admin` | `/api/customers/get-customers-id/` |
| `GET /health` | none | `/api/get-health/` |

To choose an endpoint's address yourself, give it [a page of its own](https://docs.writedocs.io/docs/openapi/multi-spec-and-overrides/#your-own-page-for-an-endpoint) with a [`slug`](https://docs.writedocs.io/docs/content/frontmatter/#slug).

In search results and link previews, the page's description is the endpoint's `description` as plain text, cut to about 160 characters - or, when it has none, its summary and request: `List all customers - GET /customers`.

## Limits

- `allOf` schemas are merged into one. For `oneOf` and `anyOf`, the page shows the first option only - describe the others in its `description`.

## The sidebar

The group lists the endpoints under one group per tag, in the order the tags first appear in the spec. An endpoint takes its first tag; endpoints with no tag go in a group called **Other**. Each endpoint shows its method next to its name.

## Writing a good spec

The pages are only as good as the spec. What helps most:

- A `summary` for every operation - it's the page's title and its name in the sidebar.
- A `description` for operations, parameters and fields.
- `example` or `examples` values, for the response examples and the playground's starting values.
- `tags`, to group the endpoints.
- `servers`, for the address the playground sends requests to.

## Scalar's API reference

With `"renderer": "scalar"`, the group is one page instead of a page per endpoint: [Scalar](https://github.com/scalar/scalar)'s API reference, at the group's `path`, inside your site - the top bar, tabs, footer, colors, font and light/dark theme are your site's. The reference takes your site's look too: its list of endpoints looks like your sidebar, and its titles, text and spacing like your other pages.

```json
{
  "group": "API reference",
  "openapi": {
    "src": "openapi.yaml",
    "path": "/api",
    "renderer": "scalar"
  }
}
```

Each group chooses for itself: one API can use Scalar's reference and another the page-per-endpoint reference, in the same site.

### What the reader sees

- **One page with every endpoint**, grouped by tag, with Scalar's own list of endpoints at its side. Each endpoint has its own address on that page, like `/api/#tag/customers/POST/customers`, made from its first tag, method and path - it stays the same from one build to the next while those don't change.
- **The sidebar.** When the group is all there is in its part of the navigation - an API tab, say - Scalar's list of endpoints takes the place of your sidebar. When the sidebar has other pages, the two stand side by side. On phones, your sidebar is in the site's menu, as on every page, and Scalar's list in a menu of its own at the top of the reference.
- **Scalar's Try it.** Every endpoint has a **Test Request** button that opens Scalar's API client on it. Requests follow [`api.proxy`](https://docs.writedocs.io/docs/configuration/api-settings/#apiproxy): straight to your API, then through Writedocs' proxy if the browser blocks them - never Scalar's hosted proxy. What a reader types as credentials stays in that browser tab, and is forgotten when the tab closes.
- **A spec download** button, except in a [protected section](https://docs.writedocs.io/docs/configuration/protected-sections/).
- **Search is the site's.** Searching for an endpoint finds it, and the result opens it on the reference page. Scalar's own search box, its AI assistant, its developer tools and its theme switch are turned off.
- **While it loads**, the page shows the reference's outline in your site's colors: the list of endpoints, your API's title and description as gray bars, and the Server, Authentication and Client Libraries boxes, with a soft shine passing over them (still, for readers whose system asks for less motion). The reference then takes its place, without the page moving. Screen readers hear that the reference is loading.
- **If the reference can't load** - the reader's connection dropped, say - the page lists the endpoints instead, each linking to its page, with a **Try again** button.

### What stays the same

Writedocs still builds the page of each endpoint described above, at its usual [address](#page-addresses), and everything that reads those pages works as for any OpenAPI group:

- **Search** finds each endpoint by its title and description, and opens it on the reference page.
- **`llms.txt`, `llms-full.txt`, the MCP server and the Markdown copies** have every endpoint, written out in full. The reference page's own Markdown copy lists the endpoints, each linking to its page.
- **Links to an endpoint's address** - from your own pages, or from other sites - open the endpoint on the reference page.

Those pages aren't listed in the sidebar or in Previous/Next links, and they tell search engines not to index them: the reference page is the one indexed, and the one in `sitemap.xml`. A reader whose browser has JavaScript turned off stays on the endpoint's page, which shows everything.

### Weight

The reference is drawn in the reader's browser. Opening it downloads about 1.2 MB of compressed code the first time - the browser keeps it for later visits - and the page carries your spec. Measured on a laptop with an empty cache: with 7 endpoints, the endpoints show in about 0.4 seconds, and in about 8 seconds on a slow mobile connection; with 800 endpoints, in about 0.8 and 10 seconds - meanwhile the page shows the reference's outline (above). A page-per-endpoint reference shows its endpoint in well under half a second either way. Choose Scalar's reference knowing your readers' connections.

### With `api.playground`

[`api.playground`](https://docs.writedocs.io/docs/configuration/api-settings/#apiplayground) picks the Try it of the page-per-endpoint references. A group with `"renderer": "scalar"` always uses Scalar's client, built into its reference, whatever `api.playground` says; your other OpenAPI groups follow `api.playground`.

### Limits

- **`path` can't be `/`**, and no page of your own can be at it - the reference is a page at that address. `writedocs validate` reports both, with the line in `writedocs.json`:

  ```text
  ✗ 1 error in writedocs.json

    writedocs.json:7  (navigation.tabs.1.pages.0.openapi.path)
      writedocs.json's "Orbit API" group has openapi.renderer "scalar" and openapi.path "/" - the reference is a page at that path, so give it one of its own, like "/api".
  ```
- **A [page of your own for an endpoint](https://docs.writedocs.io/docs/openapi/multi-spec-and-overrides/#your-own-page-for-an-endpoint)** in this group isn't shown: links to it open the endpoint on the reference page, and its text is still found by search and included in `llms-full.txt`.
- **No JavaScript, no reference.** The reference page then lists the endpoints, each linking to its page.
- **In a protected section**, the reference page - with your spec in it - is protected like the section's other pages.

## More

- [More specs, and your own pages](https://docs.writedocs.io/docs/openapi/multi-spec-and-overrides/) - several specs in one site, and replacing a generated page with one you write.
- [Try it playground](https://docs.writedocs.io/docs/configuration/api-settings/) - how requests are sent, and the CORS proxy.
- [Parameter](https://docs.writedocs.io/docs/content/components/parameter/) and [RequestExample](https://docs.writedocs.io/docs/content/components/request-response-example/) - to document an API by hand.