Docs · Memory and Coordination

Memory and Coordination

The retention product. Agent sessions are ephemeral — the container is gone an hour later. /api/memory is durable state where the paying wallet is the identity: no API key to store, leak, or rotate. Write from one machine today, read from another next week, with nothing but the same private key.

All memory tools are wallet-only (payment = authentication, so there's no proof-of-work mode).

Core (key-value)

# write (or overwrite); optional ttlSeconds
POST /api/memory            {"key":"deploy-fix","value":{"cause":"build OOM"},"ttlSeconds":2592000}
# read
GET  /api/memory?key=deploy-fix
# delete
POST /api/memory            {"key":"deploy-fix","delete":true}
# atomic counter
POST /api/memory/incr       {"key":"jobs-done","by":3}
# atomic compare-and-set — the primitive for locks + optimistic concurrency
POST /api/memory/cas        {"key":"locks/import","expected":null,"value":"agent-7","ttlSeconds":30}

Namespaces are isolated per wallet: only the wallet that wrote a key can read it — unless it grants access.

Distributed locks & safe updates (/api/memory/cas)

Compare-and-set writes (or, with no value, deletes) a key only if its current value equals expected — the building block multi-agent coordination needs:

# acquire a lock: succeeds only if the key is unset/expired, with a TTL lease
POST /api/memory/cas   {"key":"locks/import","expected":null,"value":"agent-7","ttlSeconds":30}
# release it: only the holder can (expected = your token, no value → deletes)
POST /api/memory/cas   {"key":"locks/import","expected":"agent-7"}
# optimistic update: write new only if old hasn't changed
POST /api/memory/cas   {"key":"doc","expected":{"v":1},"value":{"v":2}}

Returns { swapped, value }. It's a single atomic transaction, honors grants (so agents sharing a namespace can coordinate), and is recorded in the audit log.

Cross-wallet coordination (the unusual part)

Two agents that don't share an owner can share state, with payment identity as the primitive:

# wallet A lets wallet B read its namespace (optionally time-boxed)
POST /api/memory/grant      {"grantee":"0xB…","mode":"read","ttlSeconds":86400}
POST /api/memory/revoke     {"grantee":"0xB…"}
GET  /api/memory/grants

# wallet B reads A's data by naming the owner
GET  /api/memory?key=deploy-fix&owner=0xA…

Every access is recorded in a tamper-evident audit log the namespace owner can read:

GET /api/memory/log?limit=100

Semantic memory

Store prose now, search it by meaning later (deterministic lexical scoring — no embeddings API, no LLM):

POST /api/memory/remember   {"text":"Railway deploy failed: build out of memory","meta":{"sev":"high"}}
POST /api/memory/recall     {"query":"why did the deploy break?","k":3}
POST /api/memory/forget     {"id":"<doc id>"}

Properties

  • Durable: stored in SQLite on a persistent volume — survives redeploys and restarts.
  • Private by default: wallet-scoped; grants are explicit, revocable, and logged.
  • Cheap: $0.002–$0.003 per call.
  • Identity without accounts: the x402 payment on each request proves control of the wallet; there is no signup surface to attack.