Skip to content

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

http://<host>:8080/api/v1/...

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. CreateSession is 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.