Add one authored API reference to the project created in the quickstart. You will register an operation, write its introduction, add it to navigation, review the imported content, and verify its published files.
Run commands from your documentation project directory. SHOALRUN_CLI is the absolute path to framework/dist/cli.js set in the quickstart. Check OpenAPI support and limits before importing a larger specification.
Put the spec in your project
Create apis/notes/openapi.yaml with this complete fictional API. It documents a response without calling a live service:
openapi: 3.1.0
info: { title: Example Notes API, version: 1.0.0 }
paths:
/notes:
post:
operationId: createNote
summary: Create a note
responses:
'201':
description: The note was created.
content:
application/json:
schema:
type: object
required: [id]
properties:
id: { type: string, description: The new note identifier. }
examples:
created:
summary: A created note
value: { id: note_123 }
OpenAPI 3.0 or 3.1 YAML and JSON files are accepted. There is no required directory name; a spec can also reference other local files.
Register the operation
Add this top-level entry to your existing docs.config.yaml:
apis: { $include: ./config/api.yaml }
Create the config directory if needed and add config/api.yaml:
notes:
source:
kind: file
path: ../apis/notes/openapi.yaml
focused: true
operations:
- id: notes.create
sourceOperationId: createNote
reference: reference.create-note
source.path is relative to the config fragment that declares it. notes names this API, and sourceOperationId selects the spec's operationId. The stable operation ID notes.create connects the operation to authored pages; reference names the page that will present it. focused: true publishes a one-operation contract.
If the source lives at a public HTTPS URL, import it into a local snapshot first:
node "$SHOALRUN_CLI" api import https://api.example.com/openapi.yaml --output apis/remote
Point source.path at ../apis/remote/openapi.yaml from config/api.yaml. Commit the snapshot and its source-lock.json. Normal builds use those local files and make no network request. To check for upstream changes, run api refresh apis/remote --output apis/remote-next. If the source changed, the command reports the changed hashes and writes a complete new snapshot while keeping apis/remote intact. Point source.path to ../apis/remote-next/openapi.yaml, inspect a new api review candidate, and pin its digest before building. The CLI reference lists import limits.
Author the reference page
Create content/create-note.mdx:
---
id: reference.create-note
title: Create a note
summary: Create a note in the fictional Notes API.
type: api-reference
slug: /example-api/create-note
channel: production
version: current
language: en
operations: [notes.create]
access: { policy: public }
---
This fictional operation returns the identifier of a new note. Its response
schema and named example are generated from the local OpenAPI file.
The page ID must match the registry's reference value. An api-reference page lists exactly one operation. The compiler appends the method, path, parameters, authentication, schemas, and examples to your authored introduction.
Append this entry to the existing navigation array in docs.config.yaml:
- id: notes-create
doc: reference.create-note
If your project includes navigation from another file, add the entry there. Save the page and navigation before the review so the candidate contains the page you intend to publish.
Review imported content before publishing
Shoalrun requires publicReview.digest for every API whose content appears in a public page, embed, or focused contract. A missing or stale digest stops a normal build. Generate a local candidate in a fresh temporary directory:
API_REVIEW_DIR="$(mktemp -d /tmp/shoalrun-api-review.XXXXXX)"
node "$SHOALRUN_CLI" api review docs.config.yaml --output "$API_REVIEW_DIR"
The command builds the candidate and reports each API's digest, page URLs, focused contracts, full-source downloads, and input hashes. Inspect the candidate files for private operations, fields, descriptions, examples, and credentials. For this example, check the Create a note HTML and Markdown page and its linked focused contract.
Copy the reported digest for notes into config/api.yaml alongside source and operations:
notes:
publicReview:
digest: <paste-the-reported-notes-digest>
# Keep source and operations here.
Replace the angle-bracket placeholder with the actual digest. Keep the candidate local and remove it after review. The digest records what you reviewed; it does not determine whether content is safe. Changing source bytes, selected operations or embeds, focused contracts, or full-source publication requires another review. Changing only authored page copy does not.
Build and verify the output
node "$SHOALRUN_CLI" build docs.config.yaml site-dist
node "$SHOALRUN_CLI" api focused-audit site-dist
node "$SHOALRUN_CLI" serve site-dist
Open http://127.0.0.1:8765/example-api/create-note/ and choose Create a note in the sidebar. Confirm the introduction, POST /notes, the 201 response with its required id field, and the named example. Open http://127.0.0.1:8765/example-api/create-note.md to check the same details as Markdown. Follow the focused contract link and check that it contains only this operation and its required contract data.
The HTML uses a reference column and an API data panel at wide widths; on narrow screens the panel follows the article. The Markdown twin contains every property, variant, enum choice, and named example in reading order. JSON shapes use type placeholders; they are not runnable payloads. Generated request commands have not been executed.
For a larger live example of the documentation layout, see the fictional Create a note reference. Its archivedAt response field is both always present and nullable: presence and nullability describe different things. A field marked may be absent can be omitted entirely.
Next, generate and select more API pages.
What readers get
An authored reference adds editorial context to the operation contract. A generated reference includes the same contract details without an MDX introduction. For tasks spanning several operations, write a linked guide such as Write a note. These fictional examples do not imply a live API or tested requests.
Response status and media type share a heading row. Descriptions remain visible above property disclosures; enum choices appear below field descriptions. Markdown includes all of this without interactive controls. OpenAPI deprecated: true sets the page's status to deprecated; conflicting authored status values fail the build.
Publish several versions
Put multiple versions on one site explains sources for each publication and stable operation bindings across versions.
Map extension values to Shoalrun status
Use the extension mappings reference to map vendor x-* values to status badges.
Describe filters that do not use their OpenAPI parameter name
The query syntax example configures direct query expressions and generated cURL.
Generate many pages selectively
Generate and select API pages covers include/exclude lists, stable generated IDs, webhooks, interactive selection, and tag navigation.
Use a template for editorial context
API reference templates add editorial prompts without duplicating contract fields.
Add useful examples
Named examples and generated commands explains example selection, JSON shapes, and cURL behavior.
Link guides to API references
Related API references connects guides and references in both directions using stable page IDs.
Inspect the machine-readable contract
Focused contracts retain transitive schemas, examples, and security schemes for one operation. To publish the full source instead, set source.publish: true. That also enables focused contracts. A discovery endpoint must use HTTPS and needs site.origin; see configuration.
Preview a small API reference
Compare the authored Create a note and generated Get a note with their fictional source, Markdown twins, and focused contracts.
For a multi-file example with authentication, run npm run demo from the checkout's framework/ directory and inspect example/dist/v1/reference/create-payment/. The Cedar Parcel styling lab exercises direct query filters, conditional bodies, JSON and file responses, server and authentication overrides, extension mappings, and a webhook. Its standalone project is framework/example-configs/reference-stress/.