SDK Endpoint Contract
Canonical HTTP routes, request/response shapes, and error semantics for SDK integrations.
This page is the canonical contract for the SDK HTTP surface under /api/sdk/v1/*.
Use it when implementing direct HTTP integrations, debugging SDK client behavior, or validating backward compatibility in CI.
Transport clarification:
- SDK default transport is this HTTP surface (
/api/sdk/v1/*). - SDK can optionally use MCP JSON-RPC (
/api/mcp) when you configuretransport: "mcp"(or pointbaseUrlat/api/mcp). - CLI commands are separate tooling and are not used by SDK runtime calls.
Base URL
https://memories.shEndpoint Matrix
| Group | Route | Methods | Auth |
|---|---|---|---|
| Health | /api/sdk/v1/health | GET | None |
| Runtime | /api/sdk/v1/context/get | POST | Bearer API key (mem_...) |
| Runtime | /api/sdk/v1/memories/add | POST | Bearer API key (mem_...) |
| Runtime | /api/sdk/v1/memories/search | POST | Bearer API key (mem_...) |
| Runtime | /api/sdk/v1/memories/list | POST | Bearer API key (mem_...) |
| Runtime | /api/sdk/v1/memories/edit | POST | Bearer API key (mem_...) |
| Runtime | /api/sdk/v1/memories/forget | POST | Bearer API key (mem_...) |
| Runtime | /api/sdk/v1/memories/bulk-forget | POST | Bearer API key (mem_...) |
| Runtime | /api/sdk/v1/memories/vacuum | POST | Bearer API key (mem_...) |
| Runtime | /api/sdk/v1/memories/consolidate | POST | Bearer API key (mem_...) |
| Runtime | /api/sdk/v1/skills/files/upsert | POST | Bearer API key (mem_...) |
| Runtime | /api/sdk/v1/skills/files/list | POST | Bearer API key (mem_...) |
| Runtime | /api/sdk/v1/skills/files/delete | POST | Bearer API key (mem_...) |
| Runtime | /api/sdk/v1/skills/files/promote | POST | Bearer API key (mem_...) |
| Runtime | /api/sdk/v1/sessions/start | POST | Bearer API key (mem_...) |
| Runtime | /api/sdk/v1/sessions/checkpoint | POST | Bearer API key (mem_...) |
| Runtime | /api/sdk/v1/sessions/end | POST | Bearer API key (mem_...) |
| Runtime | /api/sdk/v1/sessions/{sessionId}/snapshot | GET | Bearer API key (mem_...) |
| Runtime | /api/sdk/v1/embeddings/models | GET | Bearer API key (mem_...) or session |
| Graph | /api/sdk/v1/graph/status | GET, POST | Bearer API key (mem_...) |
| Graph | /api/sdk/v1/graph/trace | POST | Bearer API key (mem_...) |
| Graph | /api/sdk/v1/graph/rollout | GET, POST, PATCH | Bearer API key (mem_...) |
| Management | /api/sdk/v1/management/keys | GET, POST, DELETE | Legacy management auth (session/legacy path) |
| Management | /api/sdk/v1/management/tenant-overrides | GET, POST, DELETE | Bearer API key (mem_...) or session |
| Management | /api/sdk/v1/management/embeddings/usage | GET | Bearer API key (mem_...) or session |
| Management | /api/sdk/v1/management/embeddings/backfill | GET, POST | Bearer API key (mem_...) or session |
| Management | /api/sdk/v1/management/embeddings/observability | GET | Bearer API key (mem_...) or session |
| Management | /api/sdk/v1/management/memory/observability | GET | Bearer API key (mem_...) or session |
| Management | /api/sdk/v1/management/memory/eval/replay | POST | Bearer API key (mem_...) or session |
Legacy aliases are still available:
/api/mcp/key
Authentication
Runtime + graph endpoints
Send your API key:
Authorization: Bearer mem_xxx
Content-Type: application/jsonManagement endpoints
Use /api/sdk/v1/management/tenant-overrides for headless server-to-server tenant routing management.
Canonical Response Envelope
Every SDK v1 endpoint returns this envelope shape.
Success:
{
"ok": true,
"data": {},
"error": null,
"meta": {
"version": "2026-02-11",
"endpoint": "/api/sdk/v1/context/get",
"requestId": "3a4f3fc2-24ea-4e9e-ac61-6f2807f39584",
"timestamp": "2026-02-11T12:00:00.000Z"
}
}Failure:
{
"ok": false,
"data": null,
"error": {
"type": "validation_error",
"code": "INVALID_REQUEST",
"message": "Invalid request payload",
"status": 400,
"retryable": false,
"details": {
"field": "tenantId"
}
},
"meta": {
"version": "2026-02-11",
"endpoint": "/api/sdk/v1/memories/add",
"requestId": "8f2c34e5-2ed5-4a2f-92ea-c9d9faaf8db0",
"timestamp": "2026-02-11T12:00:00.000Z"
}
}Error Semantics
Error types
auth_error(401,403)validation_error(400,409)not_found_error(404)rate_limit_error(429)internal_error(500+)unknown_error(fallback classification)
Common error codes
| Code | Typical status | Notes |
|---|---|---|
MISSING_API_KEY | 401 | Runtime/graph endpoint called without Authorization |
INVALID_API_KEY_FORMAT | 401 | Bearer token format is invalid |
INVALID_API_KEY | 401 | Key hash not found |
API_KEY_EXPIRED | 401 | Key exists but expired |
RATE_LIMITED | 429 | Includes details.retryAfterSeconds |
INVALID_REQUEST | 400 | JSON shape/validation failed |
QUERY_REQUIRED | 400 | Empty query for search |
TENANT_ID_INVALID | 400 | Invalid scope.tenantId |
USER_ID_INVALID | 400 | Invalid scope.userId |
DATABASE_NOT_CONFIGURED | 400 | No active workspace DB for API key owner |
TENANT_DATABASE_NOT_CONFIGURED | 404 | Unknown AI SDK Project (tenantId) mapping (auto-provision may create this mapping when enabled) |
TENANT_DATABASE_NOT_READY | 409 | Tenant DB mapping exists but not ready |
TENANT_DATABASE_CREDENTIALS_MISSING | 404 | Tenant mapping missing credentials |
CANARY_ROLLOUT_BLOCKED | 409 | Quality gate blocked canary rollout |
INTERNAL_ERROR | 500 | Fallback internal error code |
LEGACY_MCP_KEY_ERROR | passthrough | Management keys wrapper error |
Scope Model
Runtime + graph requests accept optional scoped routing under scope:
{
"scope": {
"tenantId": "acme-prod",
"userId": "user_123",
"projectId": "github.com/acme/platform"
}
}tenantId: AI SDK Project selector (security/database boundary)userId: end-user scope insidetenantIdprojectId: optional repository context filter (not an auth boundary)
If tenantId is omitted, the request uses the API key owner's active workspace DB.
Request Constraints (Selected)
| Field | Constraint |
|---|---|
query | max 500 chars |
content (memories/add, memories/edit) | 1..8000 chars |
limit (context/get, search, trace) | 1..50 |
limit (memories/list) | 1..100 |
graphDepth | 0, 1, or 2 |
graphLimit | 1..50 |
tags[] | max 50 tags, each 1..120 chars |
paths[] | max 100 paths, each 1..300 chars |
category | 1..120 chars |
sessionId (sessions/*, skills/files/promote) | 1..120 chars |
content (sessions/checkpoint) | 1..16000 chars |
title (sessions/start) | 1..240 chars |
client (sessions/start) | 1..120 chars |
model (memories/consolidate) | 1..160 chars |
path (skills/files/*) | 1..400 chars |
title (skills/files/promote) | 1..200 chars |
procedureKey (skills/files/promote) | 1..120 chars |
maxSteps (skills/files/promote) | integer 3..20 |
content (skills/files/upsert) | 1..120000 chars |
Runtime Endpoint Contracts
POST /api/sdk/v1/context/get
Retrieve context bundle (rules + memories + trace).
Request:
{
"query": "deployment process",
"limit": 5,
"includeRules": true,
"includeSkillFiles": true,
"mode": "all",
"strategy": "hybrid",
"graphDepth": 1,
"graphLimit": 8,
"scope": {
"tenantId": "acme-prod",
"userId": "user_123",
"projectId": "github.com/acme/platform"
}
}Defaults:
limit:5includeRules:trueincludeSkillFiles:truemode:allstrategy: policy default (lexicaluntil rollout policy promotes tohybrid)graphDepth:1graphLimit:8
Strategy aliases accepted for backward compatibility (deprecated):
baseline→lexicalhybrid_graph→hybrid
When aliases are used through @memories.sh/core, the client emits a one-time deprecation warning.
Set MEMORIES_SUPPRESS_DEPRECATION_WARNINGS=true to silence those warnings in controlled environments.
Response data:
mode,queryrules[]memories[]conflicts[](optional contradiction pairs when returned memories are linked bycontradictsedges)skillFiles[]workingMemories[]longTermMemories[]trace(strategy, rollout mode, fallback details, candidate counts, retrieval policy diagnostics)
memories[].graph explainability (present for graph-expanded memories):
whyIncluded:graph_expansionlinkedViaNode: graph node label that connected the memoryedgeType: relationship edge used for expansionhopCount: traversal depth from seed memoryconfidence: normalized edge confidence (0..1)seedMemoryId: originating seed memory id
conflicts[] item shape (ConflictPair in @memories.sh/core):
{
"memoryAId": "mem_a",
"memoryBId": "mem_b",
"edgeType": "contradicts",
"confidence": 0.91,
"explanation": "These memories are linked by a contradiction edge from relationship extraction.",
"suggestion": "These memories may conflict. Consider asking the user to clarify which preference is current."
}trace includes rollout + retrieval diagnostics such as:
retrievalPolicyDefaultStrategy,retrievalPolicyAppliedStrategy,retrievalPolicySelectionsemanticStrategyRequested,semanticStrategyApplied,semanticFallbackTriggered,semanticFallbackReasongraphDepth,graphLimit,rolloutMode,shadowExecutedbaselineCandidates,graphCandidates,graphExpandedCount,conflictCount,totalCandidatesfallbackTriggered,fallbackReason
POST /api/sdk/v1/memories/add
Create a memory.
Request:
{
"content": "Use canary rollout for graph retrieval changes",
"type": "rule",
"layer": "rule",
"embeddingModel": "openai/text-embedding-3-small",
"tags": ["rollout", "graph"],
"paths": ["packages/web/src/app/**"],
"category": "ops",
"metadata": {
"source": "runbook"
},
"scope": {
"projectId": "github.com/acme/platform",
"userId": "user_123"
}
}Success status is 201.
Response data:
idmessagememory(structured memory record)embeddingModelembeddingModelSource
POST /api/sdk/v1/memories/search
Search memories by query.
Request:
{
"query": "rollout",
"type": "rule",
"layer": "rule",
"strategy": "hybrid",
"limit": 10,
"scope": {
"userId": "user_123"
}
}Response data:
memories[]counttrace(requestedStrategy,appliedStrategy, fallback + candidate diagnostics)
POST /api/sdk/v1/memories/list
List recent memories with optional filters.
Request:
{
"type": "rule",
"layer": "rule",
"tags": "rollout",
"limit": 20,
"scope": {
"projectId": "github.com/acme/platform",
"userId": "user_123"
}
}Response data:
memories[]count
POST /api/sdk/v1/memories/edit
Update an existing memory.
Request:
{
"id": "mem_abc123",
"content": "Use canary then promote to full rollout after quality checks",
"embeddingModel": "openai/text-embedding-3-small",
"tags": ["rollout", "canary"],
"scope": {
"userId": "user_123"
}
}Requires at least one editable field beyond id (content, type, layer, tags, paths, category, or metadata).
Response data:
idupdated: truemessageembeddingModelembeddingModelSource
POST /api/sdk/v1/memories/forget
Soft-delete a memory.
Request:
{
"id": "mem_abc123",
"scope": {
"userId": "user_123"
}
}Response data:
iddeleted: truemessage
POST /api/sdk/v1/memories/bulk-forget
Bulk soft-delete memories matching filters.
Request:
{
"filters": {
"types": ["note", "fact"],
"tags": ["temporary"],
"olderThanDays": 90,
"pattern": "TODO*",
"projectId": "github.com/acme/platform"
},
"dryRun": false,
"scope": {
"tenantId": "acme-prod",
"userId": "user_123"
}
}Provide at least one filter (types, tags, olderThanDays, or pattern), or use all: true (cannot combine all with other filters).
Response data (dryRun: false):
countids[]message
Response data (dryRun: true):
countmemories[](each withid,type,contentPreview)message
POST /api/sdk/v1/memories/vacuum
Permanently purge all soft-deleted memories to reclaim storage space.
Request:
{
"scope": {
"tenantId": "acme-prod",
"userId": "user_123"
}
}Response data:
purgedmessage
POST /api/sdk/v1/memories/consolidate
Run consolidation to merge duplicates and supersede stale truths within scope.
Feature gate: MEMORY_CONSOLIDATION_ENABLED must be on (403 MEMORY_CONSOLIDATION_DISABLED when off).
Request:
{
"types": ["rule", "decision", "fact"],
"includeGlobal": true,
"globalOnly": false,
"dryRun": true,
"model": "openai/gpt-5-mini",
"scope": {
"tenantId": "acme-prod",
"userId": "user_123",
"projectId": "github.com/acme/platform"
}
}Response data:
runIdmessagerun(id,scope,projectId,userId,inputCount,mergedCount,supersededCount,conflictedCount,model,createdAt,metadata)winnerMemoryIds[]supersededMemoryIds[]
Typical endpoint-specific error codes:
MEMORY_CONSOLIDATION_DISABLED(403)INVALID_REQUEST(400) for schema/shape violations
POST /api/sdk/v1/sessions/start
Start a lifecycle session.
Feature gate: MEMORY_SESSION_ENABLED must be on (403 MEMORY_SESSION_DISABLED when off).
Request:
{
"title": "Auth migration rollout",
"client": "codex",
"metadata": {
"channel": "oncall"
},
"scope": {
"tenantId": "acme-prod",
"userId": "user_123",
"projectId": "github.com/acme/platform"
}
}Success status is 201.
Response data:
sessionIdmessagesession(id,scope,projectId,userId,client,status,title,startedAt,lastActivityAt,endedAt,metadata)
Typical endpoint-specific error codes:
MEMORY_SESSION_DISABLED(403)INVALID_REQUEST(400)
POST /api/sdk/v1/sessions/checkpoint
Append a checkpoint/event to an active session.
Feature gate: MEMORY_SESSION_ENABLED must be on (403 MEMORY_SESSION_DISABLED when off).
Request:
{
"sessionId": "sess_abc123",
"content": "User confirmed we can promote canary after metrics pass.",
"role": "assistant",
"kind": "summary",
"tokenCount": 320,
"turnIndex": 8,
"isMeaningful": true,
"scope": {
"tenantId": "acme-prod",
"userId": "user_123",
"projectId": "github.com/acme/platform"
}
}Response data:
sessionIdeventIdmessageevent(id,sessionId,role,kind,content,tokenCount,turnIndex,isMeaningful,createdAt)
Typical endpoint-specific error codes:
MEMORY_SESSION_DISABLED(403)SESSION_ID_REQUIRED(400)SESSION_CONTENT_REQUIRED(400)SESSION_NOT_FOUND(404)SESSION_NOT_ACTIVE(409)
POST /api/sdk/v1/sessions/end
End an active session with final status closed or compacted.
Feature gate: MEMORY_SESSION_ENABLED must be on (403 MEMORY_SESSION_DISABLED when off).
Request:
{
"sessionId": "sess_abc123",
"status": "compacted",
"scope": {
"tenantId": "acme-prod",
"userId": "user_123",
"projectId": "github.com/acme/platform"
}
}Response data:
sessionIdmessagesession(same shape assessions/start)
Typical endpoint-specific error codes:
MEMORY_SESSION_DISABLED(403)SESSION_ID_REQUIRED(400)INVALID_SESSION_STATUS(400)SESSION_NOT_FOUND(404)SESSION_NOT_ACTIVE(409)
GET /api/sdk/v1/sessions/{sessionId}/snapshot
Fetch latest snapshot for a session.
Feature gate: MEMORY_SESSION_ENABLED must be on (403 MEMORY_SESSION_DISABLED when off).
Query params (optional scope routing):
tenantIduserIdprojectId
Example:
GET /api/sdk/v1/sessions/sess_abc123/snapshot?tenantId=acme-prod&userId=user_123&projectId=github.com/acme/platform
Authorization: Bearer mem_xxxResponse data:
sessionIdmessagesnapshot(id,sessionId,slug,sourceTrigger,transcriptMd,messageCount,createdAt)
Typical endpoint-specific error codes:
MEMORY_SESSION_DISABLED(403)SESSION_NOT_FOUND(404)SESSION_SNAPSHOT_NOT_FOUND(404)
POST /api/sdk/v1/skills/files/upsert
Create or update a scoped skill file.
Request:
{
"path": ".agents/skills/review/SKILL.md",
"content": "---\nname: review\n---\nUse strict checks.",
"scope": {
"tenantId": "acme-prod",
"userId": "user_123",
"projectId": "github.com/acme/platform"
}
}Response data:
skillFilecreatedmessage
POST /api/sdk/v1/skills/files/list
List scoped skill files.
Request:
{
"limit": 100,
"scope": {
"tenantId": "acme-prod",
"userId": "user_123",
"projectId": "github.com/acme/platform"
}
}Response data:
skillFiles[]count
POST /api/sdk/v1/skills/files/delete
Soft-delete a scoped skill file.
Request:
{
"path": ".agents/skills/review/SKILL.md",
"scope": {
"tenantId": "acme-prod",
"userId": "user_123",
"projectId": "github.com/acme/platform"
}
}Response data:
pathdeleted: truemessage
POST /api/sdk/v1/skills/files/promote
Promote a session snapshot into a procedural skill file.
Feature gate: MEMORY_PROCEDURAL_ENABLED must be on (403 MEMORY_PROCEDURAL_DISABLED when off).
Request:
{
"sessionId": "sess_abc123",
"snapshotId": "snap_987",
"path": ".agents/skills/oncall-incident/SKILL.md",
"title": "On-call incident response procedure",
"procedureKey": "incident-response-v1",
"maxSteps": 8,
"scope": {
"tenantId": "acme-prod",
"userId": "user_123",
"projectId": "github.com/acme/platform"
}
}Status is:
201when a new skill file is created200when an existing file is updated
Response data:
skillFilecreatedsource(sessionId,snapshotId,snapshotSlug,snapshotCreatedAt)message
Typical endpoint-specific error codes:
MEMORY_PROCEDURAL_DISABLED(403)SESSION_ID_REQUIRED(400)SKILL_FILE_PATH_REQUIRED(400)SESSION_SNAPSHOT_NOT_FOUND(404)
Graph Endpoint Contracts
GET|POST /api/sdk/v1/graph/status
Read graph health + rollout metrics for current scope.
GET query params:
topNodesLimittenantIduserIdprojectId
POST body:
{
"topNodesLimit": 10,
"scope": {
"tenantId": "acme-prod",
"userId": "user_123",
"projectId": "github.com/acme/platform"
}
}Response data includes:
enabled,flagshealth(ok|schema_missing)tables,countsrolloutshadowMetricsqualityGatealarmstopConnectedNodesrecentErrorssampledAtscope(resolved scope echo)
POST /api/sdk/v1/graph/trace
Trace retrieval behavior and graph expansion decisions.
Request is similar to context/get, but defaults differ:
strategydefault: policy default (baselinefor lexical policy,hybrid_graphfor hybrid policy)limitdefault:10
graph/trace currently accepts legacy strategy literals (baseline, hybrid_graph) for direct diagnostics parity.
Use context/get with lexical|hybrid in new client integrations.
Response data includes:
mode,includeRules,querystrategy:{ requested, applied }trace: rollout/fallback/candidate metrics- includes retrieval policy diagnostics:
retrievalPolicyDefaultStrategyretrievalPolicyAppliedStrategyretrievalPolicySelectionretrievalPolicyReadyForDefaultOnretrievalPolicyBlockerCodes
- includes retrieval policy diagnostics:
tiers: rule/working/long-term ID listsrecall[]: rank + source (baselineorgraph_expansion) + graph explainabilityrules[],memories[]
GET|POST|PATCH /api/sdk/v1/graph/rollout
Manage rollout mode.
GET:
- reads current rollout + quality gate + metrics summary
- evaluates rollout plan and optional autopilot promotion
POST / PATCH request:
{
"mode": "canary",
"scope": {
"tenantId": "acme-prod",
"projectId": "github.com/acme/platform"
}
}mode must be one of:
offshadowcanary
Canary gate behavior:
POST/PATCH mode=canarycan return409withCANARY_ROLLOUT_BLOCKED- error
detailsincludesreasonCodes,qualityStatus, andwindowHours
Successful response data includes:
rolloutshadowMetricsqualityGaterolloutPlanrecommendedModedefaultBehaviorDecisionreadyForDefaultOnblockerCodesbaseline(gap-to-goal metrics)slothresholds and sample requirementsautopilot(enabled,applied)
retrievalPolicydefaultStrategyreadyWindowStreaklastDecisionlastEvaluatedAtupdatedAtupdatedBy
scope
Health Contract
GET /api/sdk/v1/health
Response data:
{
"status": "ok",
"service": "memories-sdk",
"schemaVersion": "2026-02-11"
}Management Endpoint Contracts
/api/sdk/v1/management/tenant-overrides is the primary tenant override API.
GET|POST|DELETE /api/sdk/v1/management/keys
GET: current key status plus key inventory (hasKey,keyCount,activeKeyCount, primary preview timestamps, andkeys[])POST: create an additional key withexpiresAtbody (returns newapiKeyonce)DELETE: revoke all keys, or revoke one key whenkeyIdquery param is provided
POST request:
{
"expiresAt": "2027-01-01T00:00:00.000Z"
}DELETE examples:
DELETE /api/sdk/v1/management/keys
DELETE /api/sdk/v1/management/keys?keyId=3c02d4fd-6f3d-4f7f-a190-9dc7527dd0b3GET|POST|DELETE /api/sdk/v1/management/tenant-overrides
GET: list AI SDK Projects (tenantIdmappings)POST: upsert AI SDK Project mappingDELETE: disable AI SDK Project mapping bytenantIdquery param
POST request:
{
"tenantId": "acme-prod",
"mode": "provision",
"metadata": {
"region": "us-east-2"
}
}Attach mode request:
{
"tenantId": "acme-prod",
"mode": "attach",
"tursoDbUrl": "libsql://example.turso.io",
"tursoDbToken": "token",
"tursoDbName": "example"
}DELETE example:
DELETE /api/sdk/v1/management/tenant-overrides?tenantId=acme-prodGET /api/sdk/v1/embeddings/models
Resolve available embedding models and the selected/default model for a scope.
Query params:
tenantIdprojectIdembeddingModel(optional requested override)
Response data:
models[]config(selectedModelId,source,workspaceDefaultModelId,projectOverrideModelId,allowlistModelIds)
GET /api/sdk/v1/management/embeddings/usage
Read aggregated embedding usage + cost for management dashboards and billing reconciliation.
Query params:
usageMonth(YYYY-MM-DD, defaults to current month start)tenantIdprojectIdlimit
Response data:
usageMonthsummary(requestCount, token/cost totals)breakdown[](grouped by tenant/project/model/provider)
GET|POST /api/sdk/v1/management/embeddings/backfill
Manage backfill progress and control execution.
GET: read scope statusPOST action=run: execute batchPOST action=pause|resume: toggle backfill state
GET /api/sdk/v1/management/embeddings/observability
Read operational snapshot with queue/worker/backfill/retrieval/cost health and SLO-based alarms.
Query params:
tenantIdprojectIduserIdmodelIdusageMonthwindowHours(1..168)
Response data includes:
queue,worker,backfill,retrieval,costworker.topErrorCodes[](top 5error_codevalues in the window; includes graph relationship signals such asGRAPH_RELATIONSHIP_SYNC_FAILEDandGRAPH_RELATIONSHIP_PARTIAL_DEGRADE)slosalarms[]health(healthy|degraded|critical)
GET /api/sdk/v1/management/memory/observability
Read lifecycle health snapshot for memory creation, compaction, consolidation, and contradiction trends.
Query params:
tenantIdprojectIduserIdwindowHours(1..336)
Response data includes:
lifecycle(created/updated/deleted/active/total counts)compaction(trigger mix, checkpoint coverage)consolidation(run totals + conflict rate)contradictions(window totals + daily trend)alarms[]health(healthy|degraded|critical)
POST /api/sdk/v1/management/memory/eval/replay
Run deterministic replay/eval scoring for extraction quality, compaction retention, and trigger matching.
Request:
{
"tenantId": "acme-prod",
"projectId": "github.com/acme/platform",
"passCriteria": {
"extractionF1": 0.7,
"compactionRetention": 0.85,
"triggerAccuracy": 0.9,
"casePassRatio": 0.85
},
"scenarios": [
{
"id": "release-1",
"extraction": {
"expected": ["Always snapshot before reset"],
"observed": ["Always snapshot before reset"]
},
"trigger": {
"expected": "semantic",
"observed": "semantic"
}
}
]
}Response data includes:
scope(tenant/project/user echo)summary(case counts, aggregate scores, pass/warn/fail)scenarios[](per-case extraction/compaction/trigger metrics)
Memory Lifecycle Feature Flags
Default rollout posture:
MEMORY_SESSION_ENABLED=trueMEMORY_COMPACTION_ENABLED=trueMEMORY_CONSOLIDATION_ENABLED=trueMEMORY_PROCEDURAL_ENABLED=trueMEMORY_OPENCLAW_FILE_MODE_ENABLED=false(opt-in)
When disabled, affected endpoints return 403 with a typed flag code:
MEMORY_SESSION_DISABLEDMEMORY_COMPACTION_DISABLEDMEMORY_CONSOLIDATION_DISABLEDMEMORY_PROCEDURAL_DISABLED
cURL Quick Reference
Context
curl -sS https://memories.sh/api/sdk/v1/context/get \
-H "Authorization: Bearer $MEMORIES_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query":"deployment",
"scope":{"tenantId":"acme-prod","userId":"user_123","projectId":"github.com/acme/platform"}
}'Add memory
curl -sS https://memories.sh/api/sdk/v1/memories/add \
-H "Authorization: Bearer $MEMORIES_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content":"Always run smoke tests before deploy",
"type":"rule",
"scope":{"tenantId":"acme-prod","userId":"user_123","projectId":"github.com/acme/platform"}
}'Bulk forget (dry run)
curl -sS https://memories.sh/api/sdk/v1/memories/bulk-forget \
-H "Authorization: Bearer $MEMORIES_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"filters":{"types":["note"],"olderThanDays":90},
"dryRun":true,
"scope":{"tenantId":"acme-prod","userId":"user_123"}
}'Vacuum
curl -sS https://memories.sh/api/sdk/v1/memories/vacuum \
-H "Authorization: Bearer $MEMORIES_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"scope":{"tenantId":"acme-prod","userId":"user_123"}
}'Graph rollout status
curl -sS "https://memories.sh/api/sdk/v1/graph/rollout?tenantId=acme-prod" \
-H "Authorization: Bearer $MEMORIES_API_KEY"Compatibility Notes
- Prefer
transport: "sdk_http"(or"auto") in SDK clients. - MCP JSON-RPC (
/api/mcp) remains available for MCP-native clients. - Breaking SDK HTTP changes will ship under a new prefix (
/api/sdk/v2/*).