Skip to content

Public API ​

Hypervalent Studio is a headless CMS: everything you model and publish in Studio is served by a REST API at https://api.hypervalent.io/v1, authenticated with an organization API token. Site builds read it; agents and integrations can also write through it.

Base URLhttps://api.hypervalent.io/v1
AuthenticationAuthorization: Bearer atk_… or X-API-Key: atk_… — see Authentication
FormatJSON in and out, camelCase keys; Content-Type: application/json on writes
ReferenceEndpoint reference · OpenAPI document
Errors{ status, code, message } — see Errors

New here? Follow the quickstart — it goes from a token to rendered content in five requests.

How the API is organized ​

Every URL names the organization and, for content, the project:

/orgs/{org_id}/token                                   who am I
/orgs/{org_id}/projects                                the projects this token can reach
/orgs/{org_id}/projects/{projectSlug}/doctypes         the content model
/orgs/{org_id}/projects/{projectSlug}/doctypes/{doctypeSlug}/documents
/orgs/{org_id}/projects/{projectSlug}/taxonomies
/orgs/{org_id}/projects/{projectSlug}/settings
/orgs/{org_id}/projects/{projectSlug}/design-tokens
/orgs/{org_id}/projects/{projectSlug}/media            upload
  • org_id is the organization's public id, shown in Studio → Settings → API tokens. It is not the organization's uuid.
  • projectSlug is a required path segment — every content table is project-scoped, so there is no cross-project read and no "default project". Discover slugs with GET /orgs/{org_id}/projects.
  • Document and term reads nest under their document type or taxonomy (/doctypes/{doctypeSlug}/documents/{slug}), because slugs are unique per type, not per project.

What a token can see ​

A token is an organization credential, optionally narrowed to one project. The URL is checked against it on every request, in this order: credential first, then organization, then project.

TokenMay readNaming another project
Organization-wideEvery live project in the organization—
Project-narrowedExactly its project403 TOKEN_PROJECT_MISMATCH

A read token sees published content only. A read of a draft, or of anything that does not exist, is the same plain 404 NOT_FOUND — the API never confirms that draft work exists to a read token. A read_write token on a plan with API writes can add ?status=draft to document, taxonomy and term reads to get the working view: every non-trashed row, draft or published, with its latest working version. See Authentication for scopes.

The content model in one paragraph ​

A document type (/doctypes) defines a kind of document: its root atoms — the top-level fields, each an atom (/atoms) binding with a default, required and locked flags — the taxonomies it offers, and the molecules (/molecules, reusable blocks) its body may nest. A document carries a version: rootAtoms (values keyed by atom uuid) and content (the body, a tree of nodes). Taxonomies hold hierarchical terms, which have versions of their own. Settings are admin-defined config values; design tokens are the project's design system. Reads resolve everything by uuid: a root-atom value's uuid is an atom, an image field holds image uuids you look up in the response's referencedImages, and a file field holds file uuids you look up in referencedFiles (url, filename, mime, size). A file field value written before file fields picked from the media library is a plain URL string instead. A video field holds video uuids — also in referencedFiles — and/or plain URL strings for videos hosted elsewhere (YouTube, Vimeo).

A link field holds a string (an array of strings when the field is multiple): an http(s) URL, a protocol-relative URL (//cdn.example.com/a), a path (/about, docs/intro), a query string (?ref=x), a fragment (#team), or a mailto: / tel: link. When a document or term version is saved, a link value with any other scheme (javascript:, data:) or a control character is refused: a single link is saved as "" and a refused entry of a multiple link is removed. There is no url field type any more: it was merged into link, so an atom's or a setting's fieldType that used to read url now reads link. Stored values were not rewritten by the merge (a value saved before it is checked the next time its document or term is saved), so escape link values like any other text when you render them.

Pagination ​

Two list shapes exist, and the reference names which one each route answers with:

  • Paged lists — documents of a type, a taxonomy's terms, projects — take ?limit= (max 50, default 10) and ?page= (1-based) or ?offset=, and answer { results, count, limit, offset, page } where count is the total, not the page size.
  • Full-set lists — document types, taxonomies, atoms, molecules, settings, design tokens — answer everything in one { results, count }.

Branding ​

Organizations on plans without the removeBranding entitlement get a poweredBy string on every read response (and the stamp in the CSS and W3C design-token exports). Nothing else in the body changes; writes are never stamped.

Rate limits ​

Limits are keyed by the credential, not the caller's IP, so one busy consumer cannot throttle another organization. A refused request answers 429 with a Retry-After header.

LimitApplies to
120 requests / minuteEvery read
60 / minute and 2,000 / dayEvery write — the daily cap stops a runaway loop, and only affects writes

CORS and caching ​

Public reads answer Access-Control-Allow-Origin: * without credentials, so a browser app on any domain can call the API with its token in a header (never a cookie). Every response carries Vary: Authorization, X-API-Key; credentialed responses are Cache-Control: private, no-store. Cache on your side — a site build should fetch once and render, not call the API per page view.

Regenerable, not hand-written ​

The endpoint reference and the OpenAPI document are generated from the API server's route table and its API-token allow-list. A route that is not on that reviewed list cannot be reached with a token, and cannot appear here.

Documentation for Hypervalent Studio