Memory

Let chat recall stored facts and capture new ones. Memory is on by default for signed-in keys and off for developer keys until a request opts in.

Memory gives chat two independent abilities, each set per request in the memory object. Recall reads the stored memories most relevant to the turn into it as background context. Capture lets the gateway store a durable fact from the turn for later ones. When a request sends no memory object, the key decides whether each one runs.

Defaults depend on the key

KeyRecall and capture when memory is omittedbucket in GET /api/v1/limits
Signed-in credential: device login, OAuth login, and the Cruxy web app, desktop, CLI, and mobileOnsubscription
Developer API key, created in the Cruxy ConsoleOffapikey
Headless keyOffheadless

A key minted by device login or OAuth login is a signed-in credential whichever client ran the flow, a third-party tool included. A developer key's memory is off because the key often serves people other than its owner: recall would put the owner's stored memory into their turns, and capture would store what they say. Use a developer API key for a server; see Get your API key.

Opt in from a developer key

Send true for each side you want. This request comes from an internal tool that only the key's owner uses, so it recalls the owner's memory and lets the turn store a new fact:

curl https://api.cruxy.ai/api/v1/chat \
  -H "Authorization: Bearer $CRUXY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "vaani",
    "stream": false,
    "memory": { "recall": true, "capture": true },
    "messages": [
      { "role": "user", "content": "I work in IST. When should our weekly sync with the London team be?" }
    ]
  }'

true needs a key whose allowed scopes include the memory family. An unscoped key has every family. A key without it gets 403 key_scope_forbidden, refused before anything is billed:

Error fieldValue
codekey_scope_forbidden
required_scopememory
allowed_scopesThe key's own families, for example ["chat"]

A 403 never clears by waiting. A key whose allowed scopes omit memory can never use memory through chat, which makes it the key to issue for a service that must never see anyone's memory.

What recall adds

Recall draws on the same resolved view GET /api/v1/memories lists: your personal memory, your organization's, and every vault you can read whose memory_scope is default.

  • vault_id names the vault a chat is inside. Inside a vault_only vault, recall draws on that vault's memory alone, without personal or organization memory. A vault_id you cannot read is treated as if you sent none, never reported.
  • mentioned_vault_ids adds up to three vaults the turn references, such as an @VersionGate your picker resolved. Mentions share the turn's recall budget rather than enlarging it, and never make a vault writable.
  • Billing. The recalled block is billed input, so input tokens fall by its size when recall is off.

The response reports what was recalled in cruxy.memory_recall: the scope and key of each memory, and for a vault memory its vault_id (and vault_name when it resolves). It never includes the stored value, and the field is absent when nothing was recalled.

{
  "cruxy": {
    "request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "routed_tier": "vaani",
    "reasoning_effort": "low",
    "memory_recall": {
      "count": 1,
      "items": [{ "scope": "personal", "key": "timezone" }]
    }
  }
}

What capture stores

After the turn is answered, capture decides whether the exchange held a durable fact, such as a stated preference, a stable setting, or a constraint about your work, and stores it.

  • Where it goes. Your personal memory, or the vault the request's vault_id names when you can write to it. A vault you can only read demotes the capture to your personal memory. Capture never writes organization-wide memory, whatever your role.
  • What it drops. Content carrying an email address, a phone number, or a card number is dropped before any write.
  • What it reports. Every capture appears in cruxy.memory_capture, with the scope and key of each memory stored and never the value. No field means nothing was stored.
  • What it never does. Capture cannot fail or delay a turn. If extraction is unavailable, it stores nothing.

On a stream, memory_recall rides the role primer and memory_capture rides the terminal usage frame, because what a turn stored is known only once the answer is complete.

Turn memory off for one request

Any key may send false for either side, and false needs no scope:

{ "memory": { "recall": false, "capture": false } }

recall: false reads no memory and ignores mentioned_vault_ids. capture: false stores nothing. The two are independent, so { "capture": false } alone keeps the turn personalized by what is already stored while adding nothing new.

Pin Cruxy-Version: 2026-09-26 on every request that relies on false. A gateway that predates the field would ignore it and capture anyway; with the pin, such a gateway refuses the request with 400 unknown_version instead. A server should use a developer API key. If a signed-in credential does serve other people, every request must send both false values, and rules: false, or the owner's memory and rules reach their turns.

Review and remove what is stored

  • GET /api/v1/memories lists your effective memory, one entry per key, with the id of the row that won.
  • DELETE /api/v1/memories/{id} removes that entry. You can delete what you can write: your own memories, a vault's where your membership grants can_write, and organization memory if you are an owner or admin.
  • PUT /api/v1/memories stores a value by hand. A key or value carrying an email address, a phone number, or a card number is refused with 400 pii_rejected, and nothing is stored.

API Reference has every field of the memories endpoints.

Next steps

Was this page helpful?