OpenAPI / AsyncAPI
Drop in an OpenAPI spec and get a native API reference — one real page per operation, in your sidebar and search.
Point Blume at an OpenAPI spec and it generates a native API reference: one real page per operation, grouped by tag in a tab-scoped sidebar, with schema tables, request/response examples, and generated code samples. Because each operation is a genuine Blume page, it gets its own URL, shows up in site search and llms.txt, and gets an Open Graph image — the same as any hand-written doc. The config below points Blume at the public Petstore spec as an example.
openapi: {
enabled: true,
spec: "https://petstore3.swagger.io/api/v3/openapi.json",
}
That mounts the reference at /reference (an overview page) with each operation at /reference/<tag>/<operation>. The spec is either an http(s) URL or a path to a local file in your project. Blume parses it with Scalar’s OpenAPI parser — Swagger 2.0 and OpenAPI 3.0 specs are upgraded to 3.1 automatically.
The reference doesn’t add a header tab on its own. To surface it, point a navigation tab at its route — this also scopes the operations sidebar for the native renderer:
navigation: {
tabs: [{ label: "API", path: "/reference" }],
}
A local spec
A relative path is resolved from your project root and read at build time. Both JSON and YAML work:
openapi: {
enabled: true,
spec: "./openapi.yaml",
}
Route
route controls where the reference mounts — the overview page and the prefix for every operation route (and the route you point a navigation tab at):
openapi: {
enabled: true,
route: "/api", // overview at /api, operations at /api/<tag>/<operation>
spec: "./openapi.yaml",
}
Code samples and schemas
codeSamples picks which languages render per operation (built in: curl, js, python); expandSchemas starts nested schema rows expanded rather than collapsed:
openapi: {
enabled: true,
spec: "./openapi.yaml",
codeSamples: ["curl", "js"],
expandSchemas: true,
}
Multiple specs
Use sources to publish more than one spec. Each source gets its own overview route, operation pages, and header tab. Give each a label (used for the tab and to derive its route), or set an explicit route:
openapi: {
enabled: true,
sources: [
{ label: "Public API", spec: "./public.json" }, // → /reference/public-api
{ label: "Admin API", route: "/admin", spec: "./admin.json" },
],
}
spec is shorthand for a single-entry sources, so you only reach for sources when you have more than one.
Per-source indexing
Generated pages participate in search, llms.txt, and crawler indexing by default. A secondary or overlapping spec can opt out of any surface without hiding its pages or removing it from navigation:
openapi: {
enabled: true,
sources: [
{ label: "Public API", route: "/api", spec: "./public.json" },
{
label: "Platform API",
route: "/platform",
spec: "./platform.json",
includeInSearch: false,
includeInLlms: false,
noindex: true,
},
],
}
includeInSearch: falsekeeps the source’s overview and operations out of site search.includeInLlms: falsekeeps them out of bothllms.txtfiles.noindex: trueadds crawler noindex metadata and removes the pages from the sitemap.
With the Scalar renderer, only noindex applies — a Scalar-rendered reference already sits outside Blume’s search and llms.txt, so the two include* settings have nothing to act on there.
Authorization
Operations that declare security requirements render an Authorization section above their parameters, and the generated code samples send a placeholder credential (Authorization: Bearer YOUR_TOKEN, an API-key header, or a query key — whatever the scheme calls for). There’s nothing to configure: Blume reads security from the spec, so the reference always matches what the API actually enforces.
The OpenAPI semantics carry over as written:
- An operation’s own
securityoverrides the document’s root default;security: []marks it public and renders no Authorization section. - Multiple requirement entries are alternatives — rendered as “or” groups; every scheme inside one entry is required together. The first alternative feeds the code samples.
- An empty
{}entry means auth is optional for that operation, and the section says so. - OAuth2 scopes are listed per scheme; scheme
descriptions fromcomponents.securitySchemesrender inline.
The Scalar renderer
The native renderer is the default. If you’d rather embed Scalar’s self-contained API reference — its own sidebar, search, theme, and “Try it” playground on a single route — set renderer: "scalar":
openapi: {
enabled: true,
renderer: "scalar",
spec: "./openapi.yaml",
theme: "purple", // a Scalar theme name (Scalar renderer only)
}
A Scalar-rendered reference is a self-contained embed on its own route — it doesn’t weave into Blume’s sidebar, search, or llms.txt. Its “Try it” playground calls your target API directly from the browser (Blume doesn’t proxy), so the API must allow cross-origin requests from the docs site (Access-Control-Allow-Origin). theme and the playground apply to the Scalar renderer only.
Passing Scalar options
theme is a shorthand for the one option most people reach for, but Scalar supports many more. A scalar object forwards any Scalar configuration straight to the embedded reference — Blume doesn’t gate the keys, so anything Scalar accepts flows through:
openapi: {
enabled: true,
renderer: "scalar",
spec: "./openapi.yaml",
scalar: {
localization: { locale: "es" }, // translate Scalar's own UI
agent: { disabled: true }, // disable the Scalar Agent
hideTestRequestButton: true,
orderSchemaPropertiesBy: "preserve",
},
}
Blume’s own i18n translates the docs chrome, but Scalar has a separate localization system — set scalar.localization.locale to translate the embedded reference too. Options in the scalar object win over Blume’s derived config, so anything set here (including theme, customCss, or the spec content/url) overrides Blume’s defaults. The same scalar block works on the asyncapi reference.
AsyncAPI
Event-driven APIs use a sibling asyncapi block with the same shape. AsyncAPI is rendered by Scalar (the native renderer is OpenAPI-only for now); only the default route differs (/events):
asyncapi: {
enabled: true,
spec: "./asyncapi.yaml",
}