Skip to main content

Endpoints

Entity wire format

REST writes accept the full Entity record, including its flattened base fields. The entity type field is type; entity_type is the search filter and the MCP create_entity_simple parameter. For convenience creation with generated IDs and timestamps, use MCP tools. This is a complete minimal example with optional aliases and summary. Use fresh IDs and timestamps for new records, the caller’s actual space, and security labels appropriate to your policy.
entity.json
Additional record fields include handles, identity_keys, risk_level, trust_level, known_safe, first_seen, last_seen, status, redirect_to, metadata, subjects, and subjects_state. Returned records include the serialized defaults as well as supplied values.

Create, read, and update

Save the example as entity.json, then create it:
Creation returns 201 and the complete stored entity. This handler replaces space_id with the authenticated principal’s space. The field is still required in the JSON body. Other write routes validate the supplied record against the principal’s authority; always send the correct space.
GET accepts include_deleted=true. To update, edit the returned record and send the complete JSON to PUT /v1/entities/{id}. This is a replacement, not a partial patch. Keep the body’s ID consistent with the path and preserve provenance and security metadata. The handler requires read and write access to both versions and rejects changes to security.policy_id, security.level, security.labels, or security.handling with 403, even when the caller is cleared for both versions. If the stored security changes concurrently, the write fails with 409; fetch the current record before retrying a content edit. DELETE returns 204 and soft deletes the record. POST to the corresponding /restore route returns the restored entity.

Upsert and batch writes

POST /v1/entities/upsert accepts the same full entity body. It uses the supplied ID to create or update a record; it does not resolve identity from a display name. Existing records retain their security metadata under the same checks as PUT, including when upsert restores a deleted record. POST /v1/entities/batch accepts {"items": [...]} where every item is a full entity. The response has succeeded records and failed entries with an index and error. Items are processed individually. Replacements must include the existing security metadata unchanged. A rejected item does not update or restore the entity; the batch reports the failure for that item.
The request schema currently accepts atomic, but the handler does not implement transactional batches. Do not rely on it for rollback or all-or-nothing writes.

Search and batch reads

Search accepts query, entity_type, include_deleted (default false), limit (default 50), and cursor. Results are scoped and filtered by authorization. The response contains results (full entities), cursor, has_more, and total. Pass the returned cursor unchanged for the next page. POST /v1/entities/batch-get accepts an ids string array and optional include_deleted. It returns the same succeeded / failed envelope as batch writes. Each failed item identifies its original index.

Relationships and context

GET /v1/entities/{id}/with-relations returns entity, outgoing_relations, and incoming_relations. Relationship objects use the REST relationship format, including in, out, and rel_type. GET /v1/entities/{id}/context accepts: The bundle contains entity, outgoing_relations, incoming_relations, relations, recent_events, and alerts. Outgoing and incoming entries always contain full relationship objects; relations is populated for traversal depths greater than one. Its envelope differs from MCP get_entity_context_bundle. See searching.