Skip to main content
This guide models a blog collection, fills it with items, and covers every day-to-day content operation.

Prerequisites

  • An API key with full_editor access (collections and fields) or content_editor access (items) — see Create an API key
  • A website — see the Quickstart
1

Create a collection with fields

POST /v1/cms/collections creates the collection and its initial fields in one call. Field type is one of the 14 types listed in CMS concepts; reference and multi_reference fields also need targetCollectionId.
Create a posts collection
Response (truncated)
Constraints: collection slugs match ^[a-z][a-z0-9-]{0,63}$, field keys match ^[a-z][a-z0-9_]{0,63}$, display names are 1–200 characters. A website holds at most 100 collections; a collection holds at most 100 fields.Add fields later with POST /v1/cms/collections/{collectionId}/fields (same field shape), and manage them with PATCH /v1/cms/fields/{fieldId} and DELETE /v1/cms/fields/{fieldId}. The patch also renames a field’s key (pass key; stored item data migrates atomically) and reorders it (pass position, plus anchorFieldId for before/after).
2

Create items

POST /v1/cms/collections/{collectionId}/items writes scalar values in data. Asset and reference values go in the images, files, and references maps, keyed by field key. Omit slug and Cactal derives one from title or name.
data is validated strictly against the collection’s fields; unknown keys are rejected. Value limits: plain_text and markdown up to 1,048,576 bytes, multi_reference up to 1,000 targets, gallery up to 25 images. PATCH /v1/cms/items/{itemId} updates an item with the same shape; data merges key-by-key.
3

Publish, schedule, and unpublish items

Items start as drafts with both publication timestamps set to null. Publish immediately:
Publish an item
Or schedule the latest saved item for a future absolute time:
Schedule an item
POST /v1/cms/items/{itemId}/set-published returns the item id, actual publishedAt, and pending publishAt. { "published": true } publishes now, a future { "publishAt": "..." } schedules a draft, and { "published": false } unpublishes or cancels a schedule. Published items must be unpublished before scheduling. Scheduling uses the latest saved content, and Cactal normally promotes it within one minute of the requested time.Only items with publishedAt set render on served websites, including draft previews. Draft and scheduled items stay readable over the API with published=false. You can also create an item already published with a non-future publishedAt, or scheduled with a future publishAt; do not send both.
4

Query items

GET /v1/cms/collections/{collectionId}/items returns { items, nextCursor, nextPage }. Query parameters:Field-key filter operators are eq, neq, in, nin, gt, gte, lt, lte, contains, startsWith, endsWith, and exists. Reference fields additionally accept slug for one-level equality matching, for example {"city":{"slug":"austin"}}. Metadata keys accept only a subset: id and slug take eq, in, and startsWith; publishedAt and publishAt take exists, gt, gte, lt, and lte; createdAt and updatedAt take gt, gte, lt, and lte. Search covers plain_text, markdown, link, email, and color fields.
Filter, search, and sort
Fetch one item with GET /v1/cms/items/find — by itemId, or by collectionId plus slug:
Look up by slug with hydration
You should see the full item shape with cover hydrated into an image object with CDN URLs. A slug with no match returns 404.
List the items that point at this one separately. The endpoint is cursor paginated, so follow nextCursor until it is null before making a complete impact assessment:
List item backreferences
5

Reorder and rename

Items keep a manual order (the default list sort). Both reorders and slug renames go through the same patch:
Move an item to the top
position is before, after, first, or last; before/after also require anchorItemId. The response carries the item id, slug, and its new ordering key.PATCH /v1/cms/items/{itemId} with { "slug": "hello-cactal" } renames the slug; a taken slug returns 409. Collections rename the same way via PATCH /v1/cms/collections/{collectionId} with { "slug": "..." }.
6

Delete and restore

DELETE /v1/cms/items/{itemId} soft-deletes and returns { "deleted": true }. Deleted items leave lists and lookups but remain recoverable:
Restore a deleted item
The response is { "restored": true }; restoring a live item returns 404. DELETE /v1/cms/collections/{collectionId} soft-deletes a whole collection, but is refused with 409 while reference fields in other collections target it.

Troubleshooting

The message names the first failing field, for example Markdown cannot contain raw HTML or Invalid option. Required fields must be present and non-null; date values must be ISO 8601 datetimes with a timezone.
Item slugs are unique per collection, and isUnique fields are unique per collection. Change the value or rename the conflicting item.
Pick one pagination style per request. Cursor pagination is stable under writes; page pagination supports jumping.
plain_text, markdown, reference, asset, and multi-select option fields cannot sort. Sort on number, date, boolean, link, email, color, single option, or a meta field.

Next steps