---
title: "Add an OpenAPI reference"
description: "Generate reference pages from an OpenAPI 3.x document in your repository, with one recipe."
---

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

# Add an OpenAPI reference

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.

To see a finished reference, open the [weather demo](https://demo.nimbus-docs.com/api/): a Nimbus site with a 105-endpoint API in three versions, rendered on request on Cloudflare Workers.

## Start a new site with it

The scaffolder can set the reference up for you: `--api` adds it beside the docs, at `/api`, and `--template api` makes it the whole site, at `/`. Pass your spec with `--api ./openapi.yaml`, or leave it out for a sample. See [Scaffolder options](/reference/scaffolder-options/).

```sh
npm create @cloudflare/nimbus-docs@latest -- my-docs --api ./openapi.yaml
npm create @cloudflare/nimbus-docs@latest -- my-docs --template api
```

## Install with the recipe

Start with an OpenAPI 3.x document stored in your repository. If you have a Swagger 2.0 document, [convert it first](#convert-a-swagger-20-document). `src/api/openapi.yaml` is the usual location, but Nimbus accepts any project-relative local path, a file in another git repository declared as a [content source](/content-sources/git#api-specs-from-a-source) (`spec: { source: "sdk", path: "openapi.json" }`), 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 @cloudflare/nimbus-docs add api-reference
yarn nimbus-docs add api-reference
pnpm nimbus-docs add api-reference
bunx @cloudflare/nimbus-docs add api-reference
```

Inside a coding agent, Nimbus hands the recipe straight to it. From a regular shell or a script, add `--print` and pass the output to your agent. Without `--print`, a shell gets only instructions for piping it, on standard error, and no files change.

The recipe reviews its plan with you 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.

## Convert a Swagger 2.0 document

Nimbus reads OpenAPI 3.x only. A Swagger 2.0 document fails the build with `Swagger 2.0 isn't supported. Convert it to OpenAPI 3.x first.`, followed by the document's path.

Keep the Swagger document as your source, and generate a separate OpenAPI 3.x document from it with [swagger2openapi](https://github.com/Mermade/oas-kit/tree/main/packages/swagger2openapi):

```sh
npm i -D swagger2openapi@7.0.8
yarn add -D swagger2openapi@7.0.8
pnpm add -D swagger2openapi@7.0.8
bun add -d swagger2openapi@7.0.8
```

Run the conversion before Astro in your `dev` and `build` scripts, so the generated document always matches its source:

```json title="package.json"
{
  "scripts": {
    "dev": "swagger2openapi src/api/swagger.yaml --yaml --outfile src/api/openapi.yaml && astro dev",
    "build": "swagger2openapi src/api/swagger.yaml --yaml --outfile src/api/openapi.yaml && astro build"
  }
}
```

Point the `api` entry's `spec` at the generated document, `./src/api/openapi.yaml`. The converter turns `host`, `basePath`, and `schemes` into `servers`, moves body and form parameters into request bodies, and converts security definitions. The development server watches the generated document, not the Swagger source, so restart `dev` after editing the source.

## 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, including the [API home](/api-reference/large-apis#the-api-home)'s later parts. |
| `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, tag, and webhook entries in the registered `api` collection, plus schema entries when [schema pages](/api-reference/openapi/routes#schema-pages) are on.

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 reference is served where its route file is: `src/pages/api/[...slug].astro` serves `api` at `/api`, and `src/pages/reference/api/[...slug].astro` at `/reference/api`, with versions, `openapi.json` and the API catalog under it. See [Collection URLs](/writing/collections#collection-urls).

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.

## 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. The reference's home and one operation page render: `/api`, or `/` in a site that is only the reference.
3. The same operation's `/index.md` route returns Markdown.
4. The reference's `llms.txt` lists its pages: `/api/llms.txt`, or `/llms.txt` at the root.
5. `/nimbus-api/coordinates.json` contains a known operation ID.
6. In a site with docs, 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.

## Next steps

- [Routes and coordinates](/api-reference/openapi/routes): choose the URLs your pages get.
- [Cite API pages](/api-reference/citations): link to operations from your guides.
- [Code samples](/api-reference/openapi/code-samples): control the samples on each operation.

Source: https://nimbus-docs.com/api-reference/openapi/setup/index.mdx
