Skip to content

Authoring content ​

This page explains how the assistant sees your content model, the workflow that produces good drafts, and the rules that keep edits safe. It assumes a read + write token.

The content model, as the assistant sees it ​

Studio conceptWhat the assistant readsTool
ProjectThe projects the token can reachlist_projects
Document typeIts fields in editor order — slug, type, required, locked, default, config — plus the taxonomies it offers, the molecules it allows, and the exact payload create_document expectsget_doctype
DocumentTitle, slug, description, status, the version's field values, molecule content, tagged terms and referenced imagesget_document, list_documents, search_documents
Taxonomy and termsThe taxonomy's fields and a page of its terms; one term with its contentlist_taxonomies, get_taxonomy, get_term
General Settings, design tokensCurrent values; tokens as JSON, W3C tokens.json, or CSSlist_settings, get_design_tokens

get_doctype is the key read. Its answer is written for models — every field with a one-line description of what to send — so the assistant can author for a document type it has never seen without you explaining the structure.

What the assistant can fill in ​

A document type has root-atom fields (the fields at the top of the editor) and may allow molecules (the repeatable content blocks an editor inserts below them). The assistant writes both.

  • Root-atom fields go in content, keyed by field slug.
  • Molecule content goes in blocks: a list of blocks, each naming its molecule by slug, its field values by field slug, and any nested blocks as children. get_doctype lists every molecule the document type can hold, with its fields and the molecules it may nest.
json
{
  "doctype": "page",
  "title": "About us",
  "blocks": [
    { "molecule": "metadata", "atoms": { "meta-title": "About Acme", "meta-description": "Who we are and what we make." } },
    { "molecule": "section", "atoms": { "heading": "Our story" }, "children": [
      { "molecule": "card", "atoms": { "heading": "Founded 2019" } }
    ] }
  ]
}

Unknown slugs are refused before anything is written: a field the document type doesn't bind, a molecule it doesn't allow, a block field the molecule doesn't have, or a child block its parent can't hold. Each error names its position (blocks[1].children[0].molecule) and lists what is allowed there, so the assistant can fix everything in one retry.

Make a type AI-authorable

Everything a document type allows in the Studio editor can be authored, root fields and blocks alike. Clear field and molecule titles and descriptions help the assistant most: get_doctype shows them to the model.

Field types map to plain values: text, rich text and Markdown as strings, numbers, booleans, selects as their option values, dates as ISO strings. An image field takes the image's uuid from upload_media, as an array, never a URL. A file field works the same way: upload the PDF or document with upload_media first, then pass its uuid in an array. A video field takes a video's uuid from upload_media the same way, or a YouTube, Vimeo or other hosted video URL as is — no upload needed for those.

The workflow ​

  1. Read the schema. "What does a blog post need?" → get_doctype.
  2. Draft. create_document with a title and the field values. The result is a draft: private, invisible to the public API and every site.
  3. Review in Studio. The draft appears in the document list immediately. Open it, adjust, and publish from the editor — or ask the assistant to publish.
  4. Publish. publish_document makes the working version live at once.

The built-in draft-document prompt walks the assistant through steps 1–2 with a confirmation before it writes, and never performs step 4 on its own.

Editing: the replace rule ​

update_document sends the whole set of field values. Whatever it sends replaces what was there; a field it leaves out is cleared. The tool description tells the assistant to read the draft first (get_document with status: "draft") and resend every field it wants kept, and the assistants tested do — but if you ask for a one-word change to a long document, it is worth saying "keep everything else".

The same applies to blocks: when given, it replaces the document's whole block tree. When omitted, the blocks are left alone, so a field-only edit never touches them. Every block in get_document carries a key. The assistant resends it with each block it keeps, so the block keeps its identity (links to that block in the Studio editor keep working). A block without a known key is treated as new.

The same applies to terms: when given, the tag set is replaced.

Editor locks ​

A document someone has open in the Studio editor is locked. An assistant's save against it is refused with VERSION_LOCKED, the editor's display name, and when the lock expires; nothing is written. Ask them to close it, or wait.

The reverse is also true: the assistant never holds a lock, so it can never block an editor.

Published documents and versions ​

Editing a published document creates a new draft version; the live page is unchanged until publish_document. With versioning enabled on the document type, publish keeps the history; without it, the version is updated in place. Publishing is idempotent — asking twice does nothing the second time.

unpublish_document takes the document off the public API and every consuming site at once and returns it to draft; the published versions are kept and publish_document restores it.

trash_document removes it from the API and frees its slug. It is not permanent: an editor can restore it from the trash in Studio. The assistant cannot.

Slugs ​

Omit the slug and it is derived from the title, made unique (launch, launch-2, …). Supply one and a collision answers SLUG_CONFLICT. Renaming (newSlug) changes the public URL of the document immediately on publish, so treat it like any URL change.

Taxonomy terms ​

create_document and update_document tag terms by taxonomy slug → term slugs. Draft and published terms both work, so the assistant can create a term (create_term) and tag it in the same conversation. A term slug that does not exist in that taxonomy is refused by name before anything is written.

Terms have root-atom fields and blocks of their own (get_taxonomy lists the fields and the molecules a term can hold) and the same replace rule on update_term. A term's parent must belong to the same taxonomy; null makes it top-level.

Images, files and videos ​

upload_media stores an image, a file or a video in the project's media library from a public URL (fetched by the server — private and internal addresses are refused) or from base64 data with a filename. Images are JPEG, PNG, WebP, GIF, AVIF or SVG; files are PDF, Word, Excel, PowerPoint, zip, CSV or plain text; videos are MP4, WebM or MOV, up to 30 MiB (send a video by URL — base64 data only fits small files). Identical bytes dedupe to the existing upload. The answer includes the uuid for image, file or video fields and the cdnUrl. Uploads count as writes for rate-limit purposes.

Working with the draft view ​

With a read + write token, list_documents, get_document, search_documents and get_term accept status: "draft" to read the working view: every non-trashed item with its latest working version, whether or not it is published. That is what "show me what is waiting to be published" reads. A read token is silently served the published view instead — it never learns which drafts exist.

Documentation for Hypervalent Studio