Skip to content

§ 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

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.

headers
Shell
# 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.

response envelope
JSON
{
  "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.

POST /api/memory/details
Shell
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. Every search and add draws from it.

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 returns 422.
  • previous_context: string, optional. Prior context that scopes the search.
POST /api/memory/search
Shell
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.
POST /api/memory/add
Shell
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 by semantic, episodic, and procedural. Each has a use flag and an items array describing what was written — the operation (CREATE or UPDATE), a reason, and the entity or document involved.
  • data.query: the resolved context used for extraction, including datetime and the prior semantic, episodic, and procedural context considered.
  • tokens, cost, wallet_balance: same meaning as on search.

Update and delete

Errors

invalid key · HTTP 200
JSON
{
  "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.

missing field · HTTP 422
JSON
{
  "detail": [
    {
      "type": "missing",
      "loc": ["body", "query"],
      "msg": "Field required",
      "input": {}
    }
  ]
}
  • 200 — handled. Check data.valid before 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.