API Reference Pages

An API reference in Leed is a documentation set whose pages are generated from an OpenAPI spec rather than written. It gets the same navigation, the same URLs, the same theming and the same search as any other set — what differs is where its content comes from, and that nobody edits it by hand.

What an API set is

An API set is a page type whose Type of Page is API Documentation. Everything the rest of this category describes applies to it unchanged: it has exactly one bound left menu, its folder names set its URLs, and links to its pages are page references that survive a move. What a Documentation Set Is is the shared model, and Page Types covers the record itself.

Two things are specific to it:

  • The pages are generated. They are produced from your spec on your machine, reviewed locally, and then uploaded into the CMS.
  • The set is Content Locked, permanently. Editing a generated page in the CMS is refused with API pages are generated from a spec and can’t be edited in the CMS. This is not the Content Locked checkbox you can toggle on any other page type — for an API set it is enforced by the backend regardless of the stored flag, and there is no role that lifts it. The Content Locked toggle on the page type panel shows as on and cannot be turned off.

Versioning by page type

An API set’s path may nest and carry a version — docs/api/3.7.0 — and every page of the set lives under it. A new version is a new set: create a second page type at docs/api/3.8.0, generate into it, and both versions stay live at their own URLs with their own navigation.

Two versions can share a display name, because only the path carries the version. That is why retiring one makes you type the path rather than the name (see Retiring a set).

Building the set: four steps

The flow is four commands, in order, and it is CLI-only. You can create the page type in the CMS — the Create Page Type dialog offers API Documentation — but there is no CMS control that generates or imports pages, so you still need the CLI to fill the set. Creating it from the CLI instead saves a step, because the command registers the new page type locally so the later commands can find its slug.

StepCommandWhat it producesWhat it checks first
1. Create the setleed site create-page-typeA page type in the CMS, registered in your local pageTypeList.jsonThat you are signed in
2. Generateleed site generateLocal preview pages and a menu, plus a manifest recording what was generatedThat the spec is a readable .json, .yaml or .yml, and within the size cap
3. Build and reviewleed site buildA local render of the pages you are about to uploadNothing — this step exists so you look
4. Importleed site importPages in the CMS, the generated menu, and the spec staged for commitThe two guards below
leed site create-page-type --name "Public API" --path docs/api/3.7.0 --type api
leed site generate --openapi ./openapi.yaml --page-type-id <pageTypeId>
leed site build
leed site import --page-type-id <pageTypeId>

create-page-type prints exactly those next three commands with the new id already filled in, so you rarely have to type the id yourself.

flowchart TD
    Spec[OpenAPI spec on disk] --> Create["leed site create-page-type<br/>(page type in the CMS)"]
    Create --> Generate["leed site generate<br/>local preview pages + manifest"]
    Generate --> Build["leed site build<br/>you review the real output"]
    Build --> G1{"Spec unchanged<br/>since generate?"}
    G1 -- No --> R1["Re-run generate, then build"]
    G1 -- Yes --> G2{"A recorded build<br/>newer than the generate?"}
    G2 -- No --> R2["Run leed site build<br/>(--debug builds are not recorded)"]
    G2 -- Yes --> Import["leed site import"]
    Import --> CMS["Pages in the CMS<br/>+ menu + staged spec files"]
    CMS --> Publish["Publish the set"]
    R1 --> Generate
    R2 --> Build

The two guards before import

Import refuses unless both hold, and each says which one failed.

  • The spec must be the one you generated from. Its checksum is recorded at generation time and re-checked at import. If the file moved or changed, you get The OpenAPI spec changed or is missing since you generated. — because the upload is re-derived from the file on disk, and a changed file would upload pages nobody reviewed.
  • A build must have happened since you generated. Otherwise: Build and review the generated set before importing., naming when the last recorded build actually was. This guard is the whole reason the flow is four steps rather than one command.

What import does

Import uploads the pages in batches of at most twenty, and reports every page individually.

OutcomeMeaningSafe to re-run?
ImportedThe page was createdYes — the manifest records it and a re-run skips it
SkippedA page with that id already exists; nothing was overwrittenYes
FailedThat page could not be created; the reason is reported per pageYes — a re-run retries only what is outstanding

It ends on a summary in the form X imported, Y skipped, Z failed (of N), plus whether the generated menu was applied. Import never overwrites. An existing page is skipped, not replaced — which is what makes a partial failure safe to re-run rather than something to clean up first.

On a partial failure the manifest and the local preview files stay in place so the re-run can resume, and the command names the manifest path. On full success it removes the local preview files and the manifest, because the CMS is now authoritative.

Where the spec itself goes

The source spec is uploaded and staged, not committed on its own. It rides along into the site repository with the pages when they publish, so the spec and the pages it produced always land together. Files above 25 MB are refused.

What a reader gets on an endpoint page

An endpoint page renders in two columns. The main column carries the operation itself:

  • Security — the schemes the operation accepts, with their scopes
  • Parameters, grouped by where they go: path, query, header and cookie
  • Request body, with a selector when the operation accepts more than one content type
  • Responses, with a selector for the status code and content type, each showing the schema and an example

The side column carries the code samples for the same operation, as a tab strip.

A generated endpoint page with its sidebar, parameter sections and code sample column

Everything else on the page — breadcrumbs, previous and next, the sidebar, search — is the ordinary documentation reading experience, described at Documentation Reading Experience. An API page has no on-page table of contents; its mini bar shows breadcrumbs instead.

Code sample languages

Samples are generated in four languages — cURL, TypeScript, Python and Go — and rendered through the reserved API Languages tab group, which supplies each tab’s display title and icon.

Two constraints are worth knowing before you touch that group:

  • It is created and repaired for you. Leed creates it if it is missing and fills in any icon that has gone absent. It is also the one tab group hidden from the editor’s tab-group menu, because it is not a general-purpose language group — for a hand-written page, make a group of your own. Tab Groups for Consistent Examples is the page for that.
  • Do not rename or trim it. Its entries are matched to the generated tabs by name. Remove or rename one and that tab still renders — as a bare label with no icon, because the lookup no longer finds it.

The menu is generated with the pages: a folder per resource group and one leaf per endpoint, sorted by name. Each endpoint leaf carries an icon that encodes its HTTP method — that is what renders the method badge in the sidebar, and it is also how a reader’s AI client reads the method back out of your navigation.

The Documentation tree for an API set, with method-badged endpoint leaves

The rest of the menu behaves exactly as it does for a written set, including the folder-name-to-URL rule — see Folders Set Your URLs before you reorganize one.

Retiring a set

Settings → Page Types is the only entry point, deliberately: this destroys a whole set rather than acting on one page, so it lives with the set’s settings and nowhere else.

ArtifactRemoved?Recoverable?
Every page in the setYesNo
The committed OpenAPI spec filesYesNo
The set’s navigation menuYesNo
The set’s live URLsThey stop resolving at the next deploymentOnly by rebuilding the set
The delete-API-set confirmation dialog with the typed-confirmation field

Where the command detail lives

This page owns the product model. Every flag on every command in the flow, with its defaults and its failure messages, is at OpenAPI Commands, and the workflow written from the CLI’s side — including what to do when a guard refuses — is at Importing an OpenAPI Spec. None of it works until the CLI is installed and signed in: Installing the Leed CLI.

Once the set is live, your readers’ AI clients can query it directly, method and all — Docs MCP Tool Reference covers the tools that read an API set.

ESC