API endpoint reference
Every route of the public API (https://api.hypervalent.io/v1), generated from the server's route table and its API-token allow-list — the same source the server boots from, so this page cannot list a route that does not exist. The response and body shapes name schemas in the OpenAPI document, which you can import into Postman, Insomnia, Bruno, or a client generator.
Start with the API overview for authentication, scoping and pagination; the quickstart walks through a first integration end to end.
Every route takes an organization API token in Authorization: Bearer atk_… (or X-API-Key). Routes marked read + write token need a read_write token on a plan with API writes; a read token gets 403 TOKEN_SCOPE_READ_ONLY. Answers are JSON with camelCase keys; failures carry { status, code, message } — see Errors.
Token
What a credential may do and reach. Call these first with an organization-wide token.
List reachable projects
GET /orgs/{org_id}/projects
The projects this token can reach: every live project for an organization-wide token; exactly its own for a project-narrowed one. The only way an organization-wide token discovers project slugs.
| Query | limitpageoffset |
| Answers | ProjectList |
| Rate limit | publicApi (120/min per credential) |
Who am I
GET /orgs/{org_id}/token
The presented token's scope, project narrowing, expiry and the public feature trio. A project-narrowed token is a valid caller here (there is no path project to mismatch) and is confined instead.
| Query | — |
| Answers | TokenWhoami |
| Rate limit | publicApi (120/min per credential) |
Who am I (no organization)
GET /token
The same answer as GET /orgs/{org_id}/token plus the organization the token belongs to — for a caller that does not know its organization yet (an MCP client connected by OAuth login). There is no path organization to cross-check; the token's own organization is used.
| Query | — |
| Answers | TokenWhoamiOrgless |
| Rate limit | publicApi (120/min per credential) |
Structure
The content model — document types, taxonomies, atoms (field definitions) and molecules (reusable blocks).
List atoms (field definitions)
GET /orgs/{org_id}/projects/{projectSlug}/atoms
Every published atom. Root-atom values and content nodes reference atoms by uuid; this list is how a consumer resolves them to a field definition.
| Query | status (published | draft) |
| Answers | AtomList |
| Rate limit | publicApi (120/min per credential) |
Create an atom
POST /orgs/{org_id}/projects/{projectSlug}/atoms · read + write token
Create a field definition. fieldType, category, fieldConfig (only the keys the field type reads) and defaultValue (a value of the field's own shape) are checked before anything is written — every problem at once, as 422 with issues. A draft by default: pass status: published to bind it into a molecule or document type straight away. Answers the public atom shape plus status.
| Query | — |
| Body | AtomWrite |
| Answers | AtomCreated |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
Get an atom
GET /orgs/{org_id}/projects/{projectSlug}/atoms/{slug}
| Query | status (published | draft) |
| Answers | AtomRead |
| Rate limit | publicApi (120/min per credential) |
Edit an atom
POST /orgs/{org_id}/projects/{projectSlug}/atoms/{slug} · read + write token
Edit an atom in the working view (draft or published; trashed is a 404). Every key of AtomWrite is optional and an omitted key is left alone; the checks run against the atom as it will be, so a new fieldType re-checks the stored fieldConfig and defaultValue (resend them when they no longer fit; defaultValue: null clears it). While the atom is bound in a molecule, document type or taxonomy its fieldType and multiple cannot change, and status: draft is 409 CANNOT_DRAFT_IN_USE.
| Query | — |
| Body | AtomWrite |
| Answers | AtomCreated |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
List document types
GET /orgs/{org_id}/projects/{projectSlug}/doctypes
Every published document type with its published-document count, root-atom bindings (atoms), offered taxonomies and supported molecule uuids (supports).
| Query | status (published | draft) |
| Answers | DocumentTypeList |
| Rate limit | publicApi (120/min per credential) |
Create a document type
POST /orgs/{org_id}/projects/{projectSlug}/doctypes · read + write token
Create a content blueprint: root atom bindings, the molecules its content tree may hold at the top level, the taxonomies it offers and its preset tree — every reference a published row of this project, checked before anything is written. The plan's document-type cap applies (403 LIMIT_EXCEEDED). A draft by default; documents can be created under a draft document type, but only a published one is served by the reads.
| Query | — |
| Body | DocumentTypeWrite |
| Answers | DocumentTypeCreated |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
Get a document type
GET /orgs/{org_id}/projects/{projectSlug}/doctypes/{slug}
One published document type — the authoring schema a write payload is validated against.
| Query | status (published | draft) |
| Answers | DocumentTypeRead |
| Rate limit | publicApi (120/min per credential) |
Edit a document type
POST /orgs/{org_id}/projects/{projectSlug}/doctypes/{slug} · read + write token
Edit a document type in the working view. Every key of DocumentTypeWrite is optional; atoms, supports, taxonomies and content each REPLACE the stored list or tree when sent. Existing documents keep their stored values; a root atom removed from atoms drops out of their reads. Unpublishing a document type that documents use is 409 CANNOT_DRAFT_IN_USE. Answers the working-view read.
| Query | — |
| Body | DocumentTypeWrite |
| Answers | DocumentTypeCreated |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
List the atom & molecule library
GET /orgs/{org_id}/projects/{projectSlug}/library
The platform's catalogue of ready-made atoms and molecules, which any project can insert. It is the same for every project and says nothing about what a project already holds: compare slugs with /atoms and /molecules, or call /library/plan. Strings are en-US.
| Query | — |
| Answers | LibraryCatalogue |
| Rate limit | publicApi (120/min per credential) |
Insert library items
POST /orgs/{org_id}/projects/{projectSlug}/library/insert · read + write token
Insert items and their whole dependency closure in one all-or-nothing transaction. Inserted rows are published immediately, so they can be bound at once. A slug the project already has is reused and never overwritten; a matching draft is published in place. Calling it again changes nothing. Unknown items are 404 LIBRARY_ITEM_NOT_FOUND, a malformed list 400 LIBRARY_ITEMS_INVALID.
| Query | — |
| Body | LibraryInsert |
| Answers | LibraryPlan |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
Plan a library insert
GET /orgs/{org_id}/projects/{projectSlug}/library/plan
A dry run of POST …/library/insert against this project; writes nothing. Lists every row of the dependency closure with what the insert would do to it: add, reuse (the slug exists and the project's definition wins) or publish (the slug exists as a draft and would be published in place). A publish row has no uuid unless the token can read drafts. Unknown items are 404 LIBRARY_ITEM_NOT_FOUND, a malformed list 400 LIBRARY_ITEMS_INVALID.
| Query | items |
| Answers | LibraryPlan |
| Rate limit | publicApi (120/min per credential) |
List molecules (reusable blocks)
GET /orgs/{org_id}/projects/{projectSlug}/molecules
| Query | status (published | draft) |
| Answers | MoleculeList |
| Rate limit | publicApi (120/min per credential) |
Create a molecule
POST /orgs/{org_id}/projects/{projectSlug}/molecules · read + write token
Create a reusable block: its atom bindings (published atoms of this project, each once, with typed defaults and sibling visibility conditions), the published molecules it may nest (supports) and its preset tree (content). Checked against the project's published structure before anything is written. A draft by default. Answers the public molecule shape plus status.
| Query | — |
| Body | MoleculeWrite |
| Answers | MoleculeCreated |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
Get a molecule
GET /orgs/{org_id}/projects/{projectSlug}/molecules/{slug}
| Query | status (published | draft) |
| Answers | MoleculeRead |
| Rate limit | publicApi (120/min per credential) |
Edit a molecule
POST /orgs/{org_id}/projects/{projectSlug}/molecules/{slug} · read + write token
Edit a molecule in the working view. Every key of MoleculeWrite is optional; atoms, supports and content each REPLACE the stored list or tree when sent (read it with ?status=draft first) and are left alone when omitted. A supports change re-checks the stored preset tree. Unpublishing a molecule another structure supports is 409 CANNOT_DRAFT_IN_USE.
| Query | — |
| Body | MoleculeWrite |
| Answers | MoleculeCreated |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
Documents
Published documents, nested under their document type; drafts through the working view.
List documents of a type
GET /orgs/{org_id}/projects/{projectSlug}/doctypes/{doctypeSlug}/documents
One page of the document type's published documents, each with its active version's content and projected root atoms inline. The page's referenced images ship once in referencedImages, and the files and videos its file and video fields reference once in referencedFiles.
| Query | status (published | draft)limitpageoffset |
| Answers | DocumentList |
| Rate limit | publicApi (120/min per credential) |
Create a draft document
POST /orgs/{org_id}/projects/{projectSlug}/doctypes/{doctypeSlug}/documents · read + write token
Create a draft document and its first version. The payload is validated against the document type before any write (422 with a per-field fields map). Content goes through the editor's own save path, so the write has exactly the guards the editor has. Answers the working view of the new document — the same body GET …/documents/{slug}?status=draft serves.
| Query | — |
| Body | DocumentWrite |
| Answers | DocumentRead |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
Get a document
GET /orgs/{org_id}/projects/{projectSlug}/doctypes/{doctypeSlug}/documents/{slug}
One document with its version, tagged taxonomy terms (with their content) and referenced images. Anything not published — or not existing — is a plain 404 to a read token.
| Query | status (published | draft) |
| Answers | DocumentRead |
| Rate limit | publicApi (120/min per credential) |
Edit a document
POST /orgs/{org_id}/projects/{projectSlug}/doctypes/{doctypeSlug}/documents/{slug} · read + write token
Edit the working document (draft or published; a trashed document is a 404). content / rootAtoms / taxonomyTerms land on the working version FIRST — an editor holding a fresh checkout refuses the whole save with 409 VERSION_LOCKED and nothing is written — then title / description / slug land on the row. Editing a published version with versioning on forks a new draft, as the editor would.
| Query | — |
| Body | DocumentWrite |
| Answers | DocumentRead |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
Publish a document
POST /orgs/{org_id}/projects/{projectSlug}/doctypes/{doctypeSlug}/documents/{slug}/publish · read + write token
Make the working version live — visible on the public read API and therefore on the customer's site at once. Idempotent: an already-published working version is left alone. Lock-checked like any save.
| Query | — |
| Answers | DocumentRead |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
Trash a document
POST /orgs/{org_id}/projects/{projectSlug}/doctypes/{doctypeSlug}/documents/{slug}/trash · read + write token
Soft-trash the document. The slug is rewritten to <slug>-trashed-<uuid> so the original is free again. There is no purge and no restore through the public surface — an admin restores from Studio.
| Query | — |
| Answers | DocumentTrashed |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
Unpublish a document
POST /orgs/{org_id}/projects/{projectSlug}/doctypes/{doctypeSlug}/documents/{slug}/unpublish · read + write token
Move the document row back to draft. Published versions are immutable and stay in the history.
| Query | — |
| Answers | DocumentRead |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
Taxonomies
Taxonomies and their terms.
List taxonomies
GET /orgs/{org_id}/projects/{projectSlug}/taxonomies
Every published taxonomy with its published-term count, root-atom bindings and the document types that offer it. ?status=draft lists draft taxonomies too, each with its preset content.
| Query | status (published | draft) |
| Answers | TaxonomyList |
| Rate limit | publicApi (120/min per credential) |
Create a taxonomy
POST /orgs/{org_id}/projects/{projectSlug}/taxonomies · read + write token
Create a taxonomy — the term blueprint: root atom bindings, the molecules a term's content tree may hold at the top level and its preset tree, every reference a published row of this project, checked before anything is written (422 with issues). The plan's taxonomy cap applies (403 LIMIT_EXCEEDED). A draft by default; terms can be created under a draft taxonomy, but a document type can only offer a published one.
| Query | — |
| Body | TaxonomyWrite |
| Answers | TaxonomyCreated |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
Get a taxonomy with a page of its terms
GET /orgs/{org_id}/projects/{projectSlug}/taxonomies/{slug}
The taxonomy plus one page of its terms, each with its active version's content inline.
| Query | status (published | draft)limitpageoffset |
| Answers | TaxonomyRead |
| Rate limit | publicApi (120/min per credential) |
Edit a taxonomy
POST /orgs/{org_id}/projects/{projectSlug}/taxonomies/{slug} · read + write token
Edit a taxonomy in the working view. Every key of TaxonomyWrite is optional; atoms, supports and content each REPLACE the stored list or tree when sent (read it with ?status=draft first). Existing terms keep their stored values. Unpublishing a taxonomy a document type offers or that has live terms is 409 CANNOT_DRAFT_IN_USE. Answers the working-view read.
| Query | — |
| Body | TaxonomyWrite |
| Answers | TaxonomyCreated |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
Create a draft term
POST /orgs/{org_id}/projects/{projectSlug}/taxonomies/{taxonomySlug}/terms · read + write token
Create a draft term and its first version under the taxonomy. parentSlug must name a live term of the SAME taxonomy. Answers the working view of the new term.
| Query | — |
| Body | TermWrite |
| Answers | TermRead |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
Get a term
GET /orgs/{org_id}/projects/{projectSlug}/taxonomies/{taxonomySlug}/terms/{slug}
One term with its active version, hydrated like a document. version is null for a published term that never had a published version.
| Query | status (published | draft) |
| Answers | TermRead |
| Rate limit | publicApi (120/min per credential) |
Edit a term
POST /orgs/{org_id}/projects/{projectSlug}/taxonomies/{taxonomySlug}/terms/{slug} · read + write token
Edit the working term: content first (lock check on), then the row — including parentSlug (null = top level; never itself).
| Query | — |
| Body | TermWrite |
| Answers | TermRead |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
Publish a term
POST /orgs/{org_id}/projects/{projectSlug}/taxonomies/{taxonomySlug}/terms/{slug}/publish · read + write token
Make the working version live and the term row published — visible on the public read API, and in every published document tagged with it, at once. Idempotent: an already-published working version is left alone. Lock-checked like any save. A term with no version publishes its row alone.
| Query | — |
| Answers | TermRead |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
Trash a term
POST /orgs/{org_id}/projects/{projectSlug}/taxonomies/{taxonomySlug}/terms/{slug}/trash · read + write token
Soft-trash the term. The slug is rewritten to <slug>-trashed-<uuid> so the original is free again. A term any document is tagged with is 409 CANNOT_TRASH_IN_USE. No purge and no restore through the public surface — an admin restores from Studio.
| Query | — |
| Answers | TermTrashed |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
Unpublish a term
POST /orgs/{org_id}/projects/{projectSlug}/taxonomies/{taxonomySlug}/terms/{slug}/unpublish · read + write token
Move the term row back to draft. A term any document is tagged with is 409 CANNOT_DRAFT_IN_USE.
| Query | — |
| Answers | TermRead |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
Settings
General Settings — admin-defined configuration values.
List settings
GET /orgs/{org_id}/projects/{projectSlug}/settings
Every published General Setting with its configured value under value.
| Query | — |
| Answers | SettingList |
| Rate limit | publicApi (120/min per credential) |
Get a setting
GET /orgs/{org_id}/projects/{projectSlug}/settings/{slug}
One published setting by slug — the read for a single configured value such as site-title.
| Query | — |
| Answers | SettingRead |
| Rate limit | publicApi (120/min per credential) |
Design tokens
The project's design system, as structured JSON, W3C tokens.json, or a CSS custom-property sheet.
List design token schemes
GET /orgs/{org_id}/projects/{projectSlug}/design-token-schemes
Every published scheme (e.g. light / dark). A token's missing scheme value inherits from the scheme's baseSchemeSlug.
| Query | token_type |
| Answers | DesignTokenSchemeList |
| Rate limit | publicApi (120/min per credential) |
Get the design theme
GET /orgs/{org_id}/projects/{projectSlug}/design-token-theme
The generator input the palettes and color roles are built from: the source color, the M3 scheme variant and the optional secondary / tertiary / neutral key colors, plus the variants a theme may name.
| Query | — |
| Answers | DesignThemeRead |
| Rate limit | publicApi (120/min per credential) |
Save the design theme and regenerate
POST /orgs/{org_id}/projects/{projectSlug}/design-token-theme · read + write token
Save any of the theme's keys (a key color sent as null or "" is cleared, and the variant then derives that palette from the source) and regenerate every palette and color role from it. Color tokens with valueSource: manual keep their values.
| Query | — |
| Body | DesignThemeWrite |
| Answers | DesignThemeResult |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
List design tokens
GET /orgs/{org_id}/projects/{projectSlug}/design-tokens
Every published design token, with each scheme value expanded (colors into hex / rgb / hsl forms). status=draft (a read_write token on a plan with API writes) adds the draft rows — the unpublished component tokens — each carrying its status.
| Query | status (published | draft)token_typecomponent |
| Answers | DesignTokenList |
| Rate limit | publicApi (120/min per credential) |
Edit design tokens
POST /orgs/{org_id}/projects/{projectSlug}/design-tokens · read + write token
Edit up to 200 EXISTING tokens by slug in one transaction — tokens are never created or trashed through the API. schemeValues keys replace the stored ones and the rest are kept: a color role is keyed by scheme slug (hex values), a palette by tone, every other type by default — a CSS string, a typography composite (merged by property; fontFamily names a font-family set), or a component's { ref: '<group>.<token>' } / { value }. A color edit stamps valueSource: manual so regeneration keeps it; valueSource: generated hands the color back to the generator and regenerates. status moves a token between draft and published (publishing a component's tokens adds it to the export). Every problem is reported at once as 422 with issues; nothing is written until all pass.
| Query | — |
| Body | DesignTokenEdits |
| Answers | DesignTokenEditResult |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |
CSS custom-property export
GET /orgs/{org_id}/projects/{projectSlug}/design-tokens.css
A stylesheet of custom properties per scheme (Material 3 roles), ready to link from a site. Errors from this raw export use the nested { error } envelope; an unknown org or project answers a text/plain CSS comment.
| Query | — |
| Answers | string |
| Rate limit | publicApi (120/min per credential) |
W3C tokens.json export
GET /orgs/{org_id}/projects/{projectSlug}/design-tokens.tokens.json
The published tokens in the W3C Design Tokens JSON format. Errors from this raw export use the nested { error } envelope; an unknown org or project answers { "error": "Not found" }.
| Query | — |
| Answers | W3CDesignTokens |
| Rate limit | publicApi (120/min per credential) |
Media
Image, file and video upload.
Upload an image, file or video
POST /orgs/{org_id}/projects/{projectSlug}/media · read + write token
Upload one or more images, files or videos as multipart/form-data (file / files + title / alt), or one by public URL as JSON { url } fetched server-side. Same ingest pipeline as Studio: content sniffing, a type allow-list (by default JPEG, PNG, WebP, GIF, AVIF and SVG images, PDF, Word, Excel and PowerPoint documents, zip, CSV and plain text, and MP4, WebM and MOV videos), SVG sanitizing, sha256 de-duplication, the plan's storage cap (403 LIMIT_EXCEEDED) and async thumbnails for images (files and videos have none, and no width / height). Per-file size caps, by default 20 MiB for images and files and 30 MiB for videos; a file over its cap is 413 FILE_TOO_LARGE. Use the returned uuid in an image field (images only), a file field, or a video field (videos only).
| Query | — |
| Body | MediaUploadMultipart (multipart/form-data), MediaUploadByUrl (application/json) |
| Answers | MediaUploadResult |
| Rate limit | publicApiWrite (60/min + 2,000/day per credential) |