Read API
All read endpoints live under /api/v1 and require a Bearer token with at least the read scope.
Authorization: Bearer <api-key>
Entity history
GET /api/v1/collections/{collection}/entities/{entityId}/history
Returns a paginated list of events for an entity, newest-first by default.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
from |
RFC3339 | — | Return events received at or after this time |
to |
RFC3339 | — | Return events received before or at this time |
author_id |
string | — | Filter to events from this author |
op |
string | — | Filter by operation: create, update, or delete |
path |
string | — | Filter to events that touch this field path |
source |
string | — | Filter by source system identifier |
limit |
integer | 100 | Page size (1–1,000) |
cursor |
string | — | Opaque pagination token from a previous next_cursor |
order_by |
string | version |
Sort key: version, ts_source, or ts_received |
order |
string | desc |
asc or desc |
format |
string | native |
Diff format: native or json-patch (RFC 6902) |
Response (200):
{
"entity_id": "deal-1",
"next_cursor": "eyJ2IjoxMH0=",
"events": [
{
"version": 4,
"op": "update",
"ts_received": "2026-06-02T09:00:01Z",
"ts_stored": "2026-06-02T09:00:01Z",
"ts_source": "2026-06-02T09:00:00Z",
"author_id": "user-42",
"source": "crm-backend",
"integrity": {
"hash": "sha256:9f86d0...",
"prev_hash": "sha256:2c2640..."
},
"changes": [
{"path": "amount", "op": "change", "old": 5000, "new": 7500},
{"path": "stage", "op": "change", "old": "prospect", "new": "qualified"}
]
}
]
}
The integrity field is present only when the hash_chain plugin is enabled for the collection.
Pagination: Pass the next_cursor value as the cursor parameter. When next_cursor is null, you have reached the last page.
Current state
GET /api/v1/collections/{collection}/entities/{entityId}/state
Returns the entity’s current materialized state.
Response (200):
{
"entity_id": "deal-1",
"version": 4,
"ts": "2026-06-02T09:00:01Z",
"deleted": false,
"state": {
"title": "Acme Corp",
"amount": 7500,
"stage": "qualified"
}
}
Returns 404 if the entity has never been written (or has been purged).
Point-in-time state
GET /api/v1/collections/{collection}/entities/{entityId}/state?version=3
GET /api/v1/collections/{collection}/entities/{entityId}/state?ts=2026-05-01T00:00:00Z
Reconstruct the entity’s state at a specific version or timestamp. Letopis uses the nearest snapshot plus a tail replay.
| Parameter | Type | Description |
|---|---|---|
version |
integer | Reconstruct state at this exact version |
ts |
RFC3339 | Reconstruct state at the latest version received before or at this time |
Verify hash chain
GET /api/v1/collections/{collection}/entities/{entityId}/verify
Verifies the SHA-256 hash chain for the entity (requires hash_chain plugin to be enabled for the collection). Returns the first divergence if any, or {"ok": true} if the chain is intact.
List collections
GET /api/v1/collections
Returns a list of collections in the tenant’s database, with config and stats.
List entities in a collection
GET /api/v1/collections/{collection}/entities
Returns a paginated list of entity IDs in the collection.
Query parameters: limit (default 100, max 1,000), cursor, order_by (entity_id or ts), order (asc or desc).
Business flows
GET /api/v1/flows/{flowId}
Returns the full causal DAG for a business flow: all activities and their caused_by links. Activities are sorted topologically.
{
"flow_id": "flow-deal-onboarding",
"activities": [
{
"activity_id": "act-111",
"collection": "crm.deals",
"entity_id": "deal-1",
"version": 2,
"step": "qualification",
"caused_by": []
},
{
"activity_id": "act-222",
"collection": "crm.tasks",
"entity_id": "task-99",
"version": 1,
"step": "follow-up",
"caused_by": [{"activity_id": "act-111"}]
}
]
}
Dead-letter queue
GET /api/v1/dlq
Returns failed webhook deliveries. Each entry includes the original event, the target URL, the last error, and the retry count. Entries can be replayed or deleted via the Admin API.