Use Forumulate as your website's CMS

Embed
Preview of the card
<a href="https://forumulate.com/guides/headless-cms"><img src="https://forumulate.com/guides/_api/public/orgs/046a9bc0-d530-43ae-9bae-af7945008cda/spaces/36aa4df0-1e95-4cef-8ae9-795169441345/pages/a436b86a-f098-4735-bcea-1601da47f3da/social-card.svg?v=3e7ae33eec8b" alt="Use Forumulate as your website's CMS" width="600" height="315"></a>

Your marketing site is your own code — Next.js, Astro, Nuxt, SvelteKit, anything that can make an HTTP request. Forumulate holds its content: the pages, posts, menus, settings and pictures your marketing team edits without a developer, and that your site reads at build time or on each request.

This page covers the concepts, the keys, and the delivery API. Build a Next.js site on a content library takes you from an empty folder to a deployed site whose pages, menus and settings all come from Forumulate, with edits live within seconds.

The concepts

Content libraries

A content library belongs to your organization, like Media and Forms. An organization can have several — usually one per website. A library holds:

  • its model: the collections and globals, their fields, and the block types pages are built from;

  • the entries themselves, with drafts, review, scheduling, history and translations;

  • its keys (delivery and preview), webhooks and preview URLs;

  • who may edit it: content capabilities at the organization reach every library, and a per-library grant gives somebody one website's library only.

Find it under Content in the console. A library you cannot read does not exist as far as you are concerned: every route answers 404 for it.

Start one from the Website template and it comes with a whole site's model, ready to fill in:

POST /orgs/{orgId}/content/libraries
{ "name": "Marketing site", "template": "website" }

The answer's library.id is the id every other call uses. The template creates no entries — the words on your website are yours.

Collections and globals

The console calls them Collections and Globals; the API calls both content types (GET …/types lists them, each with singleton: true for a global).

  • A collection has many entries: pages, posts, team members, case studies, menus. Each entry has a title, a slug and its fields.

  • A global has exactly one entry (per locale): the site settings, the header, the footer, the interface strings. You read it by its key.

The Website template declares:

Content type

Kind

What it is

page

Collection

A page built from blocks: hero, text, features, cta, image. Has seo.

post

Collection

A dated article: publishedAt, author, excerpt, cover, body (rich text), seo.

route

Collection

A path on your site (/pricing) and the page or post it shows. One route, one path.

menu

Collection

A navigation menu (main, footer): items, each with a label, a link and children.

site

Global

Name, logo, favicon, social links, default SEO, analytics ids, the announcement bar.

header

Global

The menu at the top and the button beside it.

footer

Global

The footer menu, small print and copyright.

strings

Global

Short interface copy (button labels, messages), translated per locale.

These are ordinary content types. Rename a field, add a block type or a whole new collection, and the change sits on top of the template rather than replacing it.

Routes: the site map is content too

A route says which entry lives at which path. A marketer adds a page by creating the page, creating a route for it and publishing both — your site looks the path up and renders whatever is there, with no code change and no deploy. Paths are unique, normalised (/pricing, never pricing/), and a route can be disabled without losing its history.

Links inside content (menu items, buttons) point at the entry, not at its path, so moving a page to a new path keeps every link to it working. When a routed entry's path changes, a redirect from the old path is recorded automatically.

Keys

Your site reads a library with a key. Keys are made per library, in Content → Keys, or with the API (content.keys capability; a token creating one needs the admin scope):

POST /orgs/{orgId}/content/libraries/{libraryId}/keys
{ "name": "marketing site (server)", "kind": "delivery" }
{
  "key": { "id": "…", "kind": "delivery", "prefix": "cfd_", "origins": null, "contentTypes": null, "locales": null },
  "secret": "cfd_…" // shown once, stored hashed
}

Kind

Prefix

Reads

Where it may live

delivery

cfd_

Published content

Your server only. Never in a browser bundle.

publishable

cfp_

Published content, only from the origins you list

Page source is fine — that is what it is for.

preview

cfv_

Drafts and scheduled content, and preview-only fields

Your server only.

  • Every key works only on the delivery API. A delivery key sent to a management route is refused, so a key that leaks can read your published content and nothing else.

  • Narrow a key with contentTypes and locales; omitted means all of them. A publishable key requires origins.

  • expiresInDays makes a key expire on its own.

  • Rotate with POST …/keys/{keyId}/rotate: you get a new secret, and the old one keeps working for graceMinutes (default 60) so you can redeploy without downtime. 0 retires it at once — for a key that leaked.

  • Revoke with DELETE …/keys/{keyId}. The next request with it is a 401.

  • cfd_ and cfv_ are registered with GitHub secret scanning. Commit one to a public repository and it is revoked: a preview key at once, a delivery key after 24 hours, so you can rotate it without your site going dark. cfp_ is not registered, because it is public by design.

Preview sessions

A preview key reads every draft for as long as it lives. To show an editor a draft on your site you do not need one: a preview session does it with nothing standing.

  1. The editor presses Preview on the entry's card in the studio (Content → the entry → Status). The studio mints a token with the editor's own session (content.read on the library), bound to that library, that entry and the path the entry renders at — the path of a route pointing at it, else its collection's previewUrl. The token is single-use and valid for ten minutes. An entry with no page on the site has the button disabled, saying so.

  2. The studio POSTs the token as a form field, with the path, to your site's preview route on the library's first preview origin — never in a URL. The route is /api/preview unless you set another under Settings → Delivery → Preview route (settings.preview.route).

  3. Your server exchanges it at POST /delivery/v1/preview/exchange with { "token", "path", "library" } and gets { "credential": "cfvs_…", "expiresAt", "libraryId" }: a delivery bearer that reads that library's drafts for one hour. Keep it in an httpOnly cookie, never in page script.

Scripts and other tools can mint a token the same way the studio does: POST /orgs/{orgId}/content/libraries/{libraryId}/preview/sessions with { "entryId": "…", "path": "/pricing" } answers { "session": { "token": "cfvt_…", "expiresAt": "…", "libraryId", "entryId", "path" } }.

A second use of the token, a different path, another library or an expired token is a 401 with the same message whichever it was. The credential reads as the editor who minted it, re-checked on every request, so removing them from the library ends their previews at once. It works on the /libraries/{libraryId}/… delivery routes only, never the shared-cache /k/ form. Preview sessions need the content.preview plan feature.

The framework helpers implement the site's half — createPreviewRoute and createExitPreviewRoute for Next (draft mode), Astro, Nuxt and SvelteKit: POST only, relative paths only, and an HttpOnly; Secure; SameSite=None; Partitioned cookie so the preview still works inside the studio's frame. See Preview in the Next.js guide.

Developing against localhost. The console only frames your site's preview origins. To preview a site running on your machine, turn on Allow localhost in the library's preview settings (settings.preview.allowLoopback); it lets that library's studio frame http://localhost:* and http://127.0.0.1:*, and nothing else. Turn it off when the site goes live.

The key list shows each key's last use and request counts (updated about once a minute). Secrets are never listed.

The delivery API

Every route lives under:

https://forumulate.com/api/delivery/v1/libraries/{libraryId}/…

with the key in the Authorization header:

curl -H "Authorization: Bearer $FORUMULATE_DELIVERY_KEY" \
     -A 'my-site/1.0' \
     "https://forumulate.com/api/delivery/v1/libraries/$LIBRARY/routes/resolve?path=/pricing"

Use the library id rather than its slug: cache tags and webhooks carry ids, so a site that reads by slug cannot be revalidated by tag. Set a non-default User-Agent, as for every API call.

Route

What it answers

GET /types

The model as your key may read it: each type's key, label, singleton, routable and fields.

GET /types/{type}/entries

A list of a collection's entries.

POST /types/{type}/entries/query

The same, with the query in the body (for a where too long for a URL).

GET /types/{type}/entries/{idOrSlug}

One entry.

GET /globals/{key}

A global (site, header, …).

GET /routes

Every live path and the entry it shows — for prerendering and sitemaps.

GET /routes/resolve?path=

What lives at a path: the entry, a redirect to follow, or 404.

GET /redirects

The redirect table, for next.config.js or a middleware.

GET /sitemap.json

Routed paths with their last change.

GET /search?q=

Full-text search over the fields a type marks searchable.

GET /schema.json, GET /openapi.json

JSON Schema and an OpenAPI document of your model, typed per content type.

One entry

{
  "id": "6f1c…",
  "type": "post",
  "slug": "launch",
  "title": "Introducing Brightfield",
  "locale": "en",
  "status": "published",
  "publishedAt": "2026-09-02T09:00:00.000Z",
  "updatedAt": "2026-09-02T09:00:00.000Z",
  "fields": { "author": "Maya Okafor", "excerpt": "…", "body": { "type": "doc", "content": [] } },
  "route": "/blog/launch", // its path, when a route points at it
  "locales": ["en", "es"],
  "_links": { "self": "/delivery/v1/libraries/…/types/post/entries/6f1c…" }
}

Fields marked internal never appear; fields marked preview-only appear for preview keys only.

Lists, filters and paging

GET …/types/post/entries?where[author][equals]=Maya%20Okafor&sort=-publishedAt&limit=10
  • where: {field: {operator: value}}, with and / or arrays, as query brackets or a JSON string. Operators: equals, not_equals, in, not_in, contains, like, exists, gt, gte, lt, lte, near. Dot paths reach into groups (hero.heading), [] into rows, and author.name into references (with depth).

  • sort: -publishedAt,title.

  • select: title,hero.heading — only these fields.

  • locale and fallback=true for untranslated fields.

  • Cursor paging only. limit (up to 100) and cursor. Every list answers { data, page: { limit, hasMore, nextCursor } }: walk nextCursor while hasMore. Add count=true for page.total where it is cheap to count. There is no page number or offset.

A filter on a field that is not indexed, over a large collection, is a 422 naming the field — mark it indexed in the model, rather than have the query slow down as the collection grows. Every malformed parameter is a 422 that names the parameter.

References

depth (0–3, capped by your plan) populates references in place: a menu's links, a post's author, a page's button target. Each populated entry has the same shape as above, including its route. Past depth, a reference is a stub: { kind, id, contentType, slug, title }. A reference to something that cannot be served — unpublished, deleted, a type your key cannot read — is null. Your site never receives an id it cannot fetch. populate[author]=name,avatar projects what a populated type brings.

Pictures

A media field is served as { url, width, height, alt, caption, focal, variants }. variants maps widths to pre-sized URLs, so a srcset needs no image service of yours. @forumulate/blocks-react's <FmImage> writes it for you.

The SDKs

You rarely call these routes by hand:

  • @forumulate/embed/content — createContentClient({ library, key }): getEntries, getEntry, getGlobal, resolveRoute, query, cursor helpers, typed where, image helpers. Works wherever fetch does.

  • @forumulate/next/content — the same reads tagged for Next's cache, draft-mode aware, plus createRevalidateHandler and the preview routes.

  • @forumulate/blocks-react — <Content> renders any entry of any type from its fields, <RichText>, <FmImage>; override any block or field with your own component.

  • Astro, Nuxt and SvelteKit have receivers and catch-all helpers of their own; see SDKs and integrations.

Hosted output

A library can also be published without a front end of your own. Turn on its hosted output with PATCH /orgs/{orgId}/content/libraries/{libraryId} and { "settings": { "hostedOutput": { "enabled": true } } }. Turning it on needs the plan's content.hostedOutput feature (Starter and up), and a downgrade takes the hosted site dark again. While it is on, the platform renders the library's published, routed entries under the /h/ reader prefix, or at a custom domain you add to the library.

The reads behind that reader are public, and serve only published routed entries (never drafts or internal fields):

  • GET /public/content/{orgId}/libraries/{libraryId}/hosted/resolve?path=/de/pricing answers the page shown at a path, a language prefix included, or the redirect to follow.

  • GET /public/content/{orgId}/libraries/{libraryId}/hosted/sitemap lists the routed, indexable paths with their last change and locale alternates.

Both answer 404 while hosted output is off or the plan no longer has it, the same 404 as a library that does not exist.

Next

In the API

Every operation below is also reachable from the other surfaces without a dedicated command. forumulate api <Operation> calls it from the CLI, the JavaScript SDK has a typed method for each one (the last column names it; the Python and Go clients are generated from the same spec), and an agent reaches the organization-scoped ones through the MCP call_api tool. Where a CLI command or MCP tool exists too, the last column names it. Operation names link to the API reference.

Content Library

Operation

Request

What it does

Shortcuts

ContentLibrary_list

GET /orgs/{orgId}/content/libraries

List libraries in an organization

forumulate libraries list<br>client.content.libraries.list()<br>MCP list_content_libraries

ContentLibrary_create

POST /orgs/{orgId}/content/libraries

Create a library in an organization

forumulate libraries create<br>client.content.libraries.create()

ContentLibrary_get

GET /orgs/{orgId}/content/libraries/{libraryId}

Get the library

forumulate libraries get<br>client.content.libraries.get()

ContentLibrary_update

PATCH /orgs/{orgId}/content/libraries/{libraryId}

Update the library

forumulate libraries update<br>client.content.libraries.update()

ContentLibrary_remove

DELETE /orgs/{orgId}/content/libraries/{libraryId}

Delete the library

forumulate libraries delete<br>client.content.libraries.remove()

ContentLibrary_listMembers

GET /orgs/{orgId}/content/libraries/{libraryId}/members

List members in an organization (content libraries)

forumulate libraries members list<br>client.content.libraries.listMembers()<br>client.content.members.list()

ContentLibrary_putMember

POST /orgs/{orgId}/content/libraries/{libraryId}/members

Create a member in an organization (content libraries)

forumulate libraries members add<br>client.content.libraries.putMember()<br>client.content.members.put()

ContentLibrary_removeMember

DELETE /orgs/{orgId}/content/libraries/{libraryId}/members/{userId}

Delete the member (content libraries)

forumulate libraries members remove<br>client.content.libraries.removeMember()<br>client.content.members.remove()

Content Model

Operation

Request

What it does

Shortcuts

ContentModel_get

GET /orgs/{orgId}/content/libraries/{libraryId}/model

Get the model in an organization

forumulate libraries model get<br>client.content.model.get()<br>MCP list_content_types<br>MCP get_content_type_schema<br>MCP create_block_type

ContentModel_put

PUT /orgs/{orgId}/content/libraries/{libraryId}/model

Replace the library's content model

forumulate libraries model put<br>client.content.model.put()<br>client.content.model.save()<br>MCP create_block_type

ContentModel_versions

GET /orgs/{orgId}/content/libraries/{libraryId}/model/versions

List versions in an organization (content libraries model)

forumulate libraries model versions<br>client.content.model.versions()

Content Studio

Operation

Request

What it does

Shortcuts

ContentStudio_types

GET /orgs/{orgId}/content/libraries/{libraryId}/types

Read the library's content types, resolved

forumulate entries types<br>client.content.studio.types()

ContentStudio_list

GET /orgs/{orgId}/content/libraries/{libraryId}/types/{type}/entries

List a content type’s entries for the studio

forumulate entries list<br>client.content.studio.list()<br>MCP query_entries

ContentStudio_runBulk

POST /orgs/{orgId}/content/libraries/{libraryId}/entries/bulk

Publish, unpublish, delete or copy many entries

forumulate entries bulk<br>client.content.studio.runBulk()

Content Workflow

Operation

Request

What it does

Shortcuts

ContentWorkflow_settings

GET /orgs/{orgId}/content/libraries/{libraryId}/workflow

Get the workflow in an organization

client.content.workflow.settings()

ContentWorkflow_putSettings

PUT /orgs/{orgId}/content/libraries/{libraryId}/workflow

Replace the workflow in an organization

client.content.workflow.putSettings()

ContentWorkflow_list

GET /orgs/{orgId}/content/libraries/{libraryId}/change-requests

List change requests in an organization

client.content.workflow.list()

ContentWorkflow_create

POST /orgs/{orgId}/content/libraries/{libraryId}/change-requests

Create a change request in an organization

client.content.workflow.create()

ContentWorkflow_get

GET /orgs/{orgId}/content/libraries/{libraryId}/change-requests/{crId}

Get the change request (content libraries)

client.content.workflow.get()

ContentWorkflow_update

PATCH /orgs/{orgId}/content/libraries/{libraryId}/change-requests/{crId}

Update the change request

client.content.workflow.update()

ContentWorkflow_transition

POST /orgs/{orgId}/content/libraries/{libraryId}/change-requests/{crId}/transition

Create the transition in an organization

client.content.workflow.transition()

Delivery Entries

Operation

Request

What it does

Shortcuts

DeliveryEntries_types[0]

GET /delivery/v1/libraries/{libraryId}/types

List the content types (libraries)

client.delivery.entries['types[0]']()

DeliveryEntries_types[1]

GET /delivery/v1/k/{keyId}/types

List the content types (k)

client.delivery.entries['types[1]']()

DeliveryEntries_list[0]

GET /delivery/v1/libraries/{libraryId}/types/{type}/entries

List entries of a content type (libraries)

client.delivery.entries['list[0]']()

DeliveryEntries_list[1]

GET /delivery/v1/k/{keyId}/types/{type}/entries

List entries of a content type (k)

client.delivery.entries['list[1]']()

DeliveryEntries_query[0]

POST /delivery/v1/libraries/{libraryId}/types/{type}/entries/query

Query entries of a content type (libraries)

client.delivery.entries['query[0]']()

DeliveryEntries_query[1]

POST /delivery/v1/k/{keyId}/types/{type}/entries/query

Query entries of a content type (k)

client.delivery.entries['query[1]']()

DeliveryEntries_one[0]

GET /delivery/v1/libraries/{libraryId}/types/{type}/entries/{idOrSlug}

Read one entry (libraries)

client.delivery.entries['one[0]']()

DeliveryEntries_one[1]

GET /delivery/v1/k/{keyId}/types/{type}/entries/{idOrSlug}

Read one entry (k)

client.delivery.entries['one[1]']()

DeliveryEntries_resolve

POST /delivery/v1/libraries/{libraryId}/types/{type}/entries/{id}/resolve

Resolve an unsaved draft

client.delivery.entries.resolve()

DeliveryEntries_global[0]

GET /delivery/v1/libraries/{libraryId}/globals/{key}

Read a global (libraries)

client.delivery.entries['global[0]']()

DeliveryEntries_global[1]

GET /delivery/v1/k/{keyId}/globals/{key}

Read a global (k)

client.delivery.entries['global[1]']()

DeliveryEntries_schema[0]

GET /delivery/v1/libraries/{libraryId}/schema.json

Read the library’s JSON Schema (libraries)

client.delivery.entries['schema[0]']()

DeliveryEntries_schema[1]

GET /delivery/v1/k/{keyId}/schema.json

Read the library’s JSON Schema (k)

client.delivery.entries['schema[1]']()

DeliveryEntries_openapi[0]

GET /delivery/v1/libraries/{libraryId}/openapi.json

Read the library’s OpenAPI document (libraries)

client.delivery.entries['openapi[0]']()

DeliveryEntries_openapi[1]

GET /delivery/v1/k/{keyId}/openapi.json

Read the library’s OpenAPI document (k)

client.delivery.entries['openapi[1]']()

Delivery Key

Operation

Request

What it does

Shortcuts

DeliveryKey_key

GET /delivery/v1/libraries/{libraryId}/key

Describe the calling delivery key

client.delivery.key.key()

DeliveryKey_keyByKeyId

GET /delivery/v1/k/{keyId}/key

Describe the calling publishable key by its id

client.delivery.key.keyByKeyId()

Delivery Keys

Operation

Request

What it does

Shortcuts

DeliveryKeys_list

GET /orgs/{orgId}/content/libraries/{libraryId}/keys

List a content library’s delivery keys

forumulate libraries keys list<br>client.content.keys.list()

DeliveryKeys_create

POST /orgs/{orgId}/content/libraries/{libraryId}/keys

Create a delivery key for a content library

forumulate libraries keys create<br>client.content.keys.create()

DeliveryKeys_update

PATCH /orgs/{orgId}/content/libraries/{libraryId}/keys/{keyId}

Update a delivery key

forumulate libraries keys update<br>client.content.keys.update()

DeliveryKeys_revoke

DELETE /orgs/{orgId}/content/libraries/{libraryId}/keys/{keyId}

Revoke a delivery key

forumulate libraries keys revoke<br>client.content.keys.revoke()

DeliveryKeys_rotate

POST /orgs/{orgId}/content/libraries/{libraryId}/keys/{keyId}/rotate

Rotate a delivery key

forumulate libraries keys rotate<br>client.content.keys.rotate()

Delivery Site

Operation

Request

What it does

Shortcuts

DeliverySite_routes[0]

GET /delivery/v1/libraries/{libraryId}/routes

List routes (libraries)

client.delivery.site['routes[0]']()

DeliverySite_routes[1]

GET /delivery/v1/k/{keyId}/routes

List routes (k)

client.delivery.site['routes[1]']()

DeliverySite_resolve[0]

GET /delivery/v1/libraries/{libraryId}/routes/resolve

Resolve a site path (libraries)

client.delivery.site['resolve[0]']()

DeliverySite_resolve[1]

GET /delivery/v1/k/{keyId}/routes/resolve

Resolve a site path (k)

client.delivery.site['resolve[1]']()

DeliverySite_redirects[0]

GET /delivery/v1/libraries/{libraryId}/redirects

List redirects (libraries)

client.delivery.site['redirects[0]']()

DeliverySite_redirects[1]

GET /delivery/v1/k/{keyId}/redirects

List redirects (k)

client.delivery.site['redirects[1]']()

DeliverySite_sitemap[0]

GET /delivery/v1/libraries/{libraryId}/sitemap.json

Read the sitemap (libraries)

client.delivery.site['sitemap[0]']()

DeliverySite_sitemap[1]

GET /delivery/v1/k/{keyId}/sitemap.json

Read the sitemap (k)

client.delivery.site['sitemap[1]']()

DeliverySite_search[0]

GET /delivery/v1/libraries/{libraryId}/search

Search entries (libraries)

client.delivery.site['search[0]']()

DeliverySite_search[1]

GET /delivery/v1/k/{keyId}/search

Search entries (k)

client.delivery.site['search[1]']()

Entry Card

Operation

Request

What it does

Shortcuts

EntryCard_overview

GET /orgs/{orgId}/content/libraries/{libraryId}/entries/{entryId}

Read an entry's status, schedule and locales

client.content.entries.overview()

EntryCard_unpublish

POST /orgs/{orgId}/content/libraries/{libraryId}/entries/{entryId}/unpublish

Unpublish an entry

client.content.entries.unpublish()

EntryCard_getSchedule

GET /orgs/{orgId}/content/libraries/{libraryId}/entries/{entryId}/schedule

Get the schedule in an organization (content libraries entries)

client.content.entries.getSchedule()

EntryCard_schedule

POST /orgs/{orgId}/content/libraries/{libraryId}/entries/{entryId}/schedule

Schedule an entry to publish

client.content.entries.schedule()

EntryCard_cancelSchedule

DELETE /orgs/{orgId}/content/libraries/{libraryId}/entries/{entryId}/schedule

Delete the schedule in an organization

client.content.entries.cancelSchedule()

EntryCard_revisions

GET /orgs/{orgId}/content/libraries/{libraryId}/entries/{entryId}/revisions

List an entry's revisions

client.content.entries.revisions()

EntryCard_revision

GET /orgs/{orgId}/content/libraries/{libraryId}/entries/{entryId}/revisions/{revisionId}

Read one revision's field values

client.content.entries.revision()

EntryCard_restore

POST /orgs/{orgId}/content/libraries/{libraryId}/entries/{entryId}/revisions/{revisionId}/restore

Restore a revision

client.content.entries.restore()

EntryCard_translate

POST /orgs/{orgId}/content/libraries/{libraryId}/entries/{entryId}/translations

Start a translation of an entry

client.content.entries.translate()

Entry Delivery Preview

Operation

Request

What it does

Shortcuts

EntryDeliveryPreview_preview

GET /orgs/{orgId}/content/libraries/{libraryId}/entries/{entryId}/delivery

Preview what delivery serves for an entry

client.content.entryDeliveryPreview.preview()

EntryDeliveryPreview_resolve

POST /orgs/{orgId}/content/libraries/{libraryId}/entries/{entryId}/resolve

Resolve an entry’s unsaved draft for live preview

client.content.entryDeliveryPreview.resolve()

Entry Fields

Operation

Request

What it does

Shortcuts

EntryFields_read

GET /orgs/{orgId}/content/libraries/{libraryId}/entries/{entryId}/fields

List fields in an organization (entries)

forumulate entries values<br>client.content.entryFields.read()<br>MCP create_entry<br>MCP get_entry

EntryFields_patch

PATCH /orgs/{orgId}/content/libraries/{libraryId}/entries/{entryId}/fields

Update fields in an organization (entries)

forumulate entries patch<br>client.content.entryFields.patch()<br>MCP patch_entry_fields

EntryFields_lock

GET /orgs/{orgId}/content/libraries/{libraryId}/entries/{entryId}/lock

Lock the entry

forumulate entries lock<br>client.content.entryFields.lock()

EntryFields_takeLock

POST /orgs/{orgId}/content/libraries/{libraryId}/entries/{entryId}/lock

Lock the entry (create)

forumulate entries lock take<br>client.content.entryFields.takeLock()

EntryFields_releaseLock

DELETE /orgs/{orgId}/content/libraries/{libraryId}/entries/{entryId}/lock

Lock the entry (delete)

forumulate entries lock release<br>client.content.entryFields.releaseLock()

EntryFields_heartbeat

POST /orgs/{orgId}/content/libraries/{libraryId}/entries/{entryId}/lock/heartbeat

Create the heartbeat in an organization (content libraries entries lock)

forumulate entries lock renew<br>client.content.entryFields.heartbeat()

Entry Usage

Operation

Request

What it does

Shortcuts

EntryUsage_usedIn

GET /orgs/{orgId}/content/libraries/{libraryId}/items/{itemId}/used-in

List the entries that reference an entry

client.content.entryUsage.usedIn()

Environments

Operation

Request

What it does

Shortcuts

Environments_list

GET /orgs/{orgId}/content/libraries/{libraryId}/environments

List a library's sandboxes

forumulate environments list<br>client.content.environments.list()

Environments_fork

POST /orgs/{orgId}/content/libraries/{libraryId}/environments

Fork a library into a sandbox

forumulate environments fork<br>client.content.environments.fork()

Environments_compare

GET /orgs/{orgId}/content/libraries/{libraryId}/environment/compare

Compare a sandbox’s model with its source

forumulate environments compare<br>client.content.environments.compare()

Environments_promote

POST /orgs/{orgId}/content/libraries/{libraryId}/environment/promote

Promote a sandbox’s model into its source

forumulate environments promote<br>client.content.environments.promote()

Library Asset

Operation

Request

What it does

Shortcuts

LibraryAsset_list

GET /orgs/{orgId}/content/libraries/{libraryId}/asset-candidates

List the assets a library’s media fields can use

client.content.assetCandidates.list()

Library Item

Operation

Request

What it does

Shortcuts

LibraryItem_create

POST /orgs/{orgId}/content/libraries/{libraryId}/items

Create an item in an organization

forumulate entries create<br>client.content.items.create()<br>client.content.entries.create()<br>MCP create_entry<br>MCP create_route

LibraryItem_lookup

POST /orgs/{orgId}/content/libraries/{libraryId}/items/lookup

Create the lookup in an organization

forumulate entries lookup<br>client.content.items.lookup()<br>client.content.entries.lookup()

LibraryItem_read

GET /orgs/{orgId}/content/libraries/{libraryId}/items/{itemId}

Get the item (content libraries)

forumulate entries get<br>client.content.items.read()<br>client.content.entries.read()

LibraryItem_patch

PATCH /orgs/{orgId}/content/libraries/{libraryId}/items/{itemId}

Update the item (content libraries)

forumulate entries update<br>client.content.items.patch()<br>client.content.entries.update()

LibraryItem_remove

DELETE /orgs/{orgId}/content/libraries/{libraryId}/items/{itemId}

Delete the item (content libraries)

forumulate entries delete<br>client.content.items.remove()

LibraryItem_fields

GET /orgs/{orgId}/content/libraries/{libraryId}/items/{itemId}/fields

List fields in an organization (items)

forumulate entries fields<br>client.content.items.fields()

LibraryItem_setFields

PATCH /orgs/{orgId}/content/libraries/{libraryId}/items/{itemId}/fields

Update fields in an organization (items)

forumulate entries fields set<br>client.content.items.setFields()<br>client.content.entries.setFields()

LibraryItem_publish

POST /orgs/{orgId}/content/libraries/{libraryId}/items/{itemId}/publish

Publish the item (content libraries)

forumulate entries publish<br>client.content.items.publish()<br>client.content.entries.publish()<br>MCP publish_entry

LibraryItem_trash

GET /orgs/{orgId}/content/libraries/{libraryId}/trash

List trash libraries in an organization

forumulate entries trash<br>client.content.items.trash()

LibraryItem_restore

POST /orgs/{orgId}/content/libraries/{libraryId}/trash/{itemId}/restore

Restore the trash

forumulate entries restore<br>client.content.items.restore()

Library Media

Operation

Request

What it does

Shortcuts

LibraryMedia_list

GET /orgs/{orgId}/content/libraries/{libraryId}/assets

List a content library’s media

forumulate media list<br>client.content.assets.list()

LibraryMedia_upload

POST /orgs/{orgId}/content/libraries/{libraryId}/assets

Upload a file to a content library

forumulate media upload<br>client.content.assets.upload()

LibraryMedia_bulkUpdate

PATCH /orgs/{orgId}/content/libraries/{libraryId}/assets

Update many of a content library’s assets at once

forumulate media bulk update<br>client.content.assets.bulkUpdate()

LibraryMedia_suggestAltText

POST /orgs/{orgId}/content/libraries/{libraryId}/assets/alt-text

Suggest alt text for a content library’s pictures

forumulate media alt-text<br>client.content.assets.suggestAltText()

LibraryMedia_update

PATCH /orgs/{orgId}/content/libraries/{libraryId}/assets/{assetId}

Update one content library asset

forumulate media update<br>client.content.assets.update()

LibraryMedia_remove

DELETE /orgs/{orgId}/content/libraries/{libraryId}/assets/{assetId}

Delete a content library asset

forumulate media delete<br>client.content.assets.remove()

LibraryMedia_usedIn

GET /orgs/{orgId}/content/libraries/{libraryId}/assets/{assetId}/used-in

List the entries that use a content library asset

forumulate media used-in<br>client.content.assets.usedIn()

Library Usage

Operation

Request

What it does

Shortcuts

LibraryUsage_read

GET /orgs/{orgId}/content/libraries/{libraryId}/usage

Read a library's usage against its plan

client.content.usage.read()

Model Io

Operation

Request

What it does

Shortcuts

ModelIo_export

GET /orgs/{orgId}/content/libraries/{libraryId}/model/export

Download the content model as a file

client.content.modelIo.export()<br>client.content.model.export()

ModelIo_import

POST /orgs/{orgId}/content/libraries/{libraryId}/model/import

Push a content model file (diff, dry run, apply)

client.content.modelIo.import()<br>client.content.model.import()

ModelIo_schema

GET /orgs/{orgId}/content/libraries/{libraryId}/model/schema.json

The library's delivery JSON Schema

client.content.modelIo.schema()<br>client.content.model.schema()

Preview Status

Operation

Request

What it does

Shortcuts

PreviewStatus_status

GET /orgs/{orgId}/content/libraries/{libraryId}/preview

Read a content library’s preview readiness

client.content.previewStatus.status()

Reference Candidates

Operation

Request

What it does

Shortcuts

ReferenceCandidates_search

GET /orgs/{orgId}/content/libraries/{libraryId}/reference-candidates

Search what a reference field can point at

client.content.referenceCandidates.search()

Releases

Operation

Request

What it does

Shortcuts

Releases_list

GET /orgs/{orgId}/content/releases

List releases

forumulate releases list<br>client.content.releases.list()

Releases_create

POST /orgs/{orgId}/content/releases

Create a release

forumulate releases create<br>client.content.releases.create()

Releases_candidates

GET /orgs/{orgId}/content/releases/candidates

Find drafts to add to a release

forumulate releases candidates<br>client.content.releases.candidates()

Releases_get

GET /orgs/{orgId}/content/releases/{releaseId}

Get a release

forumulate releases get<br>client.content.releases.get()

Releases_update

PATCH /orgs/{orgId}/content/releases/{releaseId}

Rename a release

forumulate releases rename<br>client.content.releases.update()

Releases_remove

DELETE /orgs/{orgId}/content/releases/{releaseId}

Delete a release

forumulate releases delete<br>client.content.releases.remove()

Releases_addItem

POST /orgs/{orgId}/content/releases/{releaseId}/items

Add a draft to a release

forumulate releases add<br>client.content.releases.addItem()

Releases_removeItem

DELETE /orgs/{orgId}/content/releases/{releaseId}/items/{itemId}

Remove an item from a release

forumulate releases remove<br>client.content.releases.removeItem()

Releases_schedule

POST /orgs/{orgId}/content/releases/{releaseId}/schedule

Schedule a release

forumulate releases schedule<br>client.content.releases.schedule()

Releases_unschedule

POST /orgs/{orgId}/content/releases/{releaseId}/unschedule

Unschedule a release

forumulate releases unschedule<br>client.content.releases.unschedule()

Releases_publish

POST /orgs/{orgId}/content/releases/{releaseId}/publish

Publish a release now

forumulate releases publish<br>client.content.releases.publish()

Releases_rollback

POST /orgs/{orgId}/content/releases/{releaseId}/rollback

Roll a release back

forumulate releases rollback<br>client.content.releases.rollback()

Releases_preview

POST /orgs/{orgId}/content/releases/{releaseId}/preview

Preview a release

forumulate releases preview<br>client.content.releases.preview()

The Forumulate teamUpdated