Developers
HTTP API reference
Base URL and versions
https://api.saveslot.ai/v1The version is in the path. Breaking changes get a new version; additive changes (new fields, new endpoints) do not.
Authentication
Every request sends a bearer token:
Authorization: Bearer <token>| Token | Who uses it | Reaches |
|---|---|---|
API key (ss_ro_…, ss_rw_…) | Your own backend | One slot, read only or read and write |
| OAuth access token | Apps your users authorize | The slots and permissions the user approved. See OAuth apps |
A request outside the token's reach returns 404 for slots it cannot see and 403 for actions it may not take, so a token never learns about slots it was not given.
Errors
Errors use one shape:
{
"error": {
"code": "read_only",
"message": "This key can only read slot “Health”.",
"request_id": "req_8f2c…",
"retry_after": null
}
}| Status | code | When |
|---|---|---|
| 400 | invalid_request | Malformed body or parameters; message names the field |
| 401 | unauthenticated | Missing, expired or revoked token |
| 403 | read_only, forbidden_scope | The token cannot write here, or lacks create tables / delete data |
| 404 | not_found | The slot, table or record does not exist for this token |
| 409 | conflict, version_mismatch | The record changed since you read it, or is in an unresolved conflict |
| 422 | official_table | Tried to change the structure of an official table |
| 429 | rate_limited | Too many requests; wait retry_after seconds |
| 5xx | server_error | Retry with backoff; quote request_id to support |
The console maps every code to a message the person can act on, and always shows request_id on failure.
Pagination
List endpoints return one page and the total:
{ "items": [ … ], "page": 1, "page_size": 20, "total": 255 }Query parameters: page (1-based) and page_size. Records are newest first.
Concurrency and retries
- Every record has a
version. SendIf-Match: <version>on corrections; a stale version returns409 version_mismatch. - Send
Idempotency-Key: <uuid>on anyPOST. Repeating a request with the same key returns the first result instead of creating a duplicate.
Times and amounts
- Times are ISO 8601 with offset (
2026-11-15T07:40:00-08:00). The console formats them in the person's time zone and language; the API never returns display strings such as “1 hour ago”. - Money is an integer in the smallest unit plus a currency:
{ "amount": 800, "currency": "usd" }.
Resources
Slots
| Method and path | Purpose |
|---|---|
GET /slots | Slots the token can reach |
GET /slots/{slot} | One slot, with its tables and extensions |
Tables
| Method and path | Purpose |
|---|---|
GET /slots/{slot}/tables | Tables with columns, kind (official, agent, derived) and record counts |
POST /slots/{slot}/tables | Create a table (needs create tables) |
POST /slots/{slot}/tables/{table}/recompute | Recompute a derived table |
Records
| Method and path | Purpose |
|---|---|
GET /slots/{slot}/tables/{table}/records?q=&trust=&page= | Search, filter by trust marker, and page |
POST /slots/{slot}/tables/{table}/records | Add a record |
PATCH /slots/{slot}/tables/{table}/records/{id} | Correct a record; adds a version |
GET …/records/{id}/history | All versions |
POST …/records/{id}/restore | Restore version n; adds a version |
POST …/records/{id}/resolve | Settle a conflict with the chosen option |
DELETE …/records/{id} | Delete (needs delete data); returns a preview first unless confirm=true |
A record looks like this:
{
"id": "rec_m2",
"values": { "time": "2026-11-12T19:30:00-08:00", "what": "Beef noodles", "calories": 650 },
"trust": "inferred",
"sources": [{ "kind": "agent", "name": "Claude · Web" }],
"version": 3,
"written_at": "2026-11-12T19:31:04-08:00",
"conflict": null
}trust is one of confirmed, inferred, unknown, conflicted. When trust is conflicted, conflict.options lists each value with its source and time.
Pages
| Method and path | Purpose |
|---|---|
GET /slots/{slot}/pages | Pages in a slot |
GET /pages/{page} | The page, its declared queries and versions |
DELETE /pages/{page} | Delete an agent page; default pages cannot be deleted |
Activity and usage
| Method and path | Purpose |
|---|---|
GET /slots/{slot}/activity?range=&actor=&kind=&failures_only= | Activity events |
GET /usage | Calls this period, by day and by connection |