API
Snapshots
Snapshots are materialized facet histograms for a namespace. They carry
facet listings in values[].v and facet counts in values[].n, stored
durably in S3 and mirrored into Aerospike for the latest body.
Use POST /snapshots to materialize a field now. Use history and body
routes to read the durable chronology written by the consistency watcher.
Routes
| Route | Method | Behavior |
|---|---|---|
POST /v2/namespaces/{ns}/snapshots | POST | Create an on-demand snapshot job for one field. |
GET /v2/namespaces/{ns}/snapshot-jobs | GET | List in-memory snapshot jobs. |
GET /v2/namespaces/{ns}/snapshot-jobs/{id} | GET | Read one snapshot job. |
GET /v2/namespaces/{ns}/history | GET | Newest-first durable snapshot history. |
GET /v2/namespaces/{ns}/snapshots/{sha} | GET | Full snapshot body by full SHA or 7-char prefix. |
GET /v2/activity/snapshots | GET | Cross-namespace snapshot-write activity stream. |
Create a snapshot job
POST /v2/namespaces/products/snapshots
Content-Type: application/json
{
"field": "category",
"source": "auto",
"filters": ["brand", "Eq", "Acme"],
"page_size": 1000
}
Valid sources are auto, stored, cache, and origin.
| Source | Reads from | Notes |
|---|---|---|
auto | Stored snapshot when possible, otherwise cache/origin policy | Default. Stored snapshots only support unfiltered configured fields. |
stored | Latest S3 snapshot body, with Aerospike mirror as a cache | Fastest path for configured facet fields. |
cache | Aerospike document cache | Supports filters the cache can evaluate. |
origin | Turbopuffer paginated scan | Authoritative. Persists the computed snapshot body to S3. |
The response is 202 Accepted:
{
"id": "snapshot-job-uuid",
"namespace": "products",
"field": "category",
"source": "auto",
"status": "running",
"progress": 0,
"documents_scanned": 0,
"created_at": "2026-05-26T10:00:00Z"
}
Poll the job:
GET /v2/namespaces/products/snapshot-jobs/snapshot-job-uuid
Completed jobs include sha when a body was materialized:
{
"id": "snapshot-job-uuid",
"namespace": "products",
"field": "category",
"source": "origin",
"status": "completed",
"documents_scanned": 12844,
"sha": "3f9e8b21",
"stable_as_of": 1747300000123
}
History
GET /v2/namespaces/products/history?limit=20
[
{"watermark_ms": 1747300000123, "sha": "3f9e8b21..."},
{"watermark_ms": 1747299600045, "sha": "a1c5b09f..."}
]
| Query param | Default | Purpose |
|---|---|---|
limit | 50 | Maximum entries returned. Capped at 500. |
before | none | Return entries older than this SHA. 7-char prefixes are accepted. |
The history endpoint lists S3 keys only; it does not read every snapshot body.
Snapshot body
GET /v2/namespaces/products/snapshots/3f9e8b2
{
"namespace": "products",
"watermark_ms": 1747300000123,
"sha": "3f9e8b21",
"fields": [
{
"name": "category",
"values": [
{"v": "books", "n": 1240},
{"v": "electronics", "n": 873}
]
}
],
"fields_skipped": [
{
"name": "tags",
"reason": "exceeded_cap",
"distinct_observed": 247000,
"cap": 10000
}
]
}
fields[].values[].v is the facet listing. fields[].values[].n is the
facet count. Fields present in fields[] are complete. Fields above the
10,000 distinct-value cap are listed in fields_skipped[] instead of
being partially materialized.
Activity
GET /v2/activity/snapshots?since=1747200000000&limit=50
| Query param | Required | Purpose |
|---|---|---|
since | yes | Epoch-ms lower bound on ts_ms. |
limit | no | Cap 500, default 50. |
namespace | no | Exact namespace filter. |
cursor | no | Pagination cursor from next_cursor. |
Activity is snapshot lifecycle only. Search history and clickstream events have separate feeds.