Managing pages over the API
The editorial surface is where pages are drafted and composed. It shows everything an editor sees: drafts, archived pages, the trash, and every publication a page has had. A storefront does not read from it. Visitors get the published result from the delivery routes, described in Reading published pages.
Use these routes to manage the records around a page: change page records, retire pages, keep navigation menus in step with your theme, maintain the shared library and templates, and set the site-wide settings a theme styles with.
Before you start
These are server-side calls through the gateway, made with the tenant's API key. Never send them from the browser. The authentication page covers the headers.
They are for a team that manages pages from its own tooling, or for a migration. A storefront reads delivery instead.
What this API does not do
- Block content is not here. The page routes change the page record only, so their responses have no block tree. Library items and templates are the exception: they carry their
tree. - Publishing is not one of these routes. It happens in the editor. Setting a page's status to
publishedhere does not publish its content. - Library items and templates cannot be created through these routes. You make them in the editor (Cockpit); a pop-up, which is a library item too, is created with
POST /v1/pages/popups. These routes read, change and remove them.
Conventions
- Lists answer with
items,filter(the filters that were applied) andpage(total,returned,limit,offset,hasMore). - Unknown filters. Pages, menus, library items and template assignments ignore a filter key they do not read. The answer is still
200, and that key is missing fromfilter. Templates and revisions refuse an unknown filter key with400and the codeunknown_filter. They also refuse a value that starts with an operator such asnot., with400andunsupported_filter_operator. Filters match exact values, except the text searches:qon pages andtexton library items match part of the title or label, ignoring case. - Paging uses
limit(1 to 200) andoffset.ordertakes one field, with an optional.ascor.desc. An unknown field is refused with400. - Deletes. Pages, menus and library items are soft-deleted: the record is kept and hidden from normal reads. Templates, template assignments and site settings are removed outright and cannot be restored.
- Empty updates. On menus, library items and templates, a
PUTwith no fields to change answers400with the codeempty_update. A pagePUTwith nothing to change answers200. - Every route can also answer
401,403,429and502.
Pages
| Route | What it does |
|---|---|
GET /v1/pages/pages | Lists pages of every status, newest change first. Filters: status (draft, published, archived), bundle, and q (case-insensitive title search). deleted=only lists the trash instead. Any other deleted value is 400. |
POST /v1/pages/pages | Creates a page and its source-language translation. Answers 201. |
GET /v1/pages/pages/{id} | Reads one page record. The record has no block tree. |
PUT /v1/pages/pages/{id} | Changes the record. Answers 200. |
DELETE /v1/pages/pages/{id} | Soft-deletes the page. Answers 200 with deleted: true. |
POST /v1/pages/pages/{id}/duplicate | Copies the page into a new, unpublished page. Answers 201. |
POST /v1/pages/pages/{id}/restore | Brings a deleted page back. Answers 200. |
GET /v1/pages/pages/{id}/revisions | Lists the publication history of the page. |
Create (POST /v1/pages/pages). title is required. The other fields are optional:
bundle,sourceLanguageand the page's default status come from the tenant's settings when you leave them out. The status is never a body field.slugdefaults to none.hostOptionsandmetaare stored as{}when left out.templateIdstarts the page from a template. The template's blocks are copied in, and the page takes the template's bundle. If the template has apage_bundle,bundlemust match it.400whentitleis missing, whentemplateIdnames no template, when the template is for another page type, or when the template holds a block that cannot be copied.409when another live page in the tenant already holds theslug.
Example body, using the spec's example values:
{
"title": "About us",
"slug": "about-us",
"bundle": "standard",
"sourceLanguage": "de"
}
Read (GET /v1/pages/pages/{id}). Returns title, slug, bundle, status, source_language, host_options, meta, the timestamps, and published_revision_id. A page with status: published but no published_revision_id is not served to visitors, because only a publication is delivered.
Update (PUT /v1/pages/pages/{id}). Only five fields change: title, slug, status, meta and bundle. Other body fields are dropped without an error.
metais replaced as a whole, not merged.- A new
slugworks on delivery at once, and the slug the page had at its last publish keeps working too until the page is published again in the editor. The delivery response also shows that oldersluguntil then.slug: nullclears the record's slug, but the slug from the last publish keeps serving the page until the next publish. 409when theslugbelongs to another live page.
Delete (DELETE /v1/pages/pages/{id}). The page leaves every list, read and delivery response at once, and its slug is free for another page immediately. Nothing is erased: translations, blocks, revisions and comments stay, so the page can be restored. 404 when the page is unknown or already deleted.
Duplicate (POST /v1/pages/pages/{id}/duplicate). Copies what the source shows: its blocks as published, every language's title, its bundle, language, display options and metadata. An open draft on the source is not copied. The copy gets new block ids, but a block that uses a library item keeps referencing it. The copy is unpublished, has no revisions, and starts at the default page status.
- Body:
titleandslugare both optional. Without aslugthe copy has none, so it cannot collide. An empty body gives the source title plus a copy suffix. 409when theslug, or a slug on a translation of a live page, is taken.
Restore (POST /v1/pages/pages/{id}/restore). Brings the deleted page back with its translations, revisions and published revision as they were. Only the slug can have changed, because deleting freed it.
404when the page is not deleted. Only a page in the trash can be restored.409when another live page now holds the page'sslug. The page stays in the trash; free the slug or change it, then restore again.
Publication history (GET /v1/pages/pages/{id}/revisions). One entry per publication, newest first. The list does not include the published content, only the entries. Filters are exact matches: label, created_by (user id), created_by_name, and created_at (RFC 3339, exact match only). 404 when the page id is unknown.
Menus
Menus are the navigation a theme renders, for example main, footer and account. Each menu has a menu_key, which is how a theme asks for it.
| Route | What it does |
|---|---|
GET /v1/pages/menus | Lists menus. Takes paging and order only. A menu_key filter is ignored. |
POST /v1/pages/menus | Creates a menu by key, or replaces the label and items of the menu that already has the key. |
GET /v1/pages/menus/{id} | Reads one menu by the menu's id, including the whole nested items tree. |
PUT /v1/pages/menus/{id} | Replaces the label, items and metadata of one menu, by the menu's id. |
DELETE /v1/pages/menus/{id} | Soft-deletes a menu. |
- Upsert (
POST). SendmenuKey(required) anditems. Senditemson every call: when it is missing, the menu is saved with no items, so an update that only changeslabelempties the navigation.labelis required when the key is new. An update keeps the old label if you leave it out. The answer is201when the key was free and200when an existing menu was replaced.400whenmenuKeyis missing, orlabelis missing on a create. itemsis replaced, never merged. Sending an empty list empties the navigation.- Keys are kept unique by this route only. If two menus ever share a key, this route updates whichever one it finds first.
- Update (
PUT). Do not sendmenu_key. Changing a menu's key empties the slot a theme reads, and nothing reports an error. - Delete. The menu disappears from the management list and from delivery at once. A theme that reads the key gets nothing back, with no error. The key is free again immediately, so re-seeding the theme restores it. Check what reads the key before you delete it.
Library
The library holds reusable blocks. A library item is shared by reference: pages that use it render the item's current tree, so an edit to the item changes every page that uses it, without any page being edited or republished. Compare templates, which are copied.
| Route | What it does |
|---|---|
GET /v1/pages/library | Searches the library. Filters: bundles (comma-separated block types) and text (substring of the label). Paged, default 24. |
GET /v1/pages/library/{id} | Reads one item, including its tree. |
PUT /v1/pages/library/{id} | Replaces bundle, label, metadata or tree of one item. Answers 200. |
DELETE /v1/pages/library/{id} | Soft-deletes an item. Answers 200 with deleted: true. |
- The filter is
bundles, plural.?bundle=is ignored. - Pop-ups are library items too, with the bundle
popup. An unfiltered library list includes them. Edit pop-ups through the pop-up routes instead; see Pop-ups. - Update. Replacing
treechanges every page that references the item, including published pages. No publication records the change, because the pages themselves did not change.metadatais replaced as a whole. - Delete. The item leaves the picker and the lists. Blocks that point at it keep their reference, but a reference holds no content of its own: delivery then renders each one as an empty block of its bundle, on published pages too, with no error. The API does not list which pages use an item, so check before you delete it.
404when the item is unknown or deleted.
Templates
A template is copied into a new page. Nothing links back from the pages built from it, so editing a template changes only what future pages start from.
| Route | What it does |
|---|---|
GET /v1/pages/templates | Lists templates. Every field is an exact-match filter: id, label, description, page_bundle, field_name, is_default, created_by, created_at, updated_at. |
GET /v1/pages/templates/{id} | Reads one template, including its tree. |
PUT /v1/pages/templates/{id} | Replaces the fields you send. Answers 200. |
DELETE /v1/pages/templates/{id} | Removes the template. This cannot be undone. |
- Fields.
label,description,page_bundle,field_name,is_defaultandtree. Apage_bundleorfield_nameofnulloffers the template everywhere. Filtering bypage_bundledoes not return templates that have none. is_defaultis a marker. A client can look it up with?is_default=true. Nothing in the API starts a page from it: a page starts from a template only whentemplateIdis sent on create.- Update. Does not change pages that already exist.
- Delete. Pages built from the template keep their own copy of the blocks.
404when the template id is unknown.
Template assignments
Template assignments choose the page that renders a single record, such as one product, instead of the theme's default template. A record without an assignment is not an error; it renders with the default.
| Route | What it does |
|---|---|
GET /v1/pages/template-assignments | Lists assignments. Filters: resource_type (one kind of record) and page_slug (every record one page is the template of). |
PUT /v1/pages/template-assignments/{resource_type}/{resource_id} | Assigns a page to one record. Answers 200. |
DELETE /v1/pages/template-assignments/{resource_type}/{resource_id} | Removes the assignment outright. Answers 200 with deleted: true. |
- Assign (
PUT). The body needspageSlug, the slug of a live page. The page need not be published, but the storefront uses it only once it is. The record is the address, so a secondPUTmoves the assignment rather than adding one.resource_typeis lower-case letters, digits and underscores, starts with a letter, and is up to 64 characters (a hyphen is refused).resource_idis 1 to 255 characters. The app does not look the record up. 400for an invalid type or id, a missingpageSlug, or a slug that no live page holds.409when two requests first assign the same record at the same moment; send the call again.- Remove (
DELETE). Hard delete. The page itself is not touched.404when the record has no assignment.
Site settings
Site settings are the theme-wide values a storefront styles itself with. The keys the storefront themes read are appearance, design and customCss. The API stores any JSON value under a key; the theme that reads it decides its shape.
| Route | What it does |
|---|---|
GET /v1/pages/settings/site | Lists every key that is set, ordered by key. Answers items only, with no page block. The list is capped at 200 keys. |
GET /v1/pages/settings/site/{key} | Reads one key with its value and who set it last. |
PUT /v1/pages/settings/site/{key} | Creates or replaces a key. Answers 200 either way. |
DELETE /v1/pages/settings/site/{key} | Unsets a key outright. Answers 200 with deleted: true. |
- Key format. A lower-case letter followed by letters and digits, up to 64 characters in total. Anything else is
400. - Read. A key that was never set answers
404, so "not set" and "set to nothing" are different. - Write.
valueis required and must not benull; to remove a key useDELETE. The value is replaced as a whole, not merged. The serialized value can be at most 128 KiB; a larger one is413and nothing is written.409when two requests first set the same key at the same moment; send the call again. - Delete. Setting the key again starts afresh. On delivery, an unset
appearance,designorcustomCsscomes back asnull. Any other unset key is absent.
Vocabularies
Vocabularies are the enumerated values the page API uses, such as page statuses. Each comes with its title and a plain sentence explaining it, so a select or a status badge can label the values without keeping a copy of its own.
| Route | What it does |
|---|---|
GET /v1/pages/vocabularies | Lists the vocabularies by name, title and description. The values are not included. |
GET /v1/pages/vocabularies/{name} | Returns one vocabulary with all its values, in the order a select should offer them. |
- Names.
edit-state-statuses,page-statusesandtranslation-statuses. - Values. Each value comes with a title, a description and the badge tone to render it in. The tones are
neutral,info,success,warninganddanger. Text fields can be a plain string or a map keyed by language tag; read your language and fall back toen. closed: truemeans the list is complete. A value outside it is stale data.404when the name is not published.