Memory OS

Authentication

Memory OS uses API key authentication for all API requests. Every request must include a valid API key in the Authorization header.

API Key Format

API keys follow the format:

TEXT
mos_live_<random_string>
  • mos_ - Memory OS prefix (required)
  • live_ - Environment indicator (live for production, test for sandbox)
  • <random_string> - 32-character base64url-encoded random string

Example key:

TEXT
mos_live_a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8

Authorization Header

Include your API key in the Authorization header using the Bearer scheme:

HTTP
Authorization: Bearer mos_live_<your_key>

cURL Example

Bash
curl -X GET "https://api.mymemoryos.com/api/v1/memories" \
  -H "Authorization: Bearer mos_live_a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8"

JavaScript Example

JavaScript
const response = await fetch('https://api.mymemoryos.com/api/v1/memories', {
  headers: {
    'Authorization': 'Bearer mos_live_a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8',
    'Content-Type': 'application/json'
  }
});

Python Example

Python
import requests

headers = {
    'Authorization': 'Bearer mos_live_a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8',
    'Content-Type': 'application/json'
}

response = requests.get('https://api.mymemoryos.com/api/v1/memories', headers=headers)

Scopes

API keys are issued with specific scopes that control access to different API endpoints. Scopes follow a resource:action pattern.

ScopeDescriptionEndpoints
memories:readRead access to memoriesGET /v1/memories, GET /v1/memories/:id, GET /v1/entities, GET /v1/tags
memories:writeWrite access to memoriesPOST /v1/memories, PATCH /v1/memories/:id, DELETE /v1/memories/:id, POST /v1/entities
search:readAccess to search and contextPOST /v1/search, POST /v1/context
adminAdministrative operationsGET /v1/keys, POST /v1/keys, GET /v1/usage
*Full access (all scopes)All endpoints

Default Scopes

When creating an API key without specifying scopes, these defaults are applied:

JSON
["memories:read", "memories:write", "search:read"]

Checking Required Scopes

Each endpoint requires a specific scope. If your API key lacks the required scope, the API returns a 403 Forbidden error:

JSON
{
  "error": {
    "code": "FORBIDDEN",
    "message": "Missing scope: admin"
  },
  "meta": {
    "request_id": "req_abc123"
  }
}

Rate Limiting

API requests are rate-limited per API key to ensure fair usage and system stability.

Default Limits

PlanRequests per MinuteRequests per Day
Free1001,000
Pro1,000100,000
Enterprise10,000Unlimited
Self-HostedConfigurableConfigurable

Rate Limit Headers

Every response includes rate limit information:

HTTP
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 998
X-RateLimit-Reset: 1704067200
HeaderDescription
X-RateLimit-LimitMaximum requests allowed per minute
X-RateLimit-RemainingRemaining requests in the current window
X-RateLimit-ResetUnix timestamp when the rate limit resets

Handling Rate Limits

When you exceed the rate limit, the API returns a 429 Too Many Requests response:

JSON
{
  "error": {
    "code": "RATE_LIMITED",
    "message": "Rate limit exceeded"
  },
  "meta": {
    "request_id": "req_abc123"
  }
}

The response includes an X-RateLimit-Reset header indicating when you can retry.

Retry Strategy

JavaScript
async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await fetch(url, options);

    if (response.status === 429) {
      const resetTime = parseInt(response.headers.get('X-RateLimit-Reset'));
      const waitMs = (resetTime * 1000) - Date.now() + 1000; // Add 1s buffer

      console.log(`Rate limited. Waiting ${waitMs}ms before retry...`);
      await new Promise(resolve => setTimeout(resolve, Math.max(waitMs, 1000)));
      continue;
    }

    return response;
  }

  throw new Error('Max retries exceeded');
}

Authentication Error Responses

401 Unauthorized

Returned when the API key is missing or invalid:

JSON
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or missing API key"
  },
  "meta": {
    "request_id": "req_abc123"
  }
}

Common causes:

  • Missing Authorization header
  • Incorrect key format (not starting with mos_)
  • Revoked or expired API key
  • Invalid key hash

403 Forbidden

Returned when the API key lacks required permissions:

JSON
{
  "error": {
    "code": "FORBIDDEN",
    "message": "Missing scope: memories:write"
  },
  "meta": {
    "request_id": "req_abc123"
  }
}

Common causes:

  • API key does not have the required scope
  • Attempting to access admin endpoints with non-admin key

Creating API Keys

API keys are created via the /v1/keys endpoint (requires admin scope):

Bash
curl -X POST "https://api.mymemoryos.com/api/v1/keys" \
  -H "Authorization: Bearer mos_live_<admin_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Production API Key",
    "scopes": ["memories:read", "memories:write", "search:read"],
    "rate_limit": 1000
  }'

Response:

JSON
{
  "data": {
    "id": "key_123456",
    "name": "Production API Key",
    "key": "mos_live_newKeyValue123...",
    "message": "Store this key securely - it will not be shown again"
  },
  "meta": {
    "request_id": "req_abc123",
    "latency_ms": 45
  }
}

Important: The full API key is only returned once during creation. Store it securely immediately.

Security Best Practices

  1. Never expose keys in client-side code - API keys should only be used in server-side applications
  2. Use environment variables - Store keys in environment variables, not in code
  3. Rotate keys regularly - Create new keys and revoke old ones periodically
  4. Use minimal scopes - Only request the scopes your application needs
  5. Monitor usage - Check the /v1/usage endpoint to detect unusual activity
  6. Use separate keys per environment - Use different keys for development, staging, and production

Environment Variables Example

Bash
# .env.local
MEMORYOS_API_KEY=mos_live_a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8
JavaScript
// In your application
const apiKey = process.env.MEMORYOS_API_KEY;
Ctrl+Shift+C to copy