API

Agent API and MCP

Everything the dashboard does, over HTTP with a bearer token or as MCP tools with OAuth. Signing in, finding a space, reading the model, writing content, assets and connecting a site.

5 min read

The agent API does what the dashboard does, with a bearer token, for agents and for anyone scripting Content. The same operations are MCP tools. The step-by-step guide is /agent.md, written for agents; the full reference is /openapi.json.

Send and expect JSON. Errors are problem JSON with a stable code and a hint. Content's endpoints are on content.obelism.studio: www serves accounts, organizations and spaces, and answers a Content path with a 404 that says so.

Signing in

Accounts are shared by every Obelism product and served by www.obelism.studio. Content answers /api/agent/auth/* with a 308 there, so following redirects works too.

POST https://www.obelism.studio/api/agent/auth/sign-in
{ "email": "…", "password": "…" }

answers { "token", "tokenType": "Bearer", "expiresAt" }. Send it as Authorization: Bearer <token>. It is the same session a browser login holds, lasting 30 days, renewed while in use. GET /api/agent/me shows whose it is.

For working on a space session after session, don't sign in again every time: create a management token of your own — POST …/{environment}/api-tokens with { "name": "…", "kind": "management", "scopes": ["model", "content"] } —, put its token (a cms_m_… value, shown once) in an untracked environment file, and send that instead of the session token. A content scope reads and writes the environment's content through this API without your session (migrations, imports); model — the default without scopes — keeps the model in Git through the management API. Creating or revoking tokens needs the developer or admin role and is refused in production (production_protected): a person makes production's tokens in the dashboard. Revoking a lost one is POST …/api-tokens/{tokenId}/revoke.

Where to work

GET /api/agent/organizations                     → organizations, your role in each
GET /api/agent/organizations/{org}/spaces        → spaces, their locales
POST /api/agent/organizations/{org}/spaces       → a new space (admins and developers), optionally from a `starter` model
PATCH /api/agent/organizations/{org}/spaces/{space} → rename it, or change its locales

For the whole space, under /api/agent/organizations/{org}/spaces/{space}:

RequestDoes
GET membersWho may open the space, with their role in it
PUT members/{userId}A member's role in this space (admins)
GET locale-removal?locale=…What removing a locale would delete, before you do it
GET usageDelivery API requests per environment and day

Everything else is under /api/agent/organizations/{org}/spaces/{space}/{environment}:

AreaOperations
Content modellist, read, save, replace and delete content types (content-types, content-types/{apiId}; a new type gets its kind's template fields, listed by GET /api/agent/content-type-templates; saving an existing type merges the fields it sends, keeping the ones it leaves out, and removeFields names the ones to drop, deleting their values); the whole model as a file (GET model, POST model/plan — answers a planId — POST model/apply by that or by the file)
Entrieslist (search, contentType, status, parentId, sort, limit, skip), validate (POST entries/validate, a dry run of create), create, read, save (baseRevision), publish (optionally some locales, and exclude for a shared block's live pages), unpublish, schedule, move (with slugs per locale), duplicate, detach a shared block (POST entries/{id}/detach-block with uid, baseRevision), delete, preview; publish impact (GET entries/{id}/publish-impact); bulk actions (POST entries/bulk)
ReviewGET/POST entries/{id}/review, and …/review/approve (optionally exclude for a shared block), …/review/send-back, …/review/withdraw (review before publishing)
CommentsGET/POST entries/{id}/comments, PATCH/DELETE comments/{commentId} (comments)
TranslationPOST entries/{id}/translate (one entry), POST translations (many, in the background), GET translations (what is waiting) (translating)
HistoryGET entries/{id}/versions, GET …/versions/{versionId}, POST …/versions/{versionId}/restore
TrashGET trash, POST trash/{id}/restore, DELETE trash/{id}
RedirectsGET redirects, POST redirects/create (from, to: a path, with or without a leading /, or an absolute URL), POST redirects/delete (redirects)
PluginsGET plugins: the plugins on in the environment. A field whose editor names one has it as its input for people; write its value as for any field of its type
Assetsupload (multipart with a file field up to 50 MB, a filename field names it, or base64 in a JSON body up to 1 MB; the bytes prove the type and an image's width/height, and a false renderable-image claim is refused; POST uploads/assets + PUT its uploadUrl + POST assets/from-upload takes more, videos up to 100 MB), list (search, mimeType, tag, limit, skip), read, change (alt, title, focal point, tags, private, revokeLinks), replace the file (PUT assets/{id}/file, with the same body), delete
DesignsPOST uploads (a URL to PUT a file to) and POST design-imports: a page from Claude Design as a draft on the space's blocks
PromotionPOST promotion/plan, POST promotion/apply
Export, importGET export, POST uploads/import (a URL to PUT an export file to, so megabytes skip the agent's context), POST import/plan, POST import/apply (by file or that uploadId) (export and import); GET export/sql for portable SQL files (taking your content elsewhere)
ActivityGET audit-log (activity)
ImproveGET improve: the tests and flags the improve block can name
Connect a siteGET setup, API tokens, webhooks (create, edit, pause, rotate the secret, test, delete) and their deliveries (list, redeliver), GET/PATCH settings (preview URL, product and collection paths, prompt endpoint, publishing, the model's source, AI translation)

Your role decides what you may do. In production the agent API doesn't create or revoke tokens, add or delete webhooks, or change settings (403 production_protected): a person does those in the dashboard.

Saving content

To change an entry, read it, change its draft, and send the whole content back with the revision you read:

GET …/entries/{id}                          → entry.draft, entry.draftRevision
PUT …/entries/{id}  { "content": { … }, "baseRevision": 3 }

A 409 conflict means someone saved in between: read again and redo the change. Saving checks value shapes; publishing also enforces required fields. Rich text may be sent as Markdown.

MCP

The MCP server is https://content.obelism.studio/mcp (Streamable HTTP). It signs in with OAuth 2.1 (a browser window asks you to approve the connection), so there is no token to copy; clients find everything through /.well-known/oauth-protected-resource/mcp and register with Dynamic Client Registration.

Each agent API operation is a tool named after its operationId in /openapi.json (listContentTypes, createEntry, saveEntry, publishEntry, getProjectSetup, …), taking the path parameters and body fields as one input. Tools run as you, within your role; a read-only grant (cms:read) gets only the reading tools. See connect an agent to set one up.

On this page

Marks in the margin

  • Note
  • Watch out
  • Updated

Scribes marked doubtful lines in the margin. That practice is called obelism.

Stuck on a step?