Skip to content

Branding

Whitelabel the Docs UI (and related OpenAPI / MCP names) via spec({ meta }) — not mountSpec options.

typescript
export const api = spec({
meta: {
title: 'Acme Catalog API',
version: '1.2.0',
intro: 'Product search and inventory for Acme storefronts.',
website: {url: 'https://acme.example', label: 'acme.example'},
logo: {
light: './brand/logo-light.svg',
dark: './brand/logo-dark.svg',
},
favicon: './brand/favicon.ico',
theme: {
accent: '#0ea5e9',
background: '#0f172a',
surface: '#1e293b',
fontFamily: '"Inter Variable", system-ui, sans-serif',
fontUrls: ['https://fonts.example/inter.css'],
},
navbarLinks: [
{label: 'Dashboard', href: 'https://app.acme.example', external: true},
{label: 'GitHub', href: 'https://github.com/acme/api', external: true},
],
footer: {poweredBy: false},
notice: {
title: 'Sandbox',
message: 'Read-only preview — use a local server for live try-it.',
command: 'npm run dev',
links: [{label: 'Development', href: '/development/'}],
},
sdkInstall: 'npm i @acme/sdk',
authHint: 'Production keys from the developer portal. Header: Authorization: Bearer <key>.',
mcpInstructions: 'Catalog API — search by SKU, check stock. Bearer required for write tools.',
},
routes: {searchProducts, getProductById},
});
FieldEffect
titleBrowser tab, header, OpenAPI title, MCP server name
versionHeader (always), OpenAPI, MCP server version
introHome blurb. Home is omitted unless intro, website, or sdkInstall is set
websiteOutbound link on home
logo.light / logo.darkTop header + home mark (dark falls back to light). Omitted → Callspec hex
faviconDocs tab icon (defaults to logo.light when omitted)
themeCSS variables: accent, background, surface, fontFamily, plus optional fontUrls[]. Prefer accent-only to keep distinct light/dark modes. If you set background / surface, they pin both modes and Callspec derives readable text colors from the surface luminance.
navbarLinksTop header links (label, href, optional external)
footer.poweredByShow “Powered by callspec” (default true when omitted)
noticeOptional plain-text banner above the top header (title?, message, command?, links?) — no custom HTML in message
sdkInstallStatic install command on the home page (copy button)
authHintCopy in the MCP connect panel when bearer tools exist
mcpInstructionsMCP instructions on initializeagents see this, not the docs chrome

Custom HTML, inline CSS, and external override stylesheets are not supported. Use theme colors, logos, links, and notice for whitelabeling.

Per-route labels: route({ meta: { summary, tags, description? } }) — sidebar grouping and route titles.

Field reference: spec § Spec meta.

Paths are relative to the docs URL. With docsPath: '/docs' and logo: { light: './brand/mark.png' }, the browser requests /docs/brand/mark.png.

typescript
router.use('/docs/brand', express.static(path.join(__dirname, 'brand'), {index: false}));
mountSpec(router, api, {docsPath: '/docs'});

Or use absolute CDN URLs and skip static hosting.

Theme CSS variables (--accent, --bg, --surface, --sans, …) are the override surface. Stable classes:

Class / idRole
.top-headerSticky product header (logo, links, search, theme)
.top-nav / .top-nav-linkProduct links from navbarLinks
.cs-ui-noticePlain-text notice from meta.notice (above header)
.sidebarRoute navigation drawer / column
.footer“Powered by callspec” footer
#appApp shell grid