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.
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 localesFor the whole space, under /api/agent/organizations/{org}/spaces/{space}:
| Request | Does |
|---|---|
GET members | Who 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 usage | Delivery API requests per environment and day |
Everything else is under /api/agent/organizations/{org}/spaces/{space}/{environment}:
| Area | Operations |
|---|---|
| Content model | list, 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) |
| Entries | list (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) |
| Review | GET/POST entries/{id}/review, and …/review/approve (optionally exclude for a shared block), …/review/send-back, …/review/withdraw (review before publishing) |
| Comments | GET/POST entries/{id}/comments, PATCH/DELETE comments/{commentId} (comments) |
| Translation | POST entries/{id}/translate (one entry), POST translations (many, in the background), GET translations (what is waiting) (translating) |
| History | GET entries/{id}/versions, GET …/versions/{versionId}, POST …/versions/{versionId}/restore |
| Trash | GET trash, POST trash/{id}/restore, DELETE trash/{id} |
| Redirects | GET redirects, POST redirects/create (from, to: a path, with or without a leading /, or an absolute URL), POST redirects/delete (redirects) |
| Plugins | GET 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 |
| Assets | upload (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 |
| Designs | POST 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 |
| Promotion | POST promotion/plan, POST promotion/apply |
| Export, import | GET 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) |
| Activity | GET audit-log (activity) |
| Improve | GET improve: the tests and flags the improve block can name |
| Connect a site | GET 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.