Endpoints
Everything the portal knows is available as data. These endpoints are public, need no key, and allow cross-origin requests, so a deck builder, a Figma plugin or product code can read them directly.
Every token, flat and resolved for both themes.
Keyed by dotted path. Colors and shadows carry light and dark; everything else carries a single value. No Figma aliases left to resolve.
The same tokens as CSS custom properties.
A :root block and a .dark block. Byte-for-byte the declarations the portal itself ships, so anything consuming this renders identically.
An index of sections, pages and downloadable assets.
Each asset lists every format it can be served in, with direct CDN URLs. This is the entry point for finding a resource programmatically.
The raw DTCG source files.
primitive.light, primitive.dark and semantic, exactly as exported from Figma. Use these if you want to do your own resolution; use the endpoints above if you want the answers.
Reading a token
Tokens are a flat map, so a lookup is one key access. Prefer semantic tokens (color.text.title) over primitives (primitive.color.neutral.12), because semantics carry the intent and stay correct if the palette shifts.
const { tokens } = await fetch('/api/v1/tokens.json').then((r) => r.json());
tokens['color.background.primary'];
// {
// type: 'color',
// layer: 'semantic',
// cssVar: '--color-background-primary',
// light: '#F9F9FB',
// dark: '#1B1B1F',
// primitive: 'color/neutral/2'
// }Getting an asset in the format you need
Assets are stored once as SVG. Sanity's image pipeline rasterises on request, so any format is a URL parameter, and nothing is pre-generated. The manifest lists these URLs for you, but they are predictable.
<asset-url>.svg → the vector <asset-url>.svg?fm=png&w=1024 → PNG, 1024px wide <asset-url>.svg?fm=webp&w=480 → WebP thumbnail <asset-url>.svg?dl=lean-logo.svg → download with a filename
Versioning and caching
Both token endpoints return an X-Tokens-Version header and a version field. It is a content hash of the emitted values, so it changes when a token changes and not when the site redeploys, which makes it safe to key a cache on. Paths are stable; a breaking change to the payload shape would ship under /api/v2/.