Patterns and recipes
This page collects short, copyable curl recipes for the most common Dakera tasks: prompt context, conversations, expiring task memory, the knowledge graph, consolidation, feedback, migration, multi-tenant keys, event streams and auditing, plus a checklist before going to production. It is for developers wiring Dakera into an agent; the full architecture write-ups live in the Patterns Library.
Browse all patterns
Patterns Library →The Patterns Library covers user preference recall, cross-session context, multi-agent memory, knowledge graphs, session handoff, semantic deduplication, RAG augmentation and batch ingestion, each with an explanation and working code. The examples below assume a server on localhost:3000 and an API key in $DAKERA_API_KEY.
Quick reference: common recipes
Ground an LLM's answers in what the agent remembers: store facts as they come up, and recall the relevant ones before each generation.
# 1. Store a memory from conversation
curl -X POST http://localhost:3000/v1/memory/store \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "assistant",
"content": "User prefers dark mode and concise responses",
"importance": 0.8,
"tags": ["preference"]
}'
# 2. Before generating a response, recall relevant context
curl -X POST http://localhost:3000/v1/memory/recall \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "assistant",
"query": "What does the user prefer?",
"top_k": 5
}'
# 3. Inject recalled memories into your system prompt
# system_prompt = f"Context from memory:\n{memories}\n\nRespond to the user."
Conversation memory
Store and recall multi-turn conversation context. Use sessions to group memories by conversation thread:
# Start a session
curl -X POST http://localhost:3000/v1/sessions/start \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agent_id": "chat-agent", "metadata": {"user": "u_123", "channel": "web"}}'
# Store each turn with the session
curl -X POST http://localhost:3000/v1/memory/store \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "chat-agent",
"session_id": "sess_abc123",
"content": "User asked about billing. Explained monthly vs annual pricing.",
"importance": 0.7,
"memory_type": "episodic"
}'
# End session with summary
curl -X POST http://localhost:3000/v1/sessions/sess_abc123/end \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"summary": "Discussed billing options. User chose annual plan."}'
Task memory with TTL
Short-lived memories that auto-expire. Use expires_at (Unix timestamp) for task-scoped context that shouldn't persist after completion:
curl -X POST http://localhost:3000/v1/memory/store \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "task-agent",
"content": "Working on PR #123 — fixing auth middleware",
"importance": 0.3,
"expires_at": 1778800000,
"tags": ["ephemeral", "task"],
"metadata": {"pr": 123, "repo": "backend"}
}'
Knowledge base construction
Build a structured knowledge base using entities and the knowledge graph. Store facts, extract entities, then link related knowledge:
# Store a fact (tagged with entities when the agent's namespace has extract_entities on)
curl -X POST http://localhost:3000/v1/memory/store \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "kb-builder",
"content": "React 19 introduces use() hook for async data fetching. Released January 2025.",
"importance": 0.9,
"memory_type": "semantic",
"tags": ["react", "frontend"]
}'
# Extract entities from a piece of text (nothing is stored)
curl -X POST http://localhost:3000/v1/memories/extract \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"content": "React 19 introduces use() hook for async data fetching.", "entity_types": ["technology"]}'
# Traverse the knowledge graph outward from a memory
curl -X POST http://localhost:3000/v1/knowledge/graph \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agent_id": "kb-builder", "memory_id": "<memory-id>", "depth": 2}'
Agent wake-up context
Load an agent's working context at startup with filter-based batch recall (no query, no embedding). Useful for scheduled agents and agents resuming after idle time; GET /v1/agents/{id}/wake-up is the built-in alternative.
# Recall high-importance recent memories
curl -X POST http://localhost:3000/v1/memories/recall/batch \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "my-agent",
"filter": {
"min_importance": 0.7,
"created_after": 1778000000,
"tags": ["critical", "decision"]
},
"limit": 50
}'
# Also recall blockers and pending handoffs
curl -X POST http://localhost:3000/v1/memories/recall/batch \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "my-agent",
"filter": {"tags": ["blocker", "handoff"], "min_importance": 0.5}
}'
# Get agent stats to assess memory health
curl http://localhost:3000/v1/agents/my-agent/stats \
-H "Authorization: Bearer $DAKERA_API_KEY"
Memory consolidation pipeline
Merge redundant memories on demand, for example after a bulk import or a long session. AutoPilot already deduplicates and consolidates in the background; these calls are for when you want it now or want to choose the memories:
# Consolidate chosen memories into one (a memory with an attachment, a TTL or user metadata is refused)
curl -X POST http://localhost:3000/v1/memory/consolidate \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agent_id": "my-agent", "memory_ids": ["<memory-id-1>", "<memory-id-2>"]}'
# Deduplicate: merge true duplicates (preview with dry_run; refused past 5,000 memories to compare)
curl -X POST http://localhost:3000/v1/knowledge/deduplicate \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agent_id": "my-agent", "threshold": 0.95, "dry_run": true}'
# Summarize chosen memories into one compressed memory
curl -X POST http://localhost:3000/v1/knowledge/summarize \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agent_id": "my-agent", "memory_ids": ["<memory-id-1>", "<memory-id-2>"]}'
Hybrid search patterns
Recall searches by meaning (vector), by keyword (BM25) or both. By default the server picks per query; set routing to force one:
| Pattern | Mode | When to use |
|---|---|---|
| Semantic recall | routing: "vector" | Meaning-based — "what does the user prefer?" |
| Keyword lookup | routing: "bm25" | Exact terms — error codes, IDs, names |
| Hybrid | routing: "hybrid" | Vector and BM25 results fused into one ranking |
| Automatic (default) | routing: "auto" (or omitted) | The server classifies the query and picks the backend |
# Force hybrid routing
curl -X POST http://localhost:3000/v1/memory/recall \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "my-agent",
"query": "authentication error ERR_AUTH_401",
"routing": "hybrid",
"top_k": 10
}'
# Exact terms: force BM25 full-text routing (no query embedding)
curl -X POST http://localhost:3000/v1/memory/recall \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agent_id": "my-agent", "query": "ERR_AUTH_401", "routing": "bm25", "top_k": 5}'
Cross-agent knowledge network
Agents are isolated. To see what several agents have in common, map the shared entities and related memories across them:
# Map shared entities and related memories across agents
curl -X POST http://localhost:3000/v1/knowledge/network/cross-agent \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_ids": ["agent-a", "agent-b", "supervisor"],
"min_similarity": 0.8,
"max_nodes_per_agent": 50
}'
# Link two memories of the same agent (404 unless both are live memories of that agent)
curl -X POST http://localhost:3000/v1/memories/mem_abc/links \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agent_id": "my-agent", "target_id": "mem_xyz", "label": "related"}'
Memory feedback loop
Feedback is how importance moves after a memory is stored; a recall itself does not change it. An upvote raises importance by 0.05 plus 5% of its current value (at most 1.0), a downvote lowers it by 0.15, and flag marks the memory as irrelevant without changing its importance:
# Upvote a memory that was useful
curl -X POST http://localhost:3000/v1/memories/mem_abc/feedback \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agent_id": "my-agent", "signal": "upvote"}'
# Downvote an irrelevant result
curl -X POST http://localhost:3000/v1/memories/mem_xyz/feedback \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agent_id": "my-agent", "signal": "downvote"}'
# Get feedback summary for an agent
curl http://localhost:3000/v1/agents/my-agent/feedback/summary \
-H "Authorization: Bearer $DAKERA_API_KEY"
Migration from Mem0 / Zep
Bring memories over from another memory system, or move them between Dakera servers. Import and export support Mem0, Zep, JSONL and CSV:
# Import an export file (multipart upload; format is auto-detected or explicit)
curl -X POST "http://localhost:3000/v1/import?agent_id=my-agent&format=mem0" \
-H "Authorization: Bearer $DAKERA_API_KEY" \
-F file=@mem0-export.json
# Check the import job
curl http://localhost:3000/v1/import/<job_id>/status \
-H "Authorization: Bearer $DAKERA_API_KEY"
# Export from Dakera (for backup or migration)
curl "http://localhost:3000/v1/export?agent_id=my-agent&format=jsonl" \
-H "Authorization: Bearer $DAKERA_API_KEY" -o my-agent.jsonl
jsonl (default), csv, mem0, zep. Export carries plaintext content and TTLs; each imported item is limited to 100,000 bytes of content, and an import into another agent's namespace is rewritten to the importing agent. A key needs read (export) or write (import) access to the agent's namespace.Namespace isolation for multi-tenant apps
An agent's memories live in the namespace _dakera_agent_<agent_id>. To isolate a tenant, give it an agent id and an API key pinned to that agent's namespace. The namespace must exist, which it does after the agent's first store:
# The tenant's first memory creates its namespace (_dakera_agent_acme-bot)
curl -X POST http://localhost:3000/v1/memory/store \
-H "Authorization: Bearer $DAKERA_ROOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agent_id": "acme-bot", "content": "Acme user prefers metric units"}'
# Create a key pinned to that namespace (scope: read, write or admin)
curl -X POST http://localhost:3000/v1/namespaces/_dakera_agent_acme-bot/keys \
-H "Authorization: Bearer $DAKERA_ROOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "acme-prod-key", "scope": "write"}'
# The pinned key reaches only that agent's memories
curl -X POST http://localhost:3000/v1/memory/recall \
-H "Authorization: Bearer $ACME_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agent_id": "acme-bot", "query": "units", "top_k": 5}'
/admin/* apart from four per-namespace routes, /ops/*, /v1/analytics/*, /v1/audit*, /v1/events/stream, ...): those answer 403. Backup download, upload and restore need a global super_admin key. Per-namespace limits are enforced as quotas (413 QUOTA_EXCEEDED). See Security.Real-time event streaming
Follow memory lifecycle events as Server-Sent Events, for dashboards, audit trails or agents that react to changes. The stream carries every agent's events and needs a global admin key (no namespace restriction):
# Stream memory events (all agents)
curl -N http://localhost:3000/v1/events/stream \
-H "Authorization: Bearer $DAKERA_ROOT_API_KEY"
# Each event is an SSE event named after its type, with a JSON body, for example:
# event: stored
# data: {"event_type":"stored","agent_id":"my-agent","memory_id":"mem_abc","importance":0.8,"timestamp":1778800000000}
Event types: stored, recalled, decayed, forgotten, consolidated, session_started, session_ended, importance_updated. The stream opens with a connected event, sends a keep-alive every 15 s, and emits stream_lagged when a slow client dropped events (reconnect to resume). Timestamps are Unix milliseconds.
Audit logging & compliance
The audit API is a queryable log of the memory lifecycle events (stored, recalled, decayed, forgotten, consolidated, importance_updated, session_started, session_ended); it needs a global admin key:
# Query the audit log for a specific agent (from / to are Unix milliseconds)
curl "http://localhost:3000/v1/audit?agent_id=my-agent&event_type=forgotten&from=1778000000000&to=1778800000000&limit=100" \
-H "Authorization: Bearer $DAKERA_ROOT_API_KEY"
# Export it, or follow it live
curl "http://localhost:3000/v1/audit/export?agent_id=my-agent" -H "Authorization: Bearer $DAKERA_ROOT_API_KEY"
curl -N http://localhost:3000/v1/audit/stream -H "Authorization: Bearer $DAKERA_ROOT_API_KEY"
Production deployment checklist
Before going live, check each of these:
| Check | Command / verification |
|---|---|
| Health endpoints | Readiness probe on GET /, liveness on GET /; GET /health reports "status": "healthy" with empty degraded and config_warnings |
| Configuration checked | dakera -- against the production environment and data volume exits 0 |
| API key set | DAKERA_ is a strong, unique value |
| Persistent storage | Data volume mounted: - |
| Backup configured | POST / (global super_admin key; optional encrypt and compression), and a restore tested; a stored backup schedule runs in v0.12 |
| AutoPilot running | On by default (deduplication every 6 h, consolidation every 12 h); GET / shows the last runs. Decay runs separately every hour |
| Entity extraction | The GLiNER model (about 782 MB) downloads on the first store into a namespace that extracts entities; pre-fetch with dakera models pull gliner |
| Tenant isolation | One agent per tenant, with a key pinned to its namespace; never share the root key |
| Monitoring | Scrape GET /metrics (Prometheus) and watch degraded in GET /health |
| Resource limits | Set DAKERA_, Docker memory limits |
| TLS termination | Use a reverse proxy (nginx, Caddy) for HTTPS in production |
Related: Deployment guide · Security hardening · Configuration reference · Memory Patterns Library · Multi-Agent Memory Systems
Ship memory-enabled agents
Start with the free binary or Docker image; every recipe on this page runs against it.