Using the REST API¶
Everything Athena does is reachable with plain HTTP and JSON on port 8080. This guide covers the conventions; per-endpoint request/response tables live in the API Reference.
Base shape¶
All request and response bodies are JSON. Field names are snake_case, matching the protobuf definitions (the REST surface is generated from the same proto as gRPC; see Architecture).
# The core workflow in four calls
curl -X POST .../api/v1/sessions # create session
curl -X POST .../api/v1/sessions/{id}/interactions # store a turn
curl .../api/v1/sessions/{id}/context?limit=10 # read the window
curl -X POST .../api/v1/sessions/{id}/context/search # semantic search
Headers¶
| Header | When |
|---|---|
Content-Type: application/json |
All POST bodies |
X-API-Key: <key> or Authorization: Bearer <key> |
When API-key auth is enabled |
X-JWT-Token: <token> or Authorization: JWT <token> |
When JWT auth is enabled |
Error mapping¶
gRPC status codes translate to HTTP deterministically. The body carries a JSON error with a message:
| gRPC | HTTP | Typical cause |
|---|---|---|
InvalidArgument |
400 | Missing user_id, empty search query, bad event type |
Unauthenticated |
401 | Missing/invalid credentials with auth enabled |
NotFound |
404 | Unknown session_id |
FailedPrecondition |
412 | Blob payload sent with no blob store configured |
Internal |
500 | Datastore failure; check server logs |
Treat 5xx as retryable with backoff; treat 4xx as bugs in the calling code (except 401, which is configuration).
Non-API endpoints¶
Two routes live outside /api/v1 and never require auth:
curl http://localhost:8080/health # {"status":"healthy","service":"memory-os",...}
curl http://localhost:8080/metrics # Prometheus text format
/health reports degraded when Redis or MongoDB checks fail; wire it to liveness probes. The richer dependency-by-dependency check is GET /api/v1/health.
OpenAPI spec¶
A generated OpenAPI document ships in the repo at docs/api/openapi.json (regenerated by make generate). Import it into Postman/Insomnia or feed it to a client generator for languages without an SDK.
Patterns worth copying¶
- Reuse connections. All endpoints are on one host/port; keep-alive does the right thing.
- Propagate deadlines. Long calls are the LLM-embedding paths (
context?query=,search); give them a few seconds, and keep plain window reads on a tight timeout. - Idempotency.
CreateSessionis not idempotent (each call makes a new session), but sessions are cheap and memory is keyed by identity, not session (why). Losing a session ID is harmless; create another. - gRPC when it matters. For high-frequency internal callers, the same API is on port 9090 as gRPC; see gRPC & Protobuf.