---
title: "API reference"
description: "Generate routed, versioned API documentation from an OpenAPI specification."
---

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

# API reference

Nimbus generates API references from machine-readable specifications. Each supported format has its own source, configuration, and content loader.

## OpenAPI

Nimbus currently supports OpenAPI 3.x. Nimbus turns a local OpenAPI document into a content collection that powers reference pages, navigation, alternate Markdown versions, search entries, `llms.txt` indexes, and stable links from prose documentation.

The OpenAPI document remains the source of truth. You do not create one MDX file per operation or schema.

### Install with the recipe

Start with an OpenAPI 3.x document stored in your repository. Convert Swagger 2.0 documents to OpenAPI 3.x first. `src/api/openapi.yaml` is the usual location, but Nimbus accepts any project-relative local path or an inline document object. Remote specification URLs are not supported.

Run the API reference recipe from the project root inside your coding agent:

```sh
npx add api-reference
pnpm dlx add api-reference
yarn dlx add api-reference
bunx add api-reference
```

Nimbus passes the recipe directly to detected coding agents. From a regular shell, add `--print` and pass the output to your coding agent. The recipe reviews its plan before changing files.

The recipe tells the agent to inspect your project, ask for the specification path and collection name, and then:

1. Installs the editable API layout and its parser dependencies.
2. Declares the specification in the Nimbus config in `astro.config.ts`.
3. Registers a loader-backed Astro content collection with one line.
4. Adds the HTML catch-all route. The starter's shared Markdown route serves each page's Markdown version.
5. Connects the collection to search, alternate Markdown versions, and `llms.txt` indexes.

### How the pieces fit

| File | Responsibility |
| --- | --- |
| `src/api/openapi.yaml` | The API contract and documentation source. |
| `astro.config.ts` | Declares the specification, versions, routes, and rendering policy in the Nimbus config. |
| `src/content.config.ts` | Registers the generated entries as an Astro content collection. |
| `src/pages/api/[...slug].astro` | Renders API HTML through the user-owned API layout. |
| `src/pages/[...slug]/index.md.ts` | The starter's shared Markdown route. Serves an alternate Markdown version of every API page. |
| `src/components/ui/api-*/` | Owns the reference's appearance and interaction design. |

#### Why the specification is not in `src/content`

`src/content/docs/` contains authored MDX entries. An OpenAPI document is an input to a loader: Nimbus projects it into many operation, schema, tag, and webhook entries in the registered `api` collection.

Keeping the source under `src/api/` makes that distinction visible. The path is only a convention; `src/content/api/openapi.yaml` also works if the configured `spec` points there.

### Configuration generated by the recipe

The recipe declares the specification once, as an `api` entry in the Nimbus config:

```ts title="astro.config.ts"
import { defineConfig } from "astro/config";
import nimbus, {
  defineConfig as defineNimbusConfig,
} from "@cloudflare/nimbus-docs";

const nimbusConfig = defineNimbusConfig({
  site: "https://docs.example.com",
  title: "Acme Docs",
  api: [
{
  collection: "api",
  spec: "./src/api/openapi.yaml",
},
  ],
});

export default defineConfig({
  integrations: [nimbus(nimbusConfig)],
});
```

The collection name is also its URL prefix: `api` mounts the reference at `/api`.

The recipe then registers a loader-backed collection under the same key, preserving existing collections and custom schema fields:

```ts title="src/content.config.ts"
import { defineCollection } from "astro:content";
import {
  apiCollection,
  docsCollection,
  partialsCollection,
} from "@cloudflare/nimbus-docs/content";

export const collections = {
  docs: defineCollection(docsCollection()),
  partials: defineCollection(partialsCollection()),
  api: defineCollection(apiCollection()),
};
```

`apiCollection()` reads the `api` entry whose `collection` matches its key, so the specification is declared only once. The key tells Astro which loader turns that entry into content entries, and lets Nimbus find the collection during configuration and build validation.

To mount several specifications, add one `api` entry and one `apiCollection()` line for each. The build fails if a collection key has no `api` entry, or an `api` entry has no matching `apiCollection()` under its key. The error names both files. `nimbus-docs check` reports the same mismatches without a build.

In `astro dev`, editing a spec file re-indexes its pages. Editing the `api` entries restarts the dev server and re-indexes the reference, without a manual restart.

#### Passing the entry explicitly

`apiCollection()` also accepts the entry directly: `apiCollection({ collection: "api", spec: "./src/api/openapi.yaml" })`. Sites created by earlier versions of the recipe use this form, with the Nimbus config in a separate `nimbus.config.ts` built with `defineConfig` from `@cloudflare/nimbus-docs/config`. They keep building unchanged. Moving the config back into `astro.config.ts` and switching to `apiCollection()` lets `nimbus-docs check` validate the config statically, lets `add adapter-cloudflare` edit it in place, and re-indexes edits to the `api` entries in `astro dev`.

### Coordinates and routes

Nimbus treats identity and routing separately. A **coordinate** identifies an API item in citations, cross-version matching, anchors, and the coordinate manifest. A **route** is the URL of its generated page.

Operations use their OpenAPI `operationId` as the coordinate:

```yaml
paths:
  /v1/events/{event_id}:
get:
  operationId: retrieveEvent
  summary: Retrieve an event
  tags: [Events]
```

This operation's coordinate is `retrieveEvent`. Without a route policy, its first tag and operation ID produce `/api/Events/retrieveEvent`.

The optional `resource-action-v1` policy instead derives routes from HTTP methods and paths:

```ts
api: [
  {
collection: "api",
spec: "./src/api/openapi.yaml",
requireOperationId: true,
routes: {
  convention: "resource-action-v1",
  stripPathPrefixes: ["/v1"],
},
  },
],
```

Here, Nimbus removes `/v1` and publishes the operation at `/api/events/retrieve`; its coordinate remains `retrieveEvent`.

Derivation recognizes `/<resource>` and `/<resource>/{parameter}` after prefix removal. It maps collection `GET`/`POST` to `list`/`create`, and member `GET`/`PUT`/`PATCH`/`DELETE` to `retrieve`/`update`/`update`/`delete`. Tags do not affect policy routes. Other shapes or unsupported method/shape combinations normally fall back to a normalized coordinate with a build warning; the build fails if that coordinate cannot produce a non-empty route.

An explicit operation override, keyed by the exact usable `operationId`, takes precedence and can preserve an existing URL or handle a path that cannot be derived:

```ts
routes: {
  convention: "resource-action-v1",
  operations: {
retrieveEvent: "events/get",
  },
},
```

Without a usable `operationId`, Nimbus derives a fallback coordinate from the method and path. `requireOperationId: true` rejects that fallback, but changing an existing operation ID still changes the coordinate. Webhooks always use their map keys as coordinates and publish below `webhooks/<key>`; configuring an operation override for a webhook fails the build.

Renaming a coordinate requires updating citations and affects cross-version matching. Changing only a route leaves coordinate-based citations intact, but breaks direct links to the previous URL. Nimbus does not create that redirect automatically; add it in Astro or on the deployment platform.

#### Link from prose by coordinate

Use an `api.ref:` destination in Markdown or MDX under `src/content`:

```md
See how to [retrieve an event](api.ref:api:retrieveEvent).
```

Nimbus resolves the citation during the build:

- `api` identifies the API collection.
- `retrieveEvent` identifies the operation independently of its route.
- A citation without a version targets the API family's default version.
- An unknown coordinate in a known collection fails the authored-content build and may suggest a close match.
- An unknown collection is warned and rewritten to `#`; verify collection names against `/nimbus-api/coordinates.json` so dead citations do not ship.

Pin a historical version only when the prose specifically discusses it:

```md
Review the [v1 operation](api.ref:api@v1:retrieveEvent).
```

#### Coordinate shapes

Operations are not the only addressable items. Nimbus assigns coordinates to pages and to details within them:

| API item | Coordinate example |
| --- | --- |
| API root | `api` |
| Tag | `tags.Events` |
| Operation | `retrieveEvent` |
| Request body field | `retrieveEvent.name` |
| Parameter | `retrieveEvent.path.event_id` |
| Response | `retrieveEvent.response.200` |
| Response field in an additional media type | `retrieveEvent.response.200.text-csv.id` |
| Schema | `Event` |
| Schema field | `Event.created_at` |
| Webhook | `delivery.succeeded` |

Use `/nimbus-api/coordinates.json` to inspect the exact coordinates and resolved URLs published by a built site.

### Versioned API references

API versions live inside the `api` entry. This is separate from the top-level `versions` option used for authored prose documentation. An entry accepts either `spec` for one version or `versions` for a family, not both. This example uses the default operation-ID routes; route policies are set independently on each version:

```ts title="astro.config.ts"
api: [
  {
collection: "api",
label: "Acme API",
requireOperationId: true,
versions: [
  {
    version: "v2",
    spec: "./src/api/openapi-v2.yaml",
    default: true,
    status: "ga",
  },
  {
    version: "v1",
    spec: "./src/api/openapi-v1.yaml",
    status: "deprecated",
  },
],
  },
],
```

The version marked `default: true` owns `/api`; other versions mount below their version, such as `/api/v1`. If none is marked, the first version is the default. Nimbus links pages across versions when they share a coordinate. A deprecated version renders its status in the reference UI.

Route policies belong to each version in a version family. This makes URL decisions explicit when two specifications use different base paths or need different overrides.

### Build or request rendering

API HTML is prerendered by default. Request rendering first requires the Cloudflare adapter recipe:

```sh
npx add adapter-cloudflare
pnpm dlx add adapter-cloudflare
yarn dlx add adapter-cloudflare
bunx add adapter-cloudflare
```

With server output configured, this policy renders only the API collection on request:

```ts title="astro.config.ts"
rendering: {
  default: "build",
  collections: {
api: "request",
  },
},
```

The recipe's API catch-all uses Nimbus runtime helpers to resolve either mode. Request rendering changes the canonical HTML pages only. Alternate Markdown versions, coordinate data, search records, sitemaps, and `llms.txt` indexes remain build products, and requests consume prepared content entries rather than parsing the OpenAPI document.

#### Prepared code examples

`apiCollection()` highlights request samples, primary and named request examples, responses, and the examples of additional request body and response media types while it builds the content index. OpenAPI `requestBody.content.*.examples` entries are available as `ApiOperationPage.requestExamples`, preserving each key, summary, description, media type, and inline value. External-only examples are not fetched.

User-owned renderers should render `highlightedHtml` with Astro's `set:html` rather than importing Shiki or Astro's `Code` component into a request-rendered route:

```astro
---
import type { ApiOperationPage } from "@cloudflare/nimbus-docs/api";

interface Props extends Pick<ApiOperationPage, "samples"> {}

const { samples } = Astro.props;

function preparedCode(value: { highlightedHtml?: string }): string {
  if (!value.highlightedHtml) {
throw new Error("Nimbus API code was not prepared during content sync.");
  }
  return value.highlightedHtml;
}
---

{samples.map((sample) => (
  <Fragment set:html={preparedCode(sample)} />
))}
```

Treat a missing prepared value as a stale or incorrectly built API index. Rebuild after changing the specification or API renderer types.

See [Configuration](/configuration#rendering-policy) for the Cloudflare adapter and Wrangler requirements.

### Published outputs

For a collection named `api`, the reference integrates with these routes when their corresponding starter routes are present:

| Route | Purpose |
| --- | --- |
| `/api` | Default-version API overview. |
| `/api/<page-slug>` | Operation, schema, tag, or webhook page. |
| `/api/<page-slug>/index.md` | Clean Markdown version. |
| `/api/llms.txt` | API-only `llms.txt` index. |
| `/llms.txt` and `/llms-full.txt` | Site-wide page index and full Markdown documentation. |
| `/nimbus-api/coordinates.json` | Public coordinate-to-URL manifest. |

The API entries also join the existing Pagefind search, sitemap, and OG-image routes when those features are enabled in the project.

### Cite an API hosted elsewhere

A documentation site can cite a reference published by another Nimbus site without mounting or republishing it:

```ts
apiReferences: [
  {
collection: "api",
manifest: "https://api.example.com/nimbus-api/coordinates.json",
origin: "https://api.example.com",
  },
],
```

`collection` must match the collection key published by the remote manifest. `origin` is the absolute prefix prepended to site-relative manifest paths. Include the deployment base when the remote reference is hosted below one, for example `https://api.example.com/docs`.

The remote collection then uses the same prose syntax: `api.ref:api:retrieveEvent`. Remote references provide citation targets only; they do not add the remote pages to local search or agent outputs.

Nimbus fetches HTTPS manifests during the build. An unavailable or malformed remote manifest produces warnings and its citations resolve to `#`; it does not stop the build. You can instead commit a manifest and use a project-relative path when builds must work offline. An unreadable local manifest, invalid JSON, or invalid top-level shape fails the build; malformed entries inside an otherwise valid manifest are warned and ignored.

### Verify the reference

Run a production build after adding or changing a specification:

```sh
pnpm build
```

Confirm that:

1. The build reports the number of indexed API pages.
2. `/api` and one operation page render.
3. The same operation's `/index.md` route returns Markdown.
4. `/api/llms.txt` lists the reference pages.
5. `/nimbus-api/coordinates.json` contains a known operation ID.
6. A prose `api.ref:` link resolves to the expected route.

For request rendering, test the production Worker locally with Wrangler rather than relying only on Astro's development server.

Source: https://docs.klounge.kr/api-reference/index.mdx
