§ Interfaces
The REST API. Memory in three calls.
Direct HTTP access to OctaMem. Useful when you can't install an SDK, when you're calling from a runtime we don't ship for, or when you just want to know exactly what's on the wire.
- Base URL
- platform.octamem.com
- Auth
- Bearer API key
- Primitives
- details / search / add
Use the REST API with
- OpenClawPersist agent state between OpenClaw runs.
- Claude CodeGive the CLI recall of your repo's decisions.
- CrewAIOne shared memory across every crew member.
- LangGraphCheckpoint graph state as durable memory.
- MCPExpose remember / recall / forget as MCP tools.
- CursorCarry project context across editor sessions.
Authentication
Every request takes your API key, either as a bearer token or in an X-API-Key header. Keys come from Settings → API keys at platform.octamem.com.
# Either header works.
Authorization: Bearer sk-om-live-...
X-API-Key: sk-om-live-...Base URL and response envelope
- All endpoints are served from
https://platform.octamem.com. - Three endpoints make up the surface:
/api/memory/details,/api/memory/search, and/api/memory/add. - All three are POST. There are no GET endpoints; sending GET returns
405 Method Not Allowed.
Every successful response is wrapped in the same envelope. The payload you want is always under data.
{
"success": true,
"message": "Success",
"data": { /* endpoint-specific payload */ }
}success: boolean. True when the request was handled. Note this reflects transport success, not whether your key was valid — see Errors.message: string. Human-readable status, normally"Success".data: object. The endpoint-specific payload.
POST /api/memory/details
Validate a key and read the current plan, memory usage, storage, and wallet balance. Call it before search or add to confirm the key is live and the wallet can cover the request. Takes an empty JSON body.
curl -X POST https://platform.octamem.com/api/memory/details \
-H "Authorization: Bearer $OCTAMEM_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'
# Response
{
"success": true,
"message": "Success",
"data": {
"api_key": "sk-om-live-...",
"valid": true,
"memory": {
"id": "69ca0b6914fd2458adbde4b0",
"name": "Personal-memory",
"usage": { "requests": 378, "tokens": 16934249, "spend": 62.72 },
"storage_used": 47794449,
"storage_limit": 21474836480
},
"plan": { "name": "Advanced", "storage_gb": 20, "token_rate": 3 },
"wallet_balance": 88.269767
}
}Response fields
valid: boolean. Whether the key is active. This is the field to branch on.api_key: string. The key you sent, echoed back in full. Never log or display this response verbatim.memory.id: string. Identifier of the memory store the key is bound to.memory.name: string. Human label for that store, e.g.Personal-memory.memory.usage.requests: integer. Lifetime request count for this store.memory.usage.tokens: integer. Lifetime tokens consumed.memory.usage.spend: float. Lifetime spend in USD.memory.storage_used/memory.storage_limit: integers, in bytes. Compare these to know how close you are to the ceiling.plan.name,plan.storage_gb,plan.token_rate: the current plan, its storage allowance in GB, and the multiplier applied when pricing tokens.wallet_balance: float. Remaining balance in USD. Everysearchandadddraws from it.
POST /api/memory/search
Query memory in natural language. Consumes tokens and returns memory already assembled into prose, split by memory type — not a ranked list of raw records.
Request body
query: string, required. The natural-language question. Omitting it returns422.previous_context: string, optional. Prior context that scopes the search.
curl -X POST https://platform.octamem.com/api/memory/search \
-H "Authorization: Bearer $OCTAMEM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "When does the private beta open?",
"previous_context": "Documentation QA session"
}'
# Response
{
"success": true,
"message": "Success",
"data": {
"semantic_memory": "Octamem entity has property 'rest_api_base_url': ...",
"episodic_memory": "On 2026-08-07 at 13:50 UTC, the user reviewed ...",
"procedural_memory": "",
"relevant_file_ids": [],
"file_memory": [],
"tokens": 6231,
"cost": 0.018693,
"wallet_balance": 88.269767
}
}Response fields
semantic_memory: string. Facts and entity properties, rendered as prose. Empty string when nothing matched.episodic_memory: string. Timestamped events and interactions relevant to the query.procedural_memory: string. Workflows, rules, and constraints. Often empty.relevant_file_ids: array of strings. Ids of files that matched, for use with file memory.file_memory: array. Extracts from those files.tokens: integer. Tokens this call consumed.cost: float. USD charged for this call.wallet_balance: float. Balance remaining after it.
POST /api/memory/add
Store content as memory. OctaMem decides what is worth keeping and which memory types apply, so the response is a record of that reasoning, not just an acknowledgement.
Request body
content: string, required. The content to remember.previous_context: string, optional. Context the content belongs to.
curl -X POST https://platform.octamem.com/api/memory/add \
-H "Authorization: Bearer $OCTAMEM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Private beta opens March 20. Public launch April 15.",
"previous_context": "Documentation QA session"
}'
# Response (memory_decisions abbreviated)
{
"success": true,
"message": "Success",
"data": {
"stored": true,
"bytes": 156,
"embedding_bytes": 97248,
"total_storage_bytes": 97248,
"data": {
"status": 200,
"success": true,
"data": {
"should_store_memory": true,
"memory_decisions": {
"semantic": { "use": true, "items": [ /* entities + properties */ ] },
"episodic": { "use": true, "items": [ /* interactions */ ] },
"procedural": { "use": false, "items": [] }
}
},
"query": { "datetime": "...", "current_context": "...", "...": "..." }
},
"tokens": 6546,
"cost": 0.019638,
"wallet_balance": 88.28846
}
}Response fields
stored: boolean. Whether anything was written.bytes: integer. Size of the raw content stored.embedding_bytes: integer. Size of the generated embeddings — typically far larger than the content itself.total_storage_bytes: integer. What this call added to your storage total.data.data.should_store_memory: boolean. Whether the extraction step judged the content worth keeping.data.data.memory_decisions: object keyed bysemantic,episodic, andprocedural. Each has auseflag and anitemsarray describing what was written — theoperation(CREATEorUPDATE), areason, and the entity or document involved.data.query: the resolved context used for extraction, includingdatetimeand the prior semantic, episodic, and procedural context considered.tokens,cost,wallet_balance: same meaning as onsearch.
Update and delete
Errors
{
"success": true,
"message": "Success",
"data": {
"valid": false,
"error": "not_found",
"message": "API key not found"
}
}A malformed body returns 422 with a detail array naming the offending field. Note this response is not wrapped in the standard envelope.
{
"detail": [
{
"type": "missing",
"loc": ["body", "query"],
"msg": "Field required",
"input": {}
}
]
}200— handled. Checkdata.validbefore trusting the payload.405— wrong method. All three endpoints are POST.422— a required field is missing or the wrong type.
Prefer an SDK?
Both official SDKs wrap these three endpoints, add automatic retries, and ship full type definitions. See the Python SDK and the JavaScript SDK.