Home/Tutorials/Persistent memory
Tutorial 03 Intermediate ~8 min

Build persistent agent memory with signed receipts

By the end of this tutorial you'll have stored multiple memories for an agent, retrieved them semantically across sessions, walked the receipt chain to prove tamper-evidence, and exported the full chain for regulator audit. The memory layer that makes your agents auditable in production.

PREREQUISITES Completed Tutorial 01 and Tutorial 02. You should have $DCS_API_KEY and $DCS_AGENT_ID set in your shell.

Step 01 Store multiple related memories

Store three memories that an agent might accumulate during a real conversation:

# Memory 1 — user preferences
curl -X POST https://api.dcslabs.ai/v1/memory/store \
  -H "Authorization: Bearer $DCS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "0348",
    "content": "User prefers vegetarian food, allergic to peanuts",
    "tags": ["preferences", "diet"]
  }'

# Memory 2 — context about the user
curl -X POST https://api.dcslabs.ai/v1/memory/store \
  -H "Authorization: Bearer $DCS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "0348",
    "content": "User lives in Mumbai, prefers dark mode in apps",
    "tags": ["preferences", "location"]
  }'

# Memory 3 — a recent decision
curl -X POST https://api.dcslabs.ai/v1/memory/store \
  -H "Authorization: Bearer $DCS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "0348",
    "content": "Agreed to a weekly meal-prep schedule, Sundays at 6pm",
    "tags": ["decisions", "schedule"]
  }'

Each call returns a memory_id and receipt_id. Each receipt_id is an R+2 signed receipt linking to the previous receipt in your agent's chain.

Step 02 Semantic search — query with different words

Now ask your agent something related to the stored memories but in different words:

curl -X POST https://api.dcslabs.ai/v1/memory/search \
  -H "Authorization: Bearer $DCS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "0348",
    "query": "what should I cook for this user?",
    "top_k": 3
  }'

Expected response:

{
  "results": [
    {
      "memory_id": "mem_a83f12cd",
      "content":  "User prefers vegetarian food, allergic to peanuts",
      "cosine_similarity": 0.612,
      "receipt_id": "r2_a83f12cd"
    },
    {
      "memory_id": "mem_b91d34ef",
      "content":  "Agreed to a weekly meal-prep schedule, Sundays at 6pm",
      "cosine_similarity": 0.487,
      "receipt_id": "r2_b91d34ef"
    },
    {
      "memory_id": "mem_c47a89bd",
      "content":  "User lives in Mumbai, prefers dark mode in apps",
      "cosine_similarity": 0.212,
      "receipt_id": "r2_c47a89bd"
    }
  ]
}

The agent found the diet preference and the meal-prep decision (both relevant), and ranked the unrelated "dark mode" memory third. Semantic search means your agent finds the right memory even when the query uses different words from what was stored.

Step 03 Walk the receipt chain

Every memory write linked to the previous one cryptographically. Walk the chain to see this:

curl "https://api.dcslabs.ai/v1/receipts/chain?agent_id=0348&limit=10" \
  -H "Authorization: Bearer $DCS_API_KEY"

You'll see your three receipts in order, each with a prev_receipt_cid pointing to the previous one. The first receipt has prev_receipt_cid: null — it's the genesis of your agent's chain.

Any of these can be cryptographically verified independently — without trusting our server. Pipe one through r2-verify:

curl "https://api.dcslabs.ai/v1/receipts/r2_a83f12cd" | \
  npx @trdnetwork/r2-verify --pubkey $(# your pubkey from /agents/0348)

Step 04 Test cross-session persistence

The point of persistent memory is that it survives restarts. Test it:

  1. Close your terminal completely.
  2. Open a fresh terminal — no environment variables set.
  3. Set them again from scratch:
export DCS_API_KEY="dcs_sk_live_..."
export DCS_AGENT_ID="0348"

Now query memory — it's still all there:

curl -X POST https://api.dcslabs.ai/v1/memory/search \
  -H "Authorization: Bearer $DCS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "agent_id": "0348", "query": "diet preferences" }'
PROVEN PERSISTENCE The memory survived a complete shell restart. In production, it also survives backend deploys, region failover (us-east-1 ↔ eu-west-1), and database restarts — because pgvector + the R+2 receipt chain are the source of truth, not in-process state.

Step 05 Export the full memory chain

For regulator audit or for migrating to a different DCS deployment, export everything:

curl "https://api.dcslabs.ai/v1/memory/export?agent_id=0348&format=json" \
  -H "Authorization: Bearer $DCS_API_KEY" \
  > agent-0348-memory-export.json

You get back a single JSON file containing:

This export is what you hand to a regulator if they ask "what does this agent know and when did it learn it?". Every entry is independently verifiable.

Step 06 Logical delete (right to be forgotten)

Under GDPR / DPDP / CCPA, users have the right to have their data deleted. R+2 receipts are immutable by design (that's the security property), but the content they reference can be purged:

curl -X DELETE https://api.dcslabs.ai/v1/memory/mem_a83f12cd \
  -H "Authorization: Bearer $DCS_API_KEY"

Response:

{
  "ok": true,
  "memory_id": "mem_a83f12cd",
  "deleted_at": "2026-05-21T15:50:22Z"
}

What this does:

Architecture under the hood

What you just used:

Pricing on free tier

The free tier covers:

If you hit the cap, the API returns 429. Builder tier ($29/mo) bumps you to 50K writes / 500K queries. Sovereign tier is custom.

What's next