REST API

Every /api/v1 route: what it does, who may call it, and the parameters it takes. Send your API key as a Bearer token.

On this page

The public REST API of PageHub, called with a ph_ API key (Authorization: Bearer ph_...), plus the one webhook the platform calls on a white-label tenant's server (fetchPage).

A site is HTML + Liquid files: its pages are files (pages/*.liquid), written through the files API; the page routes manage each page's record (name, slug, SEO, access). Writes land in the site's draft; PUT /api/v1/sites/{id} with published: true makes the draft live.

The headless content API (/api/v1/content/...) is described by its own document (GET /api/v1/content/openapi.json); GET /api/openapi.json serves this document with it merged in.

The routes also accept the dashboard's session cookie from the dashboard itself; only the API key is the public contract.

Every operation carries two extension fields. x-auth says who may call it: api-key (a ph_ key), session-or-key (the dashboard's own session, or a key), optional-key (public, a key widens what you see), admin-key (a platform admin's key), session (the dashboard session only; an API key is refused) or public. x-rate-limit names the rate-limit rule (see the rate-limiting guide) when the route has one; most routes limit per user, public routes per IP.

Sites

Create, read, update, publish and delete sites.

List sites

GET /api/v1/sites

The sites the key's user is a member of, or the sites of the key's tenant, newest update first.

Who can call it: API key.

Create a site

POST /api/v1/sites

Creates a site from a template's stored files, or the blank starter when no template is given.

Who can call it: API key.

JSON body fields: name, title, description, template, sourceTemplate.

Read a site

GET /api/v1/sites/{id}

The site's own fields. Its pages are files: read them through the files API. mountKey is returned only to a tenant key or a user with the owner or agency role.

Who can call it: Public; an API key shows more.

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Update or publish a site

PUT /api/v1/sites/{id}

Sets the site's own fields. published: true builds a release from the draft and makes it live (the first publish is subject to the plan's site limit); published: false unpublishes. Pages are not sent here: use the files and pages routes.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: name, title, description, ogImage, portal, crawlPolicy, timezone, language, mountOrigin, rotateMountKey, published, expectedUpdatedAt.

Delete a site

DELETE /api/v1/sites/{id}

Permanently deletes the site and everything under it. Site owners only.

Who can call it: API key.

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Duplicate a site

POST /api/v1/sites/{id}/duplicate

Copies the site's files and page rows into a new site owned by the caller. Needs edit access.

Who can call it: API key.

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: name, title, description.

Audit a draft page

GET /api/v1/sites/{id}/audit

Renders the draft page as the preview does, then runs the SEO or accessibility checks on it.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
kindqueryseo \accessibility
pathquerystringThe page's URL path.

Screenshot the draft

POST /api/v1/sites/{id}/screenshot

Renders the draft preview in a real browser and returns the image as base64. Nothing is stored.

Who can call it: API key.

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: path, width, height, fullPage, selector.

Change theme, favicon, language or integrations

PUT /api/v1/sites/{id}/source-settings

Settings that live in the site's files: theme sets custom properties in theme.css, favicon sets or clears site.json favicon, language is site.json lang, integrations merges provider blocks. Send at least one.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: theme, favicon, language, integrations.

List AI edits waiting for review

GET /api/v1/sites/{id}/ai-review

In review mode PageHub AI stages its file edits instead of writing them. count=1 answers only the number.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
countquery

Keep or discard staged AI edits

POST /api/v1/sites/{id}/ai-review

Keep writes a staged file to the draft (as an AI write, against bases); discard drops it. keep and discard take file paths or "all". A file that changed meanwhile answers 409 version_conflict and nothing is written.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: keep, discard, bases.

Read the social image design

GET /api/v1/sites/{id}/og-card

The site-wide Social Image designer scene. Claimed sites need an editor session; an unclaimed site passes.

Who can call it: Dashboard session only (an API key is refused).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Save the social image design

PUT /api/v1/sites/{id}/og-card

Who can call it: Dashboard session only (an API key is refused).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: scene.

Read the favicon design

GET /api/v1/sites/{id}/favicon-design

Who can call it: Dashboard session only (an API key is refused).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Save the favicon design

PUT /api/v1/sites/{id}/favicon-design

Who can call it: Dashboard session only (an API key is refused).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: scene, renderedMediaId.

Read a site's privacy settings

GET /api/v1/sites/{id}/privacy

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Update a site's privacy settings

PUT /api/v1/sites/{id}/privacy

Send only the fields to change.

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: consentMode, privacyUrl, builtInAnalytics, submissionRetentionDays.

Files

A site's draft files (pages, partials, theme.css, site.json, ...).

List draft files, read several, or search them

GET /api/v1/sites/{id}/files

Without q or read: every file path of the draft with its version (a content hash); glob keeps only the matching paths. With read: the text and version of up to 40 files in one call (400,000 characters at most; the rest comes back as skipped). With q: the hits of the text (plain, case-insensitive) or, with regex, of a JavaScript regular expression run under a time limit; each hit has its line and column and the text around the match. Up to 100 hits.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
X-PageHub-StageheaderWith an API key: read the draft under the staged AI layer and write into that layer instead of the draft.
qquerystringText to search for.
pathquerystringWith q: only files whose path starts with this, e.g. pages/.
readquerystringComma-separated paths to read in one call (1-40), e.g. pages/index.liquid,partials/header.liquid.
regexquery1 \true
globquerystringOnly paths matching, for the listing and for q: * within a folder, ** across folders, ?, {a,b}. A glob with no / matches the file name at any depth (*.liquid).
contextqueryintegerWith q: lines of context before and after each hit.

Save a batch of files atomically

POST /api/v1/sites/{id}/files

Writes and deletes up to 500 files in one atomic save. baseVersions says which version of each file you edited; a file someone else changed since answers 409 version_conflict and nothing is written. Files are linted and sanitized; invalid HTML nesting is repaired and reported in repaired, so compare the stored text before the next edit. pages also creates a page record for each new page file in the same write, so a new page and the link to it land together; a page that can't be created (taken URL, plan cap) answers 400 or 403 and writes nothing. Not available in review mode.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
X-PageHub-StageheaderWith an API key: read the draft under the staged AI layer and write into that layer instead of the draft.

JSON body fields: changes, baseVersions, pages.

Read one draft file

GET /api/v1/sites/{id}/files/{path}

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
X-PageHub-StageheaderWith an API key: read the draft under the staged AI layer and write into that layer instead of the draft.
path (required)pathstringThe file's path in the site, one URL segment per folder, e.g. pages/shop/[handle].liquid.

Write one draft file

PUT /api/v1/sites/{id}/files/{path}

Same rules as the batch save, for a single file. page on a new pages/<slug>.liquid file also creates its page record.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
X-PageHub-StageheaderWith an API key: read the draft under the staged AI layer and write into that layer instead of the draft.
path (required)pathstringThe file's path in the site, one URL segment per folder, e.g. pages/shop/[handle].liquid.

JSON body fields: text, baseVersion, page.

Outline a page

GET /api/v1/sites/{id}/outline

The structure of one page of the draft: sections and landmarks with their line ranges, headings, and every {% render %} / {% section %} of a partial, expanded in place with its own sections and headings (anchored to the partial's file and lines) unless expand=0. Rendered partials that are components carry their use counts.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
X-PageHub-StageheaderWith an API key: read the draft under the staged AI layer and write into that layer instead of the draft.
page (required)querystringA page id, its URL (/about) or a file path (pages/about.liquid, partials/header.liquid).
expandquery0 \1
classesquery1 \true

Pages

The page records of a site: name, slug, URL pattern, SEO, access policy.

List pages

GET /api/v1/sites/{id}/source-pages

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Create a page

POST /api/v1/sites/{id}/source-pages

Creates the page's file (it must not exist yet) and its record. The first page of a site becomes the home page. Send text, or blank: true to start from the site's own header and footer around a heading.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: name, slug, pathPattern, text, blank, seo, file.

Read a page's record and settings

GET /api/v1/sites/{id}/source-pages/{pageId}

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
pageId (required)pathstringThe page's pageId from the pages list.

Change a page's record

PATCH /api/v1/sites/{id}/source-pages/{pageId}

seo and policy merge into the current values; a null value removes a key. file edits the page's own file. Clients (content-only role) cannot change page settings.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
pageId (required)pathstringThe page's pageId from the pages list.

JSON body fields: name, slug, pathPattern, isHomePage, is404Page, isHidden, seo, policy, file.

Delete a page

DELETE /api/v1/sites/{id}/source-pages/{pageId}

Deletes the page's file, then its record. The home page cannot be deleted.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
pageId (required)pathstringThe page's pageId from the pages list.

Components

Reusable components (partials) of a site.

List components

GET /api/v1/sites/{id}/components

The reusable components (partials) of the site's draft and where each is used.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Rename a component

PATCH /api/v1/sites/{id}/components/{name}

Renames the component and every {% render %} tag of it, as one write.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
name (required)pathstringThe component's id.

JSON body fields: name.

Delete a component

DELETE /api/v1/sites/{id}/components/{name}

Refused with 409 in_use while anything still renders it.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
name (required)pathstringThe component's id.

Collections

A site's collections and their rows. Reading them publicly is the content API.

List collections

GET /api/v1/sites/{id}/collections

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Create a collection

POST /api/v1/sites/{id}/collections

Needs the owner or agency role on the site and a plan that includes collections (and the chosen source type).

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: slug, name, description, schema, source, isPublic.

Read a collection

GET /api/v1/sites/{id}/collections/{colId}

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.

Update a collection

PATCH /api/v1/sites/{id}/collections/{colId}

name and description are open to any editor; changing the slug, schema, source, visibility or member gates needs the owner or agency role.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.

JSON body fields: name, description, slug, schema, source, isPublic, requiresCustomerLogin, requiredPlans, memberFields.

Delete a collection and its rows

DELETE /api/v1/sites/{id}/collections/{colId}

Owner or agency role.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.

List rows

GET /api/v1/sites/{id}/collections/{colId}/rows

Cursor-paginated, in order. Fields the reader's role cannot read are redacted.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.
limitqueryinteger
cursorquerystringThe nextCursor of the previous page.

Create rows

POST /api/v1/sites/{id}/collections/{colId}/rows

Send one row ({ data } or the bare field object), an array of rows, or { rows: [...] }; up to 500 per call. Each row is validated against the collection's schema.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.

Update a row

PATCH /api/v1/sites/{id}/collections/{colId}/rows/{rowId}

data merges into the row's current data and is validated against the schema.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.
rowId (required)pathstring

JSON body fields: data, order, externalId.

Delete a row

DELETE /api/v1/sites/{id}/collections/{colId}/rows/{rowId}

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.
rowId (required)pathstring

Fetch a Google Sheet as CSV

POST /api/v1/sites/{id}/collections/sheet-csv

Only for Google Sheets links shared as "Anyone with the link". The server fetches the export (the browser can't) through the SSRF guard, up to 8 MB.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: link.

Read a collection's fields and bindings

GET /api/v1/sites/{id}/collections/{colId}/fields

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.

Export a collection's rows as CSV

GET /api/v1/sites/{id}/collections/{colId}/export.csv

One column per schema field, in row order. Served as a file download.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.

Import rows from CSV

POST /api/v1/sites/{id}/collections/{colId}/import

Send CSV text as a text/csv body or { csv }, or { mediaId } for an uploaded CSV, TSV or XLSX the site's members uploaded. Columns map to schema fields by name. mode: append (default), replace (deletes the rows first), or upsert (matches on externalId or id).

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.
modequeryappend \replace \

JSON body fields: csv, mediaId.

Sync a collection from its source

POST /api/v1/sites/{id}/collections/{colId}/sync

Runs the collection's source sync (the source type must be allowed on the plan). The answer is the sync result.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.

List a collection's recent syncs

GET /api/v1/sites/{id}/collections/{colId}/sync-logs

The last 50 runs, newest first.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.

Whether a collection has source credentials

GET /api/v1/sites/{id}/collections/{colId}/credentials

Answers only a boolean; the secrets are never returned.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.
sourceTypequerystringDefaults to the collection's source type.

Save a collection's source credentials

POST /api/v1/sites/{id}/collections/{colId}/credentials

Owner or agency role.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.
sourceTypequerystringDefaults to the collection's source type.

JSON body fields: secrets, sourceType.

Delete a collection's source credentials

DELETE /api/v1/sites/{id}/collections/{colId}/credentials

Owner or agency role.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.
sourceTypequerystringDefaults to the collection's source type.

List a row's revisions

GET /api/v1/sites/{id}/collections/{colId}/rows/{rowId}/history

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.
rowId (required)pathstringThe row's id.

Restore a row revision

POST /api/v1/sites/{id}/collections/{colId}/rows/{rowId}/history

A normal update seeded from the snapshot, so it validates against the current schema and records a new revision.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.
rowId (required)pathstringThe row's id.

JSON body fields: revisionId.

Connect RSS or Atom feed

POST /api/v1/sites/{id}/apps/rss

Fills a collection with the latest posts from a feed. Checks what was sent with the app (a bad key is a 400 with a message to show as is), makes or reuses the collection it fills, stores secrets encrypted, and runs the first sync. Needs an owner or agency role on the site, and an app the site's plan includes (403 with upgrade: true otherwise). Secrets are never returned.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: url, name.

Connect Notion database

POST /api/v1/sites/{id}/apps/notion

Fills a collection from a Notion database. Checks what was sent with the app (a bad key is a 400 with a message to show as is), makes or reuses the collection it fills, stores secrets encrypted, and runs the first sync. Needs an owner or agency role on the site, and an app the site's plan includes (403 with upgrade: true otherwise). Secrets are never returned.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: token, databaseId, name.

Connect Cal.com open times

POST /api/v1/sites/{id}/apps/calcom

Shows the next open times of one Cal.com event. Checks what was sent with the app (a bad key is a 400 with a message to show as is), makes or reuses the collection it fills, stores secrets encrypted, and runs the first sync. Needs an owner or agency role on the site, and an app the site's plan includes (403 with upgrade: true otherwise). Secrets are never returned.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: apiKey, eventLink, name.

Connect Eventbrite events

POST /api/v1/sites/{id}/apps/eventbrite

Fills a collection with upcoming Eventbrite events. Checks what was sent with the app (a bad key is a 400 with a message to show as is), makes or reuses the collection it fills, stores secrets encrypted, and runs the first sync. Needs an owner or agency role on the site, and an app the site's plan includes (403 with upgrade: true otherwise). Secrets are never returned.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: token, organizationId, name.

Connect Ticket Tailor events

POST /api/v1/sites/{id}/apps/tickettailor

Fills a collection with upcoming Ticket Tailor events. Checks what was sent with the app (a bad key is a 400 with a message to show as is), makes or reuses the collection it fills, stores secrets encrypted, and runs the first sync. Needs an owner or agency role on the site, and an app the site's plan includes (403 with upgrade: true otherwise). Secrets are never returned.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: apiKey, name.

Connect Supabase table

POST /api/v1/sites/{id}/apps/supabase

Fills a collection from a table in a Supabase project's public schema. Checks what was sent with the app (a bad key is a 400 with a message to show as is), makes or reuses the collection it fills, stores secrets encrypted, and runs the first sync. Needs an owner or agency role on the site, and an app the site's plan includes (403 with upgrade: true otherwise). Secrets are never returned.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: projectUrl, table, apiKey, name.

Connect Baserow table

POST /api/v1/sites/{id}/apps/baserow

Fills a collection from a Baserow table. Checks what was sent with the app (a bad key is a 400 with a message to show as is), makes or reuses the collection it fills, stores secrets encrypted, and runs the first sync. Needs an owner or agency role on the site, and an app the site's plan includes (403 with upgrade: true otherwise). Secrets are never returned.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: token, tableId, baseUrl, name.

Connect NocoDB table

POST /api/v1/sites/{id}/apps/nocodb

Fills a collection from a NocoDB table. Checks what was sent with the app (a bad key is a 400 with a message to show as is), makes or reuses the collection it fills, stores secrets encrypted, and runs the first sync. Needs an owner or agency role on the site, and an app the site's plan includes (403 with upgrade: true otherwise). Secrets are never returned.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: token, baseUrl, tableId, name.

Connect Shopify products

POST /api/v1/sites/{id}/apps/shopify

Fills a collection with a Shopify store's products. Checks what was sent with the app (a bad key is a 400 with a message to show as is), makes or reuses the collection it fills, stores secrets encrypted, and runs the first sync. Needs an owner or agency role on the site, and an app the site's plan includes (403 with upgrade: true otherwise). Secrets are never returned.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: shop, token, name.

Connect WooCommerce products

POST /api/v1/sites/{id}/apps/woocommerce

Fills a collection with a WooCommerce store's products. Checks what was sent with the app (a bad key is a 400 with a message to show as is), makes or reuses the collection it fills, stores secrets encrypted, and runs the first sync. Needs an owner or agency role on the site, and an app the site's plan includes (403 with upgrade: true otherwise). Secrets are never returned.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: storeUrl, consumerKey, consumerSecret, name.

Connect Square items

POST /api/v1/sites/{id}/apps/square

Fills a collection with a Square account's items. Checks what was sent with the app (a bad key is a 400 with a message to show as is), makes or reuses the collection it fills, stores secrets encrypted, and runs the first sync. Needs an owner or agency role on the site, and an app the site's plan includes (403 with upgrade: true otherwise). Secrets are never returned.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: token, storeUrl, name.

Connect Gumroad products

POST /api/v1/sites/{id}/apps/gumroad

Fills a collection with a Gumroad account's products. Checks what was sent with the app (a bad key is a 400 with a message to show as is), makes or reuses the collection it fills, stores secrets encrypted, and runs the first sync. Needs an owner or agency role on the site, and an app the site's plan includes (403 with upgrade: true otherwise). Secrets are never returned.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: token, name.

Connect Lemon Squeezy products

POST /api/v1/sites/{id}/apps/lemonsqueezy

Fills a collection with a Lemon Squeezy store's products. Checks what was sent with the app (a bad key is a 400 with a message to show as is), makes or reuses the collection it fills, stores secrets encrypted, and runs the first sync. Needs an owner or agency role on the site, and an app the site's plan includes (403 with upgrade: true otherwise). Secrets are never returned.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: apiKey, storeId, name.

Connect an Airtable table

POST /api/v1/sites/{id}/apps/airtable

Fills a collection from an Airtable table. Reads the table's first records, which checks the token. Checks what was sent with the app (a bad key is a 400 with a message to show as is), makes or reuses the collection it fills, stores secrets encrypted, and runs the first sync. Needs an owner or agency role on the site, on a plan that includes Airtable (Business and up; 403 with upgrade: true otherwise). Secrets are never returned.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: token, base, table, name.

Connect Hospitable

POST /api/v1/sites/{id}/apps/hospitable

Fills the properties collection with the homes in a Hospitable account. Checks what was sent with the app (a bad key is a 400 with a message to show as is), makes or reuses the collection it fills, stores secrets encrypted, and runs the first sync. Needs an owner or agency role on the site, on Pro and up (403 with upgrade: true otherwise). Secrets are never returned.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: token, bookingUrl.

Connect Hostaway

POST /api/v1/sites/{id}/apps/hostaway

Fills the properties collection with the homes in a Hostaway account. Checks what was sent with the app (a bad key is a 400 with a message to show as is), makes or reuses the collection it fills, stores secrets encrypted, and runs the first sync. Needs an owner or agency role on the site, on Pro and up (403 with upgrade: true otherwise). Secrets are never returned.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: accountId, apiKey, bookingUrl.

Connect Guesty

POST /api/v1/sites/{id}/apps/guesty

Fills the properties collection with the homes in a Guesty account. Checks what was sent with the app (a bad key is a 400 with a message to show as is), makes or reuses the collection it fills, stores secrets encrypted, and runs the first sync. Needs an owner or agency role on the site, on Pro and up (403 with upgrade: true otherwise). Secrets are never returned.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: clientId, clientSecret, bookingUrl.

List the calendar links a site reads

GET /api/v1/sites/{id}/apps/calendar-feed

The links themselves are secret and never returned; each entry carries only its host.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
kind (required)queryavailability \events

Connect a calendar link

POST /api/v1/sites/{id}/apps/calendar-feed

Reads the link once, adds it (as a home or a calendar), makes the properties or events collection if the site has none, and runs the first sync. Needs an owner or agency role and Pro or up.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: app, name, url, bookingUrl.

Stop reading a calendar link

DELETE /api/v1/sites/{id}/apps/calendar-feed

Its rows go with it. Answers with the same shape as connecting, listing the links that remain.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
kind (required)queryavailability \events
feedId (required)querystringThe link's id, from the list.

List dates closed in a rental tool

GET /api/v1/sites/{id}/collections/{colId}/booking-pushes

The collection's homes' dates that were closed (or failed to close) in their rental tool, newest first, up to 20.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.

Run a failed date push again

POST /api/v1/sites/{id}/collections/{colId}/booking-pushes

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.

JSON body fields: pushId.

List the calendar links a collection's homes share

GET /api/v1/sites/{id}/collections/{colId}/claim-feeds

Up to 200 homes. path is null until a link is made for the home.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.

Make a home's calendar link

POST /api/v1/sites/{id}/collections/{colId}/claim-feeds

Returns the path of the link other platforms read. With rotate, the link is replaced and the old one stops working.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.

JSON body fields: rowId, rotate.

List the dates taken or closed on a row

GET /api/v1/sites/{id}/collections/{colId}/rows/{rowId}/claims

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.
rowId (required)pathstringThe row's id.

Close dates on a row

POST /api/v1/sites/{id}/collections/{colId}/rows/{rowId}/claims

Closes open dates by hand. Answers 409 when any of them is already taken.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.
rowId (required)pathstringThe row's id.

JSON body fields: field, keys, note.

Reopen dates closed on a row

DELETE /api/v1/sites/{id}/collections/{colId}/rows/{rowId}/claims

A claim tied to an order is refused with 409: unbook the order instead.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
colId (required)pathstringThe collection's id or slug.
rowId (required)pathstringThe row's id.

JSON body fields: claimId.

Releases

Releases built by publishing.

Read a release

GET /api/v1/sites/{id}/releases/{releaseId}

A publish too big to build inside the request answers release.queued; poll the release until status is ready or failed.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
releaseId (required)pathstring

Make a release live again

POST /api/v1/sites/{id}/releases/{releaseId}

Rollback: the undo for a bad publish. Needs permission to publish the site.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
releaseId (required)pathstring

JSON body fields: action.

Media

A site's media library and direct uploads.

Read the media library

GET /api/v1/sites/{id}/media

The site's media items and folders. ?summary=1 returns the library's tab counts and ?usage=1 where each file is used, instead.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
kindqueryOnly images.
summaryquery
usagequery

Upload media: sign, confirm, import a URL, or register items

POST /api/v1/sites/{id}/media

Large files go straight to the CDN in two steps, so the bytes never pass through the API:

  1. { step: "sign", size, contentType, filename? } returns an uploadURL. Send the file there: images as a multipart POST with field formField (file); everything else as a raw PUT whose Content-Type matches contentType exactly.
  2. { step: "confirm", ticket, filename?, width?, height? } finalizes the upload and registers it in the library. Confirm is not optional.

private: true (digital downloads) works only through sign then confirm. Without step: { fileUrl } (or imageUrl) imports a public URL, { dataBase64, mimeType, filename } uploads small bytes inline (a few MB at most), and { items } registers already-uploaded files in the library.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Reorder or move library items

PATCH /api/v1/sites/{id}/media

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: order, move.

List media folders

GET /api/v1/sites/{id}/media/folders

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Replace the media folders

PUT /api/v1/sites/{id}/media/folders

Replaces all folders. Items in a removed folder move to the top level.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: folders.

List the user's unattached files

GET /api/v1/sites/{id}/media/unattached

The signed-in user's stored files that no library lists. An API key gets an empty list. canManage is true for the site's owner, who may add them to the library or delete them.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Update a library file

PATCH /api/v1/sites/{id}/media/{mediaId}

metadata merges key by key; a null value removes a key.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
mediaId (required)pathstringThe file's media id.

JSON body fields: name, order, type, cdnId, metadata.

Remove a file from the library

DELETE /api/v1/sites/{id}/media/{mediaId}

Drops the entry and, for a signed-in caller, deletes the stored file when that is safe. An API key only drops the entry (deleted: false). A file in no library is deleted only by the site's owner, and only when nothing uses it (409 in-use).

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
mediaId (required)pathstringThe file's media id.

Format

The HTML + Liquid authoring reference.

The HTML + Liquid authoring reference

GET /api/v1/format/liquid

Public; no key needed. The tags, filters, objects and lint rules are generated from the renderer's catalogues; the conventions (files, runtime data-* attributes with examples, site JavaScript, forms and form webhooks, dates and timezone, maps) are written by hand and checked against the runtime. The same Markdown is the MCP get_style_reference topic liquid and the /docs/schema page.

Who can call it: Public.

Content

The public headless content API.

List collection items

GET /api/v1/content/{site}/{collection}

ParameterInTypeWhat it is
site (required)pathstringPage id.
collection (required)pathstringCollection slug.
qquerystringFull-text search.
categoryquerystring
sortquerystringe.g. price-asc, newest.
pagequeryinteger
limitqueryinteger
minPricequeryinteger
maxPricequeryinteger
filterquerystringJSON object of equality constraints, e.g. {"brand":"acme"}.
facet.<key>querystringComma-separated facet values, e.g. ?facet.color=red,blue.

Describe a collection's fields + response shape

GET /api/v1/content/{site}/{collection}/schema

ParameterInTypeWhat it is
site (required)pathstring
collection (required)pathstring

Stock

Public stock image and video search.

Search stock images

GET /api/v1/stock-images

Public. Searches the verified stock library; returned images get their uses count bumped.

Who can call it: Public.

ParameterInTypeWhat it is
qquerystringFull-text search.
categoryquerystring
orientationquerystring
sourcequeryunsplash \pexels \
sortquerypopular \newest
pagequeryinteger
limitqueryinteger

Upsert stock images (admin)

POST /api/v1/stock-images

Platform admins only. Each item needs photoId and url; an item without them comes back as a result with an error instead of failing the call.

Who can call it: Platform admin API key.

Search a stock image provider

POST /api/v1/stock-images/search-external

Public. Searches an external provider (Pexels by default) and caches the results in the stock library. A provider that is unavailable or fails answers 200 with an empty list and a note.

Who can call it: Public.

JSON body fields: q, count, orientation, provider.

Search a stock video provider

POST /api/v1/stock-videos/search-external

Public. Like the image search; nothing is cached.

Who can call it: Public.

JSON body fields: q, count, orientation, minDuration, maxDuration, provider.

Blocks

The block library and placing a block into a page.

Browse the block library

GET /api/v1/liquid-blocks

The public library plus the caller's own saved blocks, without their source. Ask the block's route for the ones you use.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
qquerystring
categoryquerystring
stylequerystring
limitqueryinteger

Read one block as Liquid

GET /api/v1/liquid-blocks/{slug}

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
slug (required)pathstringThe block's slug.

Place a library block into a page

POST /api/v1/sites/{id}/blocks

Adds the block's Liquid (with fresh ids) to a page file of the draft as one write. pageId or path picks the page, the home page by default. position is end (default, before the footer) or start; before or after is text that occurs once in the page.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: slug, pageId, path, position, before, after.

Templates

The template catalog.

List templates

GET /api/v1/templates

Public templates; with a key, also the tenant's own (an admin key sees every template). slugs=a,b,c fetches those templates in full and ignores the other filters.

Who can call it: Public; an API key shows more.

ParameterInTypeWhat it is
categoryquerystring
tagquerystring
qquerystringFull-text search.
slugsquerystringComma-separated slugs (up to 100).
previewLimitquerystringTrims how many preview items each template carries.

Create a template

POST /api/v1/templates

A template is its files: send files (and pages), or fromSite to snapshot a site. The thumbnail is captured automatically after the response. Only platform admins publish into the public catalog (isPublic); a tenant's templates stay its own.

Who can call it: API key.

JSON body fields: slug, title, tagline, description, category, tags, hidden, isPublic, sortOrder, files, pages, fromSite.

Read a template

GET /api/v1/templates/{slug}

A private template is visible only to its tenant or an admin. fields=theme answers just the palette and style guide; format=liquid answers the files and page records a site made from the template starts with.

Who can call it: Public; an API key shows more.

ParameterInTypeWhat it is
slug (required)pathstringThe template's slug.
fieldsquery
formatquery

Update a template

PUT /api/v1/templates/{slug}

The tenant's own template, or any for an admin. Send files / pages / fromSite to replace its content (the thumbnail is recaptured). expectedVersion guards against a concurrent edit.

Who can call it: API key.

ParameterInTypeWhat it is
slug (required)pathstringThe template's slug.

JSON body fields: title, tagline, description, category, tags, hidden, sortOrder, expectedVersion, files, pages, fromSite.

Delete a template

DELETE /api/v1/templates/{slug}

Who can call it: API key.

ParameterInTypeWhat it is
slug (required)pathstringThe template's slug.

Audit a template page

GET /api/v1/templates/{slug}/audit

Renders the template's stored page as its preview does, then runs the SEO or accessibility checks on it. A private template is visible only to its tenant or an admin.

Who can call it: Public; an API key shows more.

ParameterInTypeWhat it is
slug (required)pathstringThe template's slug.
kindqueryseo \accessibility
pathquerystringThe page's URL path.

Presets

Curated theme bundles.

List presets

GET /api/v1/presets

Public presets; with a key, also the tenant's own.

Who can call it: Public; an API key shows more.

ParameterInTypeWhat it is
moodquerystringCase-insensitive match on a mood.
limitqueryinteger

Create a preset (admin)

POST /api/v1/presets

Platform admins only: presets are global and public.

Who can call it: Platform admin API key.

JSON body fields: presetId, name, description, mood, palette, styleGuide, fonts, style.

Read a preset

GET /api/v1/presets/{id}

A private preset is visible only to its owner.

Who can call it: Public; an API key shows more.

ParameterInTypeWhat it is
id (required)pathstringThe preset's presetId.

Update a preset

PUT /api/v1/presets/{id}

Only the preset's owner.

Who can call it: API key.

ParameterInTypeWhat it is
id (required)pathstringThe preset's presetId.

JSON body fields: name, description, mood, palette, styleGuide, fonts, style.

Delete a preset

DELETE /api/v1/presets/{id}

Only the preset's owner.

Who can call it: API key.

ParameterInTypeWhat it is
id (required)pathstringThe preset's presetId.

Components library

The shared component library (blocks stored as Liquid).

Search the component library

GET /api/v1/components

Public blocks; with a key, also the caller's own. The Liquid source is left out: read one block for it.

Who can call it: Public; an API key shows more.

ParameterInTypeWhat it is
qquerystringFull-text search.
tagquerystring
featuredquery
sortquerypopular \newest \
pagequeryinteger
limitqueryinteger
categoryquerystringComma-separated for several.
categoriesquerystring
subcategoryquerystring
presetquerystring
sourcequerystring
groupquerystring
stylequerystringComma-separated for several.
stylesquerystring
blockTypequerystring

Add a block to the library

POST /api/v1/components

A block is its Liquid source (sanitized and linted like a site file). Only platform admins can publish one (isPublic) or mark it a category preview.

Who can call it: API key.

JSON body fields: name, slug, description, visual, category, subcategory, tags, preset, group, style, styles, isPublic, isCategoryPreview, source.

List library categories

GET /api/v1/components/categories

Categories with counts, subcategories and styles, for a category-first block picker.

Who can call it: Public; an API key shows more.

Read a block with its Liquid

GET /api/v1/components/{id}

By _id or slug. Bumps the block's uses count.

Who can call it: Public; an API key shows more.

ParameterInTypeWhat it is
id (required)pathstringThe block's _id or slug.

Update a block

PUT /api/v1/components/{id}

Only the block's owner (or an admin). source is sanitized and linted. expectedVersion guards against a concurrent edit. Only an admin can change isPublic, isFeatured or isCategoryPreview.

Who can call it: API key.

ParameterInTypeWhat it is
id (required)pathstringThe block's _id or slug.

JSON body fields: name, slug, description, visual, category, subcategory, tags, preset, group, style, isPublic, isFeatured, isCategoryPreview, expectedVersion, source.

Delete a block

DELETE /api/v1/components/{id}

Only the block's owner (or an admin).

Who can call it: API key.

ParameterInTypeWhat it is
id (required)pathstringThe block's _id or slug.

Like a public block

POST /api/v1/components/{id}/like

Idempotent per caller: the first like counts, repeats answer alreadyLiked.

Who can call it: API key.

ParameterInTypeWhat it is
id (required)pathstringThe block's _id or slug.

Team

Site members and invites.

List members and pending invites

GET /api/v1/sites/{id}/invites

Needs a user key (not a tenant key) with the owner role on the site.

Who can call it: API key.

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Invite someone to the site

POST /api/v1/sites/{id}/invites

Who can call it: API key.

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: email, role.

Revoke a pending invite

DELETE /api/v1/sites/{id}/invites

Who can call it: API key.

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
inviteId (required)querystringThe invite's id.

Domain

A site's custom domain.

Read a site's domain, or preflight one

GET /api/v1/sites/{id}/domain

The attached domain with the DNS records still to create for each variant. check=<domain> preflights a candidate instead; a candidate held by another site answers only available: false.

Who can call it: API key.

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
checkquerystringA domain to preflight.

Attach a domain or change its redirect mode

PATCH /api/v1/sites/{id}/domain

Needs the owner or agency role. Attaching registers both variants of the pair with the host, and the answer carries the DNS records to create; attaching does not publish the site. Repeating the same call is a no-op that reports the DNS state.

Who can call it: API key.

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: domain, domainRedirectMode.

Detach the domain

DELETE /api/v1/sites/{id}/domain

Needs the owner or agency role. detachFailures lists any variant still left on the host project.

Who can call it: API key.

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Chat

The site's chat bot.

Read the site chat bot's settings

GET /api/v1/sites/{id}/chat

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Update the site chat bot's settings

PUT /api/v1/sites/{id}/chat

A partial update; an unknown setting is refused.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: enabled, assistantName, greeting, instructions, leadFields, leadCollectionSlug, notifyEmail, dailyCreditCap.

Emails

The emails a site sends, and the address they come from.

List the site's emails

GET /api/v1/sites/{id}/emails

Every email kind, whether the owner customized it, and whether it is sent today.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Read the look of the site's emails

GET /api/v1/sites/{id}/emails/brand

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Change the look of the site's emails

PUT /api/v1/sites/{id}/emails/brand

Logo on or off and the button colour, on every plan.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: brand.

Read one email

GET /api/v1/sites/{id}/emails/{kind}

The stored design (null = default) with file versions, the defaults, the kind's variables and slots, sample data, and feature.customDesigns (whether the owner's plan saves custom designs).

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
kind (required)pathWhich email.

Save one email

PUT /api/v1/sites/{id}/emails/{kind}

source (the design) needs a plan with custom designs and an HTML-first site; subject and preheader save on every plan. The design is checked before saving; problems come back as errors. base carries the file versions the edit started from.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
kind (required)pathWhich email.

JSON body fields: subject, preheader, source, base.

Reset one email to the default

DELETE /api/v1/sites/{id}/emails/{kind}

Both of the email's files are removed.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
kind (required)pathWhich email.

Preview an unsaved email

POST /api/v1/sites/{id}/emails/{kind}/preview

Renders the draft with sample data. A field the body leaves out uses what is saved. A design with errors renders the default (usedDefault).

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
kind (required)pathWhich email.

JSON body fields: subject, preheader, source.

Send a test of an unsaved email

POST /api/v1/sites/{id}/emails/{kind}/test

Sends the draft, with sample data, to the signed-in user only. Dashboard session only: an API key is refused. Refused while the design has errors.

Who can call it: Dashboard session only (an API key is refused).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
kind (required)pathWhich email.

JSON body fields: subject, preheader, source.

Read the address the site's emails come from

GET /api/v1/sites/{id}/email-sender

How mail goes out now, the saved SMTP settings (password masked), the last error, and what PageHub sending looks like for this site.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Save the site's own mail server

PUT /api/v1/sites/{id}/email-sender

Owner or agency role, on a plan with own sender. Saved unverified: nothing changes until the test succeeds. Without password, the stored one is kept only if host, port and username are unchanged.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: fromName, fromEmail, replyTo, host, port, user, password.

Remove the site's own mail server

DELETE /api/v1/sites/{id}/email-sender

Back to PageHub sending. Open on every plan.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Test the site's mail server

POST /api/v1/sites/{id}/email-sender/test

Connects, logs in, and sends one email to the signed-in user from the owner's address. Success turns the sender on. Dashboard session only; owner or agency role.

Who can call it: Dashboard session only (an API key is refused).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Storefront

Stripe catalog, checkout, orders and file downloads.

Search the Stripe catalog

GET /api/v1/sites/{id}/stripe

Full-catalog tooling (not the visitor storefront). action picks the read: search, categories or product.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
action (required)querysearch \categories \
qquerystringWith search.
categoryquerystringWith search.
limitqueryintegerWith search.
sortquerystringWith search.
idquerystringWith product: the product id.
slugquerystringWith product.

Refresh the products collection from Stripe

POST /api/v1/sites/{id}/stripe

action=refresh syncs the live catalog into the site's products collection.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
action (required)queryRequired.

Read storefront settings

GET /api/v1/sites/{id}/storefront-settings

The switches for the buyer receipt, gift cards, shipping and Stripe Tax, which are all off until turned on.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Update storefront settings

PATCH /api/v1/sites/{id}/storefront-settings

Merges any subset of the keys. Needs the owner or agency role.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: allowPromoCodes, orderEmail, giftCard, shipping, tax, collectEmailConsent.

List checkout configs

GET /api/v1/sites/{id}/checkout

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Point checkout at a collection

POST /api/v1/sites/{id}/checkout

Maps a collection's price field so its rows can be sold. Map a priceId field, or give the collection a numeric price field to sell via price data.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: collectionSlug, provider, fieldMap.

Remove a collection's checkout config

DELETE /api/v1/sites/{id}/checkout

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
collectionSlug (required)querystringThe collection's slug.

List storefront orders

GET /api/v1/sites/{id}/orders

Newest first, read from the site's Stripe account. stripeConnected: false when none is connected. Needs the owner or agency role.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
cursorquerystringThe nextCursor of the previous page (a Checkout Session id).
emailquerystringOnly this buyer.

Mark an order shipped

POST /api/v1/sites/{id}/orders/{orderId}/fulfilment

Also re-saves tracking. The buyer's shipped email goes out after the response, only from the request that applied the change, and only with notifyBuyer.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
orderId (required)pathstringThe order's Stripe Checkout Session id.

JSON body fields: carrier, tracking, notifyBuyer.

Mark an order not shipped

DELETE /api/v1/sites/{id}/orders/{orderId}/fulfilment

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
orderId (required)pathstringThe order's Stripe Checkout Session id.

Refund an order

POST /api/v1/sites/{id}/orders/{orderId}/refund

Refunds through the site's own Stripe account. This moves money. amount is in the smallest currency unit; omit it to refund everything not yet refunded.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
orderId (required)pathstringThe order's Stripe Checkout Session id.

JSON body fields: amount.

List hosted file downloads

GET /api/v1/sites/{id}/downloads

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Publish a download or add a version

POST /api/v1/sites/{id}/downloads

Needs the owner or agency role and a plan that hosts files. Send { mediaId, filename, name?, downloadId?, label?, notes? } to publish or add a version, { downloadId, currentVersionId } to roll back or forward, or { downloadId, name } to rename. Any of these may carry access: { members, plans }; access: null makes it public. The file is a non-image upload by a site member, from private storage or a public one that is moved private here.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: mediaId, filename, name, downloadId, label, notes, currentVersionId, access.

Remove a download or one of its versions

DELETE /api/v1/sites/{id}/downloads

Files no other version uses are deleted too. The current version cannot be removed alone.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
downloadId (required)querystring
versionIdquerystringRemove only this non-current version.

Approve or decline a held order

POST /api/v1/sites/{id}/orders/{orderId}/approval

For an order whose collection's checkout holds the payment. Approving charges the held amount through the site's Stripe account (this moves money) and settles the order like a paid one: stock, customer and receipt. Declining releases the hold and emails the guest. A site without Stripe connected answers 404.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
orderId (required)pathstringThe order's Stripe Checkout Session id.

JSON body fields: approve.

Reopen the dates an order holds

DELETE /api/v1/sites/{id}/orders/{orderId}/booking

Never refunds: refunding is its own call. A site without Stripe connected answers 404.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
orderId (required)pathstringThe order's Stripe Checkout Session id.

List promo codes

GET /api/v1/sites/{id}/promo-codes

The promo codes on the site's own Stripe account, newest first, on and off. Needs the owner or agency role.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Create a promo code

POST /api/v1/sites/{id}/promo-codes

Creates a coupon and a promotion code on the site's own Stripe account. Give percentOff (1 to 99) or amountOff in the smallest currency unit with currency (default usd). On a booking with lodging tax, Stripe takes the same share off every line, so tax is worked out on the price after the code.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: code, percentOff, amountOff, currency, maxRedemptions, expiresAt.

Turn a promo code off or on

PATCH /api/v1/sites/{id}/promo-codes

Redemptions already made stand.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: id, active.

History

A site's revision timeline, what changed in each version, and restoring one to the draft.

List a site's revisions

GET /api/v1/sites/{id}/history

The timeline, newest first: one row per editing session, publish or restore. restorable is false for a version saved before the HTML editor (it can be listed, not diffed or restored). retention is the site owner's plan cap. Needs write access to the site (owner, editor, agency).

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
pagequeryintegerPage number.
pageSizequeryintegerRows per page.

Read one revision, optionally with what changed

GET /api/v1/sites/{id}/history/{revId}

With diff=prev (or another revision's id) the answer groups the changes by page: added, removed, changed and moved elements, with class changes as token sets. Capped at 500 changes (truncated, totalChanges). 409 LEGACY_REVISION for a version saved before the HTML editor.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
revId (required)pathstringA revision's id from the history list.
diffquerystringprev, or the id of the revision to compare against.

Restore a revision into the draft

POST /api/v1/sites/{id}/history/{revId}/restore

Writes the revision's files forward into the DRAFT and records a restore revision, so a restore is itself undoable; the live release is never touched, publish to make it live. A full pre-restore backup is taken first: if it fails the answer is 500 PRE_RESTORE_BACKUP_FAILED and nothing changes. scope: "page" restores one page (needs pageNodeId). Owner, editor and agency; a client or viewer cannot.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
revId (required)pathstringA revision's id from the history list.

JSON body fields: scope, pageNodeId.

Review

Client review comments pinned to a site's preview.

List a site's review comments

GET /api/v1/sites/{id}/review-threads

The client-review threads pinned to the site's preview, newest first, each with its messages (author emails included: you can moderate). The same list the dashboard's Review inbox shows. A signed-in team member's key (owner, editor, agency); a tenant key is refused.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
statusqueryopen \resolved \
pageSlugquerystringA page's slug. Present and empty: the home page. Absent: every page.
summaryquery1Add summary (open, resolved, total, people, lastCommentAt).
pagequeryintegerPage number.
pageSizequeryintegerRows per page.

Reply to a review comment

POST /api/v1/sites/{id}/review-threads/{threadId}

Posts as the key's user (max 5,000 characters, 100 replies per thread), emails the site's other owners and lands in History > Activity, like a reply from the dashboard. Replying does not reopen a resolved thread. A tenant key is refused.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
threadId (required)pathstringA thread's id from the review-threads list.

JSON body fields: body.

Open, resolve or close a review comment

PATCH /api/v1/sites/{id}/review-threads/{threadId}

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
threadId (required)pathstringA thread's id from the review-threads list.

JSON body fields: status.

Forms

A site's form submissions and the webhooks that deliver them.

List a site's form submissions

GET /api/v1/sites/{id}/submissions

The form inbox, newest first, filtered to one state (default open). Each row carries its webhook delivery status when the form has a webhook. formNames and summary ride on the first page. Reading never marks a row read. Visitor details: owner, editor and agency members.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
statequeryopen \done \
formNamequerystringOnly this form.
qquerystringMatches anywhere in the answers.
cursorquerystringnextCursor of the previous page.
limitqueryintegerRows per page.

Read one form submission

GET /api/v1/sites/{id}/submissions/{submissionId}

The answers, how the visitor arrived (attribution), the notes and state changes (activity) and the webhook delivery. Does not mark the row read.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
submissionId (required)pathstringA submission's _id from the list.

Resend a submission's webhook

POST /api/v1/sites/{id}/submissions/{submissionId}/webhook

Resets the attempts and queues the delivery again from the start, to the form's current webhook URL. The submissionId in the payload never changes. Owners only: a delivery carries the lead's details to a third party. 409 when the submission has no webhook; 502 when it could not be queued.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.
submissionId (required)pathstringA submission's _id from the list.

List the form webhook destinations and whether each has a signing secret

GET /api/v1/sites/{id}/form-webhooks

The destinations the forms on the LIVE release post to (URL without its query string), with the forms that use each. A secret is never returned. Owners only.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

Rotate or set a form webhook's signing secret

POST /api/v1/sites/{id}/form-webhooks

rotate mints a new secret and returns it ONCE; set stores the secret the receiver issued (16 to 256 characters, no spaces) and returns nothing. endpoint is the key the list returned: the URL never comes from the caller. Receivers verify X-PageHub-Signature: sha256=<hex HMAC-SHA256 of "<X-PageHub-Timestamp>.<raw body>">. Owners only.

Who can call it: API key (or the dashboard session).

ParameterInTypeWhat it is
id (required)pathstringThe site's id.

JSON body fields: endpoint, action, secret.