/api/entities is the legacy general read/write surface over workspace
records. One endpoint serves every entity type — initiatives, workstreams,
milestones, tasks, decisions, artifacts, runs, goals, and more — selected by a
type parameter. Existing MCP and workspace integrations may still use it.
This endpoint lives outside the
/api/v1 namespace and outside the published
OpenAPI document. It is retained for compatibility only. New integrations
should use the dedicated /api/v1 operation for the resource they need; the
OpenAPI document is the machine contract.Authentication
All three methods require a personal API key or an authenticated MCP connection:user_id parameter must match the key’s identity; a mismatch returns 403.
Methods
There is no
DELETE method on this endpoint. See
deletion and terminal states.
Entity type vocabulary
Thetype parameter accepts these values. Each maps to one underlying table;
the label and body columns show which field names the type actually stores
(generic title/name and summary/description aliases are mapped for
you on write).
Two additional read-only types are served without a table lookup:
agent
(the built-in agent roster, filterable by domain) and video_template.
The alias issue is accepted and normalized to blocker.
GET — list and fetch
Query parameters
Response envelope
POST — create
The body is flat:type plus the record’s fields. owner_id defaults to the
API key’s identity.
- Initiative idempotency.
idempotency_key(up to 120 characters) replays the existing initiative with_dedup: trueand_replayed: trueinstead of inserting a duplicate. - Hierarchy dedup. Creating a
workstream,milestone, ortaskwhose label already exists (case-insensitive) inside the same parent scope returns the existing row with_dedup: truerather than a sibling duplicate. - Hierarchy parents.
workstreamrequiresinitiative_id;taskandmilestoneresolve their parents frommilestone_id/workstream_id/initiative_id. - Guarded types.
blockercreation is refused here (blockers are raised by runs).decisioncreation may not set a non-pendingstatus or any server-owned resolution field.runcreation may not setstatus,started_at,completed_at, orcancelled_at.artifactcreation may not setapprovedorrejected— those assert a human ruling; an automated reviewer writeseval_passedinstead.
{ "type": ..., "data": { ... } } with the created
row in data (also spread at the top level for older clients). Its data.id
is the UUID you use everywhere else.
PATCH — update
The body is flat:type, id, plus the fields to change.
- Decision: proposal-field updates are available through the MCP decision
tool while a decision is
pending; a personal API key receives403. Only proposal fields (title,summary,description,priority,due_at,recommended_action,blocks_task,estimate,urgency,urgency_score) are patchable, and only whilepending(409otherwise). Approving or declining is a human action — see the decision page. - Run:
statusand timestamp fields are rejected (403); control a run throughPOST /api/v1/runs/{runId}/actions/{action}. - Blocker: not patchable at all; blockers close through their resolve and dismiss lifecycle.
- Artifact:
approvedandrejectedare rejected (403); a machine reviewer writeseval_passed. - Task:
donetasks are terminal for automated updates; a409tells you to reopen deliberately first.
Deletion and terminal states
/api/entities has no DELETE method, and hard deletion is not part of the
API-key REST contract. Use terminal statuses for API-key workflows. The MCP
orgx_act tool can perform the additional lifecycle actions available to an
authenticated MCP connection.
With an API key, use terminal statuses instead:
Lifecycle actions — POST /api/v1/lifecycle
One route pauses, resumes, retries, or cancels any node of the hierarchy. It
takes exactly three fields, all required:
Note the field names: this route takes
level and id, not entity_type
and entity_id (those belong to the artifact and receipt surfaces). There is
no status or target-state field — the target state is implied by action,
and cascades to child runs.
{ data, meta } envelope — returned with
200 when ok is true and 422 when it is false:
error and blockReasons to the lifecycle result. Lifecycle
errors use the same structured error envelope as the rest of /api/v1.
