memories.sh logomemories.sh
SDK

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 configure transport: "mcp" (or point baseUrl at /api/mcp).
  • CLI commands are separate tooling and are not used by SDK runtime calls.

Base URL

https://memories.sh

Endpoint Matrix

GroupRouteMethodsAuth
Health/api/sdk/v1/healthGETNone
Runtime/api/sdk/v1/context/getPOSTBearer API key (mem_...)
Runtime/api/sdk/v1/memories/addPOSTBearer API key (mem_...)
Runtime/api/sdk/v1/memories/searchPOSTBearer API key (mem_...)
Runtime/api/sdk/v1/memories/listPOSTBearer API key (mem_...)
Runtime/api/sdk/v1/memories/editPOSTBearer API key (mem_...)
Runtime/api/sdk/v1/memories/forgetPOSTBearer API key (mem_...)
Runtime/api/sdk/v1/skills/files/upsertPOSTBearer API key (mem_...)
Runtime/api/sdk/v1/skills/files/listPOSTBearer API key (mem_...)
Runtime/api/sdk/v1/skills/files/deletePOSTBearer API key (mem_...)
Graph/api/sdk/v1/graph/statusGET, POSTBearer API key (mem_...)
Graph/api/sdk/v1/graph/tracePOSTBearer API key (mem_...)
Graph/api/sdk/v1/graph/rolloutGET, POST, PATCHBearer API key (mem_...)
Management/api/sdk/v1/management/keysGET, POST, DELETELegacy management auth (session/legacy path)
Management/api/sdk/v1/management/tenantsGET, POST, DELETELegacy management auth (session/legacy path)

Legacy aliases are still available:

  • /api/mcp/key
  • /api/mcp/tenants

Authentication

Runtime + graph endpoints

Send your API key:

Authorization: Bearer mem_xxx
Content-Type: application/json

Management endpoints

/api/sdk/v1/management/* is currently a compatibility wrapper over legacy management routes and uses the same auth path as those endpoints.

If you are doing headless server-to-server management calls, validate auth flow in your environment before rollout.

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

CodeTypical statusNotes
MISSING_API_KEY401Runtime/graph endpoint called without Authorization
INVALID_API_KEY_FORMAT401Bearer token format is invalid
INVALID_API_KEY401Key hash not found
API_KEY_EXPIRED401Key exists but expired
RATE_LIMITED429Includes details.retryAfterSeconds
INVALID_REQUEST400JSON shape/validation failed
QUERY_REQUIRED400Empty query for search
TENANT_ID_INVALID400Invalid scope.tenantId
USER_ID_INVALID400Invalid scope.userId
DATABASE_NOT_CONFIGURED400No active workspace DB for API key owner
TENANT_DATABASE_NOT_CONFIGURED404Unknown AI SDK Project (tenantId) mapping (auto-provision may create this mapping when enabled)
TENANT_DATABASE_NOT_READY409Tenant DB mapping exists but not ready
TENANT_DATABASE_CREDENTIALS_MISSING404Tenant mapping missing credentials
CANARY_ROLLOUT_BLOCKED409Quality gate blocked canary rollout
INTERNAL_ERROR500Fallback internal error code
LEGACY_MCP_KEY_ERRORpassthroughManagement keys wrapper error
LEGACY_MCP_TENANTS_ERRORpassthroughManagement tenants 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 inside tenantId
  • projectId: 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)

FieldConstraint
querymax 500 chars
content (memories/add, memories/edit)1..8000 chars
limit (context/get, search, trace)1..50
limit (memories/list)1..100
graphDepth0, 1, or 2
graphLimit1..50
tags[]max 50 tags, each 1..120 chars
paths[]max 100 paths, each 1..300 chars
category1..120 chars
path (skills/files/*)1..400 chars
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": "baseline",
  "graphDepth": 1,
  "graphLimit": 8,
  "scope": {
    "tenantId": "acme-prod",
    "userId": "user_123",
    "projectId": "github.com/acme/platform"
  }
}

Defaults:

  • limit: 5
  • includeRules: true
  • includeSkillFiles: true
  • mode: all
  • strategy: baseline
  • graphDepth: 1
  • graphLimit: 8

Response data:

  • mode, query
  • rules[]
  • memories[]
  • skillFiles[]
  • workingMemories[]
  • longTermMemories[]
  • trace (strategy, rollout mode, fallback details, candidate counts)

POST /api/sdk/v1/memories/add

Create a memory.

Request:

{
  "content": "Use canary rollout for graph retrieval changes",
  "type": "rule",
  "layer": "rule",
  "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:

  • id
  • message
  • memory (structured memory record)

POST /api/sdk/v1/memories/search

Search memories by query.

Request:

{
  "query": "rollout",
  "type": "rule",
  "layer": "rule",
  "limit": 10,
  "scope": {
    "userId": "user_123"
  }
}

Response data:

  • memories[]
  • count

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",
  "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:

  • id
  • updated: true
  • message

POST /api/sdk/v1/memories/forget

Soft-delete a memory.

Request:

{
  "id": "mem_abc123",
  "scope": {
    "userId": "user_123"
  }
}

Response data:

  • id
  • deleted: true
  • message

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:

  • skillFile
  • created
  • message

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:

  • path
  • deleted: true
  • message

Graph Endpoint Contracts

GET|POST /api/sdk/v1/graph/status

Read graph health + rollout metrics for current scope.

GET query params:

  • topNodesLimit
  • tenantId
  • userId
  • projectId

POST body:

{
  "topNodesLimit": 10,
  "scope": {
    "tenantId": "acme-prod",
    "userId": "user_123",
    "projectId": "github.com/acme/platform"
  }
}

Response data includes:

  • enabled, flags
  • health (ok | schema_missing)
  • tables, counts
  • rollout
  • shadowMetrics
  • qualityGate
  • alarms
  • topConnectedNodes
  • recentErrors
  • sampledAt
  • scope (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:

  • strategy default: hybrid_graph
  • limit default: 10

Response data includes:

  • mode, includeRules, query
  • strategy: { requested, applied }
  • trace: rollout/fallback/candidate metrics
  • tiers: rule/working/long-term ID lists
  • recall[]: rank + source (baseline or graph_expansion) + graph explainability
  • rules[], memories[]

GET|POST|PATCH /api/sdk/v1/graph/rollout

Manage rollout mode.

GET:

  • reads current rollout + quality gate + metrics summary

POST / PATCH request:

{
  "mode": "canary",
  "scope": {
    "tenantId": "acme-prod",
    "projectId": "github.com/acme/platform"
  }
}

mode must be one of:

  • off
  • shadow
  • canary

Canary gate behavior:

  • POST/PATCH mode=canary can return 409 with CANARY_ROLLOUT_BLOCKED
  • error details includes reasonCodes, qualityStatus, and windowHours

Successful response data includes:

  • rollout
  • shadowMetrics
  • qualityGate
  • 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/* currently wraps legacy /api/mcp/* responses into SDK envelopes.

GET|POST|DELETE /api/sdk/v1/management/keys

  • GET: current key status (hasKey, keyPreview, createdAt, expiresAt, isExpired)
  • POST: rotate key with expiresAt body
  • DELETE: revoke key

POST request:

{
  "expiresAt": "2027-01-01T00:00:00.000Z"
}

GET|POST|DELETE /api/sdk/v1/management/tenants

  • GET: list AI SDK Projects (tenantId mappings)
  • POST: upsert AI SDK Project mapping
  • DELETE: disable AI SDK Project mapping by tenantId query 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/tenants?tenantId=acme-prod

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"}
  }'

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/*).

On this page