REST API
Read and write your memories over plain HTTPS, using the same OAuth token your MCP clients already use. No SDK, no API key.
Base URL
https://api.agentage.io/v1Twelve endpoints under /v1: list, create, inspect, and retire memories; list, read, write, edit, and delete notes; search; and export. Every route twins one of the six frozen memory__* MCP tools, so field names, defaults, and limits match the tool contract you already know.
The vaults noun is deprecated
/v1/vaults/* still resolves, as a deprecated alias of /v1/memories/*, sunsetting Sun, 08 Feb 2027 00:00:00 GMT. It is a path alias, not a shape-compat layer: responses already use the new memories field names. Every response on the alias carries Deprecation: true, Sunset: Sun, 08 Feb 2027 00:00:00 GMT, and Link: </v1/memories>; rel="successor-version".
Authentication
Send an OAuth 2.1 access token as a bearer header:
Authorization: Bearer <access-token>The token is the same one issued when you connect any MCP client (OAuth 2.1 with PKCE, sign-in at auth.agentage.io). Which memories you see is decided by the token, not by request parameters - a token scoped to one memory lists only that memory. Reads need the memory:read scope; writes need memory:write.
Endpoints
Every endpoint, grouped by resource. Click a row to expand its contract - parameters, a curl example, the 200 response, response fields, and error codes.
Memories
Notes
Search & export
Writes and concurrency
Every write (POST/DELETE on memories, PUT/PATCH/DELETE on notes) accepts an optional If-Match: <rev> header for optimistic concurrency. Send the rev you last read; a stale value fails the write with 409 CONFLICT instead of silently overwriting someone else's change.
rev is the memory's HEAD sha. Read it from GET /v1/memories/{memory}, or from the rev field every write returns - chain writes without a re-fetch.
Errors
Every non-2xx response carries the same JSON envelope. code is a stable, machine-readable string you can switch on; message is a human-readable hint that may change.
{
"error": {
"code": "UNAUTHENTICATED",
"message": "missing bearer token"
}
}Codes: UNAUTHENTICATED (401), FORBIDDEN (403), NOT_FOUND (404), BAD_REQUEST (400), CONFLICT (409), RATE_LIMITED (429), UPSTREAM_UNAVAILABLE (503).
Limits and versioning
- Reads need the
memory:readscope; writes needmemory:write. - Rate limited to 60 requests per minute per IP.
- Rate-limit responses carry IETF draft-7 headers
ratelimitandratelimit-policy(notX-RateLimit-*); a 429 also sendsRetry-After. - The
/v1contract is frozen: fields are only ever added, never renamed or removed. Breaking changes would ship as/v2.
What this API is not
- Not a sync channel - memory contents sync over git (Obsidian plugin, CLI).
- No API keys - OAuth 2.1 bearer only.