API action reference
Everything goes through one endpoint, POST /api/, with an action field naming what to do. For the shape of the request and the reasoning behind a single entrypoint, see The API. This page is the catalogue.
Authentication is bearer-only (no cookies, which removes CSRF). A magic-link flow issues the token: request_code → email → verify_code → token in Authorization: Bearer …. Each row lists the permission the action requires.
Response and error conventions
Success usually carries success: true. Queries return a single result (for resolve/byPath) or a plural results with a count. Error statuses you’ll meet:
| Status | Meaning |
|---|---|
400 | Validation / bad request |
401 | Not authenticated |
402 | Plan limit reached (carries limitType) |
403 | Permission, feature gate, or coming-soon |
404 | Not found |
409 | Conflict — path in use, lock held, connector slug clash |
413 | Body too large |
422 | Operation failed |
429 | Rate limited (Retry-After on auth backoff) |
A global ceiling of 120 requests/hour per IP applies; health and log_client_error have their own limits.
Auth
| Action | Does | Permission | |—|—|—| | request_code | Request a six-digit login code by email | none (auth backoff) | | verify_code | Exchange the code for a bearer token | none | | revoke | Revoke the current session token | bearer |
Node lifecycle
| Action | Does | Permission | |—|—|—| | create | Create a node as a draft; routable when given a path | write + create.route/create.collection | | duplicate | Clone an existing node to a new draft | write | | save | Save one property on the draft | write | | approve | Publish draft → live; compile, propagate, invalidate caches | publish | | make_draft | Open a live node for editing | write | | discard | Drop the draft, revert to live | write | | unpublish | Take a live node offline (back to draft) | publish | | delete | Remove the node and its index entries | delete | | status | Full status: graph, draft, diff, lock | view | | submit | Public submission → draft for review | feature publicSubmit | | form_spec | Form spec + values for the drawer form | view | | atoms_spec | The declarative atom contract (types, formats, read-only keys) | view |
Editor locks
The advisory heartbeat trio (Concur\Lock) sits alongside the older lock/unlock actions kept for existing callers.
| Action | Does | Permission |
|---|---|---|
lock_acquire | Claim an editor lock on {type, id} | write (409 if held) |
lock_renew | Extend the 30-minute TTL (heartbeat) | write |
lock_release | Release the lock | write |
Actors
| Action | Does | Permission | |—|—|—| | whoami | Your own actor data (token masked) | view | | list_actors / get_actor | List or fetch persons and API keys | manage.actors | | save_person | Create or update a person + permissions | manage.actors | | save_webapi | Create or update a WebAPI key | manage.actors | | rotate_token | Roll a WebAPI token (one-time reveal) | manage.actors | | remove_actor | Remove an actor (not yourself) | manage.actors |
Space configuration
| Action | Does | Permission | |—|—|—| | get_space | Organisation + plan + usage | manage.settings | | save_organisation | Name, URL, view gating, owner | manage.settings | | save_plan | Toggle features (publicSubmit, viewGating, customDomain, apiAccess) | manage.settings |
Files
| Action | Does | Permission | |—|—|—| | upload_file | Upload → ImageObject node; MIME whitelist (no SVG), 10 MB max, alt text required | write (402 over storage limit) | | delete_file | Remove a file and its node | delete | | list_files | List media files | bearer |
Registry, query and rendering
| Action | Does | Permission | |—|—|—| | index | The registry as an ItemList | bearer | | appears_in | Where a node is referenced | bearer | | set_routing | Set or change a node’s @path and @build | create.route | | query | byType / byIdentifier / byAppearsIn / resolve / byPath; fields selects columns | view | | resolve | Path → @id / @type / @build lookup | bearer | | build | Server-side render a form or block (menu/page reserved) | write | | collections | The type-picker vocabulary | view |
Worker
| Action | Does | Permission | |—|—|—| | rebuild | Rebuild registry/indexes and recompile all live nodes | manage.settings | | maintain | Run cron maintenance now (stale locks, sessions, rate files) | manage.settings | | cron_status | Cron state and log | manage.settings | | wipe | Clear .index / .sessions and stale lock backups | manage.settings |
Observability
| Action | Does | Permission | |—|—|—| | health | Per-subsystem status; 200 healthy / 503 otherwise | none (60/min) | | log_client_error | Browser error → runtime log | none (10/hour, 2 KB cap) |
Wizard
The wizard picks AnthropicLLMClient when an AI connector is active, otherwise the built-in CtxrLLMClient.
| Action | Does | Permission |
|---|---|---|
wizard.turn | One chat cycle (ask → assess → execute) | view (execution gated deeper) |
wizard.confirm | Typed confirmation for a destructive step | view |
wizard.sessions / wizard.session | List sessions / fetch one | view |
Connectors
Secrets are always redacted in responses, and every mutation emits an audit event.
| Action | Does | Permission |
|---|---|---|
connector.list | Instances, available kinds, categories, plan tier | view |
connector.install | New instance (inactive) | manage.settings |
connector.configure | Partial config update | manage.settings |
connector.test | Run the kind’s test callable | manage.settings (10/hour) |
connector.activate / connector.deactivate | Flip status; swap-confirmation on operation overlap | manage.settings |
connector.uninstall | Remove the config | manage.settings |
Incoming and OAuth (edge routes)
These sit outside the action map, with their own authentication.
POST /api/incoming/{provider}— webhooks. Signature-verified (not bearer), routed to a synthetic actor with a whitelisted set of operations, then mapped to an operation invoke.GET /oauth/callback/{kind}— OAuth return, bound through thestateparameter, handled by the connector’s adapter.
The openai connector is registered but marked coming-soon, so it can’t be installed yet.