Memory API

Live

Persistent, namespace-isolated semantic memory for AI agents. Store text → embeddings generated automatically. Search by meaning. Forget on command.

Base URL: https://sendryx.polsia.app Model: text-embedding-3-small (1536 dims) Similarity: cosine

Quick Start

Three calls to get persistent memory working in your agent:

# 1. Create an API key (from /app) # Your API key scopes all memory to its namespace automatically. # 2. Store a memory curl -X POST https://sendryx.polsia.app/v1/memory/store \ -H "X-API-Key: sk-gw-your-key" \ -H "Content-Type: application/json" \ -d '{"content": "User prefers concise responses and hates bullet points"}' # → { "success": true, "memory": { "id": 42, "namespace": "prod", "created_at": "..." } } # 3. Search by meaning — returns semantically relevant memories curl "https://sendryx.polsia.app/v1/memory/search?query=user+formatting+preferences" \ -H "X-API-Key: sk-gw-your-key" # → { "results": [{ "id": 42, "content": "...", "similarity": 0.91, "metadata": {} }] }

Authentication

All Memory API endpoints require an API key. Create keys at /app. Every key is bound to a namespace — your memories are automatically isolated.

# Option A: Bearer token header Authorization: Bearer sk-gw-your-key # Option B: X-API-Key header X-API-Key: sk-gw-your-key

Rate Limits

Memory endpoints are rate-limited separately from gateway endpoints. Limits apply per API key.

WindowLimitError
Per minute 60 requests 429 Too Many Requests — includes retry_after_seconds
Per hour 600 requests 429 Too Many Requests — includes retry_after_seconds

Store and search generate embeddings on every call — rate limits protect against runaway embedding costs from misbehaving agents.

TTL & Expiry

Memories can be permanent (default) or short-lived. Set expires_in_seconds on store to create a TTL.

# Short-term memory: expires in 1 hour { "content": "Current conversation context: user is debugging a payment bug", "expires_in_seconds": 3600 } # Long-term memory: permanent (no TTL) { "content": "User's Stripe account ID is acct_1234" // no expires_in_seconds field }
  • Expired memories are excluded from search results automatically
  • Expired memories are excluded from list results by default (use include_expired=true to see them)
  • Expired rows are purged from the database hourly via background cleanup
  • GET /v1/memory/stats shows counts for permanent, active TTL, and expired memories

Endpoints

POST /v1/memory/store

Store a memory. Embeddings are auto-generated — just pass text.

Request Body

FieldTypeRequiredDescription
content string Required Text to store. Max 8,191 characters (embedding model limit). Will be trimmed.
metadata object Optional Arbitrary JSON attached to the memory. Returned with search/list results. Default: {}
expires_in_seconds integer Optional TTL in seconds from now. Omit for permanent memory. E.g. 3600 = 1 hour.

Example

curl -X POST https://sendryx.polsia.app/v1/memory/store \ -H "X-API-Key: sk-gw-your-key" \ -H "Content-Type: application/json" \ -d '{ "content": "Alice is a premium subscriber who prefers email over SMS", "metadata": { "user_id": "u_alice", "source": "onboarding" }, "expires_in_seconds": 2592000 }' // Response { "success": true, "memory": { "id": 42, "namespace": "production", "content": "Alice is a premium subscriber who prefers email over SMS", "metadata": { "user_id": "u_alice", "source": "onboarding" }, "created_at": "2026-04-05T18:00:00Z", "expires_at": "2026-05-05T18:00:00Z" } }
DELETE /v1/memory/forget

Delete a specific memory by ID, or wipe an entire namespace. Explicit action required — nothing auto-wipes.

Options

FieldSourceDescription
id body { id: N } or query ?id=N Delete a single memory by ID. Must be a positive integer.
wipe body { wipe: true } or query ?wipe=true Delete ALL memories in the namespace. Irreversible.

Examples

# Delete one memory by ID curl -X DELETE "https://sendryx.polsia.app/v1/memory/forget?id=42" \ -H "X-API-Key: sk-gw-your-key" // → { "success": true, "deleted": 1, "message": "Memory 42 deleted" } # Wipe entire namespace curl -X DELETE "https://sendryx.polsia.app/v1/memory/forget?wipe=true" \ -H "X-API-Key: sk-gw-your-key" // → { "success": true, "deleted": 107, "message": "Cleared 107 memories from namespace: production" }
GET /v1/memory/list

List all memories in the namespace with pagination. Returns most recent first.

Query Parameters

ParamTypeDefaultDescription
limit integer 50 Records per page. Max: 200.
offset integer 0 Pagination offset.
include_expired boolean false Include expired memories in the result. Set to true to see all records including past-TTL ones.
GET /v1/memory/stats

Memory counts by type: total, permanent, active TTL, expired, oldest/newest timestamps.

curl "https://sendryx.polsia.app/v1/memory/stats" \ -H "X-API-Key: sk-gw-your-key" // Response { "success": true, "namespace": "production", "stats": { "total_memories": "247", "permanent": "180", "active_ttl": "55", "expired": "12", "oldest_at": "2026-01-15T09:00:00Z", "newest_at": "2026-04-05T17:45:00Z" } }
GET /v1/memory/usage

Per-namespace API call counts and storage usage estimate.

curl "https://sendryx.polsia.app/v1/memory/usage" \ -H "X-API-Key: sk-gw-your-key" // Response { "success": true, "namespace": "production", "calls": { "total_stores": "1842", "total_searches": "9341", "total_deletes": "23", "total_wipes": "0", "last_called_at": "2026-04-05T17:55:00Z" }, "storage": { "total_memories": 247, "permanent_count": 180, "active_ttl_count": 55, "expired_count": 12, "content_bytes": 84320, "embedding_bytes": 1516416, "total_bytes": 1600736, "total_kb": "1563.21", "total_mb": "1.5266" } }

Embedding bytes estimated at 1536 floats × 4 bytes per memory. Content bytes are exact character length.


Error Codes

StatusWhenResponse
400 Missing required fields, invalid ID, or no action specified on forget { "success": false, "message": "..." }
401 Missing or invalid API key { "success": false, "message": "API key required..." }
404 Memory ID not found in namespace { "success": false, "message": "Memory 42 not found..." }
429 Rate limit exceeded { "success": false, "message": "...", "retry_after_seconds": 12 }
500 Server error (e.g. OpenAI key not configured) { "success": false, "message": "OpenAI not configured..." }