YantrikDB HTTP API Reference — REST Endpoints for AI Memory
YantrikDB Server exposes a JSON HTTP gateway on port 7438 (configurable). Every endpoint accepts a Bearer token in the Authorization header.
Authentication
Section titled “Authentication”Two ways to authenticate:
- Per-database token — generated with
yantrikdb token create --db <name>. Each token grants access to one database. - Cluster master token — when clustering is enabled, the
cluster_secretdoubles as a master token that works on any node and grants access to the default database.
curl -H "Authorization: Bearer ydb_xxxxxxxx..." http://localhost:7438/v1/statsEndpoints
Section titled “Endpoints”Memory operations
Section titled “Memory operations”| Method | Path | Description |
|---|---|---|
| POST | /v1/remember | Store a memory |
| POST | /v1/remember/batch | Store up to 10k memories in one call |
| POST | /v1/recall | Semantic search (response includes fallback: "fts5_keyword" when the engine fell back to BM25 keyword matching; null otherwise — v0.8.17+) |
| POST | /v1/forget | Tombstone a memory |
| POST | /v1/relate | Create knowledge graph edge |
Memory inspection (v0.8.17+, dashboard-facing)
Section titled “Memory inspection (v0.8.17+, dashboard-facing)”Issue #39 Phase 1 ships three read endpoints that back wysie’s yantrikdb-hermes-dashboard. They use the RFC 014-B Principal substrate — query params can narrow the token’s authorized namespace but never broaden it.
| Method | Path | Description |
|---|---|---|
| GET | /v1/identity-scope | What this token sees — principal, effective_scope, namespace_inventory, and a nested identity_scope summary (identities / actors / spaces / conversations). Requires Scope::Read. |
| GET | /v1/memories | Paged, filtered list of active memories. Query params: namespace, status, domain, memory_type, limit (default 50, max 200), offset, sort (created_at / importance / last_access). Response: {total, limit, offset, items[]} with each row in the 25-field dashboard shape. |
| GET | /v1/memory/{rid} | Point read for a single memory, with consolidation_sources/entities/claims conditional arrays. Supports ?min_seq=N for read-your-writes — returns 412 replica_behind if the local node hasn’t applied the requested seq. |
Structured error envelope (v0.8.17+)
Section titled “Structured error envelope (v0.8.17+)”Every /v1/* error response is shaped:
{ "error": { "code": "stable_id", "message": "human-readable", "hint": "optional" } }Branch on code, not on the prose message. The stable code registry lives at docs/error-codes.md (unauthenticated, insufficient_scope, namespace_not_found, memory_not_found, invalid_query_parameter, replica_behind, and more). Legacy call sites that haven’t migrated to a specific code emit "code": "generic" via a shim — these are tracked and will migrate over time.
Skill substrate (v0.8.11+)
Section titled “Skill substrate (v0.8.11+)”First-class skill primitives — schema-validated, RYW-consistent, namespace-scoped to skill_substrate. Strict shape validation catches drift bugs (hyphen-vs-underscore in applies_to entries, malformed skill_id) without enforcing semantic ontology — the engine validates shape, the agent layer decides meaning.
| Method | Path | Description |
|---|---|---|
| POST | /v1/skills/define | Register a skill (skill_id, body, applies_to, skill_type). Returns 409 on duplicate. |
| GET | /v1/skills/{skill_id} | Exact lookup by skill_id. |
| POST | /v1/skills/search | Semantic search across skills with optional applies_to / skill_type post-filter. |
| POST | /v1/skills/{skill_id}/outcome | Append-only outcome event log. Engine never auto-rolls-up success_count — agent-layer pedagogy. |
| POST | /v1/skills/{skill_id}/forget | Tombstone a skill (optionally cascade outcomes). |
Cluster & health
Section titled “Cluster & health”| Method | Path | Description |
|---|---|---|
| GET | /v1/health | Shallow health + cluster state (cluster mode adds last_log_index, last_applied_index, replication_lag_log_entries, role_label per RFC 010 PR-6.9) |
| GET | /v1/health/deep | Deep health — probes engine lock, control DB, cluster quorum. Returns 503 if degraded. |
| GET | /v1/cluster | Cluster state: role, term, leader, peers |
| POST | /v1/cluster/promote | Force election from this node |
| GET | /v1/stats | Database statistics |
| GET | /metrics | Prometheus metrics (handler latency, lock waits, request counts) |
Admin (cluster master token required)
Section titled “Admin (cluster master token required)”| Method | Path | Description |
|---|---|---|
| POST | /v1/databases | Create a new tenant database |
| GET | /v1/databases | List all databases |
| GET | /v1/admin/control-snapshot | Export databases + tokens for replication |
| POST | /v1/admin/snapshot | Online backup of a tenant database (BLAKE3 checksum) |
POST /v1/remember
Section titled “POST /v1/remember”curl -X POST http://localhost:7438/v1/remember \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "text": "Alice leads engineering at Acme", "importance": 0.9, "domain": "work", "memory_type": "semantic", "valence": 0.0, "half_life": 168.0 }'Response: {"rid": "019d623a-..."}
Optional fields: metadata (object), namespace, certainty, source, emotional_state, embedding (pre-computed vector for client_only mode).
POST /v1/remember/batch
Section titled “POST /v1/remember/batch”Store up to 10,000 memories in a single call. Subject to per-tenant max_batch_size quota.
curl -X POST http://localhost:7438/v1/remember/batch \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "memories": [ {"text": "Alice leads engineering", "importance": 0.9, "domain": "work"}, {"text": "Bob runs the ML team", "importance": 0.8, "domain": "work"} ] }'Response: {"rids": ["019d623a-...", "019d623b-..."], "count": 2}
GET /v1/health/deep
Section titled “GET /v1/health/deep”Active liveness check that probes 3 subsystems. Returns 200 if all pass, 503 if any fail. Use for K8s readiness probes or smart load balancers.
curl http://localhost:7438/v1/health/deepResponse:
{ "status": "healthy", "checks": [ {"check": "engine_lock", "pass": true, "latency_ms": 0.25}, {"check": "control_db", "pass": true, "latency_ms": 0.11, "databases": 3}, {"check": "cluster_quorum", "pass": true, "node_id": 1, "role": "Leader", "term": 23} ]}POST /v1/admin/snapshot
Section titled “POST /v1/admin/snapshot”Create an online backup of a tenant database. Requires cluster master token. WAL-checkpoints before copy for consistency. Returns path + BLAKE3 checksum.
curl -X POST http://localhost:7438/v1/admin/snapshot \ -H "Authorization: Bearer $CLUSTER_SECRET" \ -H "Content-Type: application/json" \ -d '{"database": "default"}'Response: {"database": "default", "path": "/data/snapshots/default-1712345678.db", "size_bytes": 4096, "checksum_blake3": "abc123..."}
POST /v1/recall
Section titled “POST /v1/recall”curl -X POST http://localhost:7438/v1/recall \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "query": "who leads engineering?", "top_k": 5, "domain": "work", "expand_entities": true }'Response:
{ "results": [ { "rid": "019d623a-...", "text": "Alice leads engineering at Acme", "score": 1.41, "memory_type": "semantic", "domain": "work", "importance": 0.9, "why_retrieved": ["semantically similar (0.54)", "important", "recent"] } ], "total": 1}POST /v1/forget
Section titled “POST /v1/forget”curl -X POST http://localhost:7438/v1/forget \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"rid": "019d623a-..."}'Response: {"rid": "...", "found": true}
POST /v1/relate
Section titled “POST /v1/relate”curl -X POST http://localhost:7438/v1/relate \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "entity": "Alice", "target": "Acme", "relationship": "works_at", "weight": 1.0 }'Response: {"edge_id": "019d623a-..."}
Sessions
Section titled “Sessions”| Method | Path | Description |
|---|---|---|
| POST | /v1/sessions | Start a cognitive session |
| DELETE | /v1/sessions/{id} | End a session |
curl -X POST http://localhost:7438/v1/sessions \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"namespace": "chat-1", "client_id": "user-42"}'Cognition
Section titled “Cognition”| Method | Path | Description |
|---|---|---|
| POST | /v1/think | Run consolidation + conflict scan |
| GET | /v1/conflicts | List open conflicts |
| POST | /v1/conflicts/{id}/resolve | Resolve a conflict |
| GET | /v1/personality | Get derived personality traits |
| Method | Path | Description |
|---|---|---|
| GET | /v1/health | Server health + cluster status (no auth required) |
| GET | /v1/stats | Engine statistics for the authenticated database |
| GET | /metrics | Prometheus-format metrics (no auth) |
GET /v1/health
Section titled “GET /v1/health”{ "status": "ok", "engines_loaded": 1, "cluster": { "node_id": 1, "role": "Leader", "term": 5, "leader": 1, "accepts_writes": true, "healthy": true }}GET /metrics
Section titled “GET /metrics”Prometheus exposition format. Drops in to your existing scraping setup:
# HELP yantrikdb_active_memories Number of active memories# TYPE yantrikdb_active_memories gaugeyantrikdb_active_memories{db="default"} 1247
# HELP yantrikdb_cluster_is_leader Whether this node is currently the leader# TYPE yantrikdb_cluster_is_leader gaugeyantrikdb_cluster_is_leader{node_id="1"} 1Database management
Section titled “Database management”| Method | Path | Description |
|---|---|---|
| GET | /v1/databases | List databases |
| POST | /v1/databases | Create a database |
Cluster
Section titled “Cluster”| Method | Path | Description |
|---|---|---|
| GET | /v1/cluster | Detailed cluster status |
| POST | /v1/cluster/promote | Manually promote this node to leader (force election) |
GET /v1/cluster
Section titled “GET /v1/cluster”{ "clustered": true, "node_id": 1, "role": "Leader", "current_term": 5, "leader_id": 1, "healthy": true, "accepts_writes": true, "quorum_size": 2, "peers": [ { "node_id": 2, "addr": "192.168.1.2:7440", "role": "voter", "reachable": true, "current_term": 5, "last_seen_secs_ago": 0.5 }, { "node_id": 99, "addr": "192.168.1.3:7440", "role": "witness", "reachable": true, "current_term": 5, "last_seen_secs_ago": 0.6 } ]}Error responses
Section titled “Error responses”All errors return JSON with HTTP status:
{ "error": "read-only: not the leader (current leader: node 2)", "leader": 2}| Status | Meaning |
|---|---|
| 200 | Success |
| 400 | Invalid request body |
| 401 | Missing or invalid Bearer token |
| 404 | Database or memory not found |
| 503 | This node is read-only (not the leader) — try the leader |
| 500 | Internal server error |