{
  "openapi": "3.1.0",
  "info": {
    "title": "Audaxic Memory API",
    "version": "2026-09-25",
    "summary": "Persistent memory layer for coding agents",
    "description": "Audaxic Memory stores facts extracted from coding-agent conversations and recalls them across sessions, so tools like Claude Code, Codex, OpenCode, and Cursor remember user preferences, project decisions, and past work.\n\nThis specification covers two planes:\n\n- **Data plane** (`https://api.memory.audaxic.com`) — store and retrieve memories. Authenticate with a project API key (`ak_...`).\n- **Management plane** (`https://memory-api.audaxic.com`) — manage projects, API keys, workspaces, and scoped auth tokens. Authenticate with a Clerk session JWT (dashboard) or a workspace auth token (`at_...`) with granular scopes.\n\nQuickstart: https://docs.audaxic.com/docs/memory/quickstart/\nPricing (machine-readable): https://memory.audaxic.com/pricing.md\n\nVersioning: every operation accepts an optional `X-Api-Version` header (current version: 2026-09-25) and every response includes an `X-Api-Version` header stating the version that served it. Breaking changes are released only in new dated versions; deprecations are announced with `Deprecation` and `Sunset` headers (RFC 9745) at least 90 days in advance.\n\nRate limits: management-plane responses carry `RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset`, and `RateLimit-Policy` headers (create operations are limited to 100 per hour per IP; 429 responses include `Retry-After`). Data-plane responses carry the same headers for the per-IP failed-authentication guard (100 failed attempts per 4 hours; blocked clients receive 429 with `Retry-After`).",
    "contact": {
      "name": "Audaxic",
      "url": "https://memory.audaxic.com",
      "email": "hello@audaxic.com"
    },
    "license": {
      "name": "Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://api.memory.audaxic.com",
      "description": "Data plane — memories (Bearer ak_...)"
    },
    {
      "url": "https://memory-api.audaxic.com",
      "description": "Management plane — projects, API keys, workspaces, auth tokens"
    }
  ],
  "tags": [
    {
      "name": "Memories",
      "description": "Store, search, list, update, and delete memories (data plane, `ak_...` keys)"
    },
    {
      "name": "Projects",
      "description": "Organize memories into projects (management plane)"
    },
    {
      "name": "API Keys",
      "description": "Manage per-project API keys (management plane)"
    },
    {
      "name": "Workspaces",
      "description": "Group projects into workspaces (management plane)"
    },
    {
      "name": "Auth Tokens",
      "description": "Workspace-scoped tokens with granular permissions for programmatic management (management plane)"
    }
  ],
  "paths": {
    "/add": {
      "servers": [
        {
          "url": "https://api.memory.audaxic.com"
        }
      ],
      "post": {
        "tags": [
          "Memories"
        ],
        "operationId": "addMemories",
        "summary": "Add memories from messages",
        "description": "Extracts facts from one or more messages and stores them as searchable memories. An add request is counted per memory extracted (a batch that extracts 5 memories counts as 5 add requests).",
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AddRequest"
              },
              "examples": {
                "simple": {
                  "summary": "Store a preference",
                  "value": {
                    "messages": [
                      "I prefer dark mode and use VS Code"
                    ]
                  }
                },
                "withTimestamp": {
                  "summary": "Backfill with a session date",
                  "value": {
                    "messages": [
                      "We decided to use bun instead of npm"
                    ],
                    "timestamp": "2026-08-01"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Memories extracted and stored.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AddResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request — malformed body or parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "No active subscription or the plan's usage quota is exhausted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Management create operations are limited to 100 per hour per IP. All create responses also carry `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` headers so agents can self-throttle before being limited.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Maximum number of create operations allowed per window.",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "RateLimit-Remaining": {
                "description": "Create operations remaining in the current window.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the current rate limit window resets.",
                "schema": {
                  "type": "integer",
                  "example": 2400
                }
              },
              "Retry-After": {
                "description": "Seconds until the rate limit window resets.",
                "schema": {
                  "type": "integer",
                  "example": 2400
                }
              },
              "RateLimit-Policy": {
                "description": "Rate limit policy as a structured field, e.g. 100;w=3600 (100 requests per 3600-second window).",
                "schema": {
                  "type": "string",
                  "example": "100;w=3600"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "$ref": "#/components/parameters/ApiVersion"
        }
      ]
    },
    "/search": {
      "servers": [
        {
          "url": "https://api.memory.audaxic.com"
        }
      ],
      "post": {
        "tags": [
          "Memories"
        ],
        "operationId": "searchMemories",
        "summary": "Search memories semantically",
        "description": "Hybrid semantic plus keyword search over stored memories. Returns the most relevant memories with scores. Retrieval requests use tiered counting: the first 10 memories retrieved count as 1 request; each additional 10 counts as 1 more.",
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SearchRequest"
              },
              "examples": {
                "query": {
                  "summary": "Ask a question",
                  "value": {
                    "query": "What editor does the user prefer?",
                    "limit": 5
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Matching memories, sorted by relevance.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request — malformed body or parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "No active subscription or the plan's usage quota is exhausted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Management create operations are limited to 100 per hour per IP. All create responses also carry `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` headers so agents can self-throttle before being limited.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Maximum number of create operations allowed per window.",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "RateLimit-Remaining": {
                "description": "Create operations remaining in the current window.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the current rate limit window resets.",
                "schema": {
                  "type": "integer",
                  "example": 2400
                }
              },
              "Retry-After": {
                "description": "Seconds until the rate limit window resets.",
                "schema": {
                  "type": "integer",
                  "example": 2400
                }
              },
              "RateLimit-Policy": {
                "description": "Rate limit policy as a structured field, e.g. 100;w=3600 (100 requests per 3600-second window).",
                "schema": {
                  "type": "string",
                  "example": "100;w=3600"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "$ref": "#/components/parameters/ApiVersion"
        }
      ]
    },
    "/list": {
      "servers": [
        {
          "url": "https://api.memory.audaxic.com"
        }
      ],
      "get": {
        "tags": [
          "Memories"
        ],
        "operationId": "listMemories",
        "summary": "List memories",
        "description": "Lists stored memories for the authenticated project, newest first (created_at DESC, id ASC). Paginate with limit and offset until fewer than limit results are returned.",
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of memories to return (1-100).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Number of memories to skip, for pagination.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of memories, newest first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request — malformed body or parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "No active subscription or the plan's usage quota is exhausted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Management create operations are limited to 100 per hour per IP. All create responses also carry `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` headers so agents can self-throttle before being limited.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Maximum number of create operations allowed per window.",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "RateLimit-Remaining": {
                "description": "Create operations remaining in the current window.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the current rate limit window resets.",
                "schema": {
                  "type": "integer",
                  "example": 2400
                }
              },
              "Retry-After": {
                "description": "Seconds until the rate limit window resets.",
                "schema": {
                  "type": "integer",
                  "example": 2400
                }
              },
              "RateLimit-Policy": {
                "description": "Rate limit policy as a structured field, e.g. 100;w=3600 (100 requests per 3600-second window).",
                "schema": {
                  "type": "string",
                  "example": "100;w=3600"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "$ref": "#/components/parameters/ApiVersion"
        }
      ]
    },
    "/update": {
      "servers": [
        {
          "url": "https://api.memory.audaxic.com"
        }
      ],
      "put": {
        "tags": [
          "Memories"
        ],
        "operationId": "updateMemory",
        "summary": "Update a memory",
        "description": "Replaces the text of an existing memory. The memory must belong to the authenticated project.",
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UpdateRequest"
              },
              "examples": {
                "update": {
                  "summary": "Correct a stored fact",
                  "value": {
                    "memory_id": "mem_abc123",
                    "data": "User prefers bun and uses Neovim"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated memory.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpdateResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request — malformed body or parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "No active subscription or the plan's usage quota is exhausted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or not visible to these credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Management create operations are limited to 100 per hour per IP. All create responses also carry `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` headers so agents can self-throttle before being limited.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Maximum number of create operations allowed per window.",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "RateLimit-Remaining": {
                "description": "Create operations remaining in the current window.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the current rate limit window resets.",
                "schema": {
                  "type": "integer",
                  "example": 2400
                }
              },
              "Retry-After": {
                "description": "Seconds until the rate limit window resets.",
                "schema": {
                  "type": "integer",
                  "example": 2400
                }
              },
              "RateLimit-Policy": {
                "description": "Rate limit policy as a structured field, e.g. 100;w=3600 (100 requests per 3600-second window).",
                "schema": {
                  "type": "string",
                  "example": "100;w=3600"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "$ref": "#/components/parameters/ApiVersion"
        }
      ]
    },
    "/delete/{memory_id}": {
      "servers": [
        {
          "url": "https://api.memory.audaxic.com"
        }
      ],
      "delete": {
        "tags": [
          "Memories"
        ],
        "operationId": "deleteMemory",
        "summary": "Delete a memory",
        "description": "Deletes a single memory by ID. The memory must belong to the authenticated project.",
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "memory_id",
            "in": "path",
            "required": true,
            "description": "ID of the memory to delete.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deletion result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or not visible to these credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "$ref": "#/components/parameters/ApiVersion"
        }
      ]
    },
    "/delete": {
      "servers": [
        {
          "url": "https://api.memory.audaxic.com"
        }
      ],
      "delete": {
        "tags": [
          "Memories"
        ],
        "operationId": "deleteAllMemories",
        "summary": "Delete all memories in the project",
        "description": "Deletes every memory belonging to the authenticated project. This operation is irreversible.",
        "security": [
          {
            "apiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Number of memories deleted.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeleteResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "$ref": "#/components/parameters/ApiVersion"
        }
      ]
    },
    "/api/projects": {
      "servers": [
        {
          "url": "https://memory-api.audaxic.com"
        }
      ],
      "get": {
        "tags": [
          "Projects"
        ],
        "operationId": "listProjects",
        "summary": "List projects",
        "description": "Lists projects for the authenticated account (or for the token's workspace when using an `at_...` auth token). Paginate with limit and offset.",
        "security": [
          {
            "managementAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "query",
            "required": false,
            "description": "Filter to a specific workspace.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum projects to return (1-100).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Projects to skip for pagination.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of projects.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated but not permitted — e.g. the auth token lacks the required scope or the resource is outside its workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or not visible to these credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Projects"
        ],
        "operationId": "createProject",
        "summary": "Create a project",
        "description": "Creates a project. Accounts are limited to 500,000 projects. Auth tokens create the project in their own workspace (requires the projects:write scope). Management create operations are limited to 100 per hour per IP.",
        "security": [
          {
            "managementAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateProjectRequest"
              },
              "examples": {
                "create": {
                  "summary": "Create a project",
                  "value": {
                    "name": "my-project"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Project created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request — malformed body or parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated but not permitted — e.g. the auth token lacks the required scope or the resource is outside its workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or not visible to these credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Management create operations are limited to 100 per hour per IP. All create responses also carry `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` headers so agents can self-throttle before being limited.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Maximum number of create operations allowed per window.",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "RateLimit-Remaining": {
                "description": "Create operations remaining in the current window.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the current rate limit window resets.",
                "schema": {
                  "type": "integer",
                  "example": 2400
                }
              },
              "Retry-After": {
                "description": "Seconds until the rate limit window resets.",
                "schema": {
                  "type": "integer",
                  "example": 2400
                }
              },
              "RateLimit-Policy": {
                "description": "Rate limit policy as a structured field, e.g. 100;w=3600 (100 requests per 3600-second window).",
                "schema": {
                  "type": "string",
                  "example": "100;w=3600"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "$ref": "#/components/parameters/ApiVersion"
        }
      ]
    },
    "/api/projects/{id}": {
      "servers": [
        {
          "url": "https://memory-api.audaxic.com"
        }
      ],
      "get": {
        "tags": [
          "Projects"
        ],
        "operationId": "getProject",
        "summary": "Get a project",
        "description": "Returns a single project owned by the authenticated account.",
        "security": [
          {
            "managementAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Project ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The project.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated but not permitted — e.g. the auth token lacks the required scope or the resource is outside its workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or not visible to these credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Projects"
        ],
        "operationId": "deleteProject",
        "summary": "Delete a project",
        "description": "Deletes a project and its API keys, and wipes the project's stored memories. Requires the projects:write scope for auth tokens.",
        "security": [
          {
            "managementAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Project ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deletion result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated but not permitted — e.g. the auth token lacks the required scope or the resource is outside its workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or not visible to these credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "$ref": "#/components/parameters/ApiVersion"
        }
      ]
    },
    "/api/api-keys": {
      "servers": [
        {
          "url": "https://memory-api.audaxic.com"
        }
      ],
      "get": {
        "tags": [
          "API Keys"
        ],
        "operationId": "listApiKeys",
        "summary": "List API keys",
        "description": "Lists API keys for the authenticated account, optionally filtered by project or workspace. Raw keys are never returned — only metadata. Paginate with limit and offset. Requires the keys:read scope for auth tokens.",
        "security": [
          {
            "managementAuth": []
          }
        ],
        "parameters": [
          {
            "name": "project_id",
            "in": "query",
            "required": false,
            "description": "Filter to a project.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "workspace_id",
            "in": "query",
            "required": false,
            "description": "Filter to a workspace.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum keys to return (1-100).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Keys to skip for pagination.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of API key metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated but not permitted — e.g. the auth token lacks the required scope or the resource is outside its workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or not visible to these credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "API Keys"
        ],
        "operationId": "createApiKey",
        "summary": "Create an API key",
        "description": "Creates a project API key (`ak_...`). The raw key is returned only once in the response; only its SHA-256 hash is stored. Accounts are limited to 1,000,000 keys. Requires the keys:write scope for auth tokens.",
        "security": [
          {
            "managementAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateApiKeyRequest"
              },
              "examples": {
                "create": {
                  "summary": "Create a key for a project",
                  "value": {
                    "name": "ci-preview",
                    "project_id": "3da4d7e2-9df7-4969-8324-55c78147016d"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "API key created — `key` is shown only once.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApiKeyCreatedResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request — malformed body or parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated but not permitted — e.g. the auth token lacks the required scope or the resource is outside its workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or not visible to these credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Management create operations are limited to 100 per hour per IP. All create responses also carry `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` headers so agents can self-throttle before being limited.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Maximum number of create operations allowed per window.",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "RateLimit-Remaining": {
                "description": "Create operations remaining in the current window.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the current rate limit window resets.",
                "schema": {
                  "type": "integer",
                  "example": 2400
                }
              },
              "Retry-After": {
                "description": "Seconds until the rate limit window resets.",
                "schema": {
                  "type": "integer",
                  "example": 2400
                }
              },
              "RateLimit-Policy": {
                "description": "Rate limit policy as a structured field, e.g. 100;w=3600 (100 requests per 3600-second window).",
                "schema": {
                  "type": "string",
                  "example": "100;w=3600"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "$ref": "#/components/parameters/ApiVersion"
        }
      ]
    },
    "/api/api-keys/{id}": {
      "servers": [
        {
          "url": "https://memory-api.audaxic.com"
        }
      ],
      "delete": {
        "tags": [
          "API Keys"
        ],
        "operationId": "deleteApiKey",
        "summary": "Delete an API key",
        "description": "Revokes an API key immediately. Requires the keys:write scope for auth tokens.",
        "security": [
          {
            "managementAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "API key ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deletion result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Authenticated but not permitted — e.g. the auth token lacks the required scope or the resource is outside its workspace.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or not visible to these credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "$ref": "#/components/parameters/ApiVersion"
        }
      ]
    },
    "/api/workspaces": {
      "servers": [
        {
          "url": "https://memory-api.audaxic.com"
        }
      ],
      "get": {
        "tags": [
          "Workspaces"
        ],
        "operationId": "listWorkspaces",
        "summary": "List workspaces",
        "description": "Lists workspaces for the authenticated account with project counts. Every account starts with a workspace named Default. Paginate with limit and offset.",
        "security": [
          {
            "managementAuth": []
          }
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum workspaces to return (1-100).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Workspaces to skip for pagination.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of workspaces.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkspaceListResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or not visible to these credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Workspaces"
        ],
        "operationId": "createWorkspace",
        "summary": "Create a workspace",
        "description": "Creates a workspace. Management create operations are limited to 100 per hour per IP.",
        "security": [
          {
            "managementAuth": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWorkspaceRequest"
              },
              "examples": {
                "create": {
                  "summary": "Create a workspace",
                  "value": {
                    "name": "client-acme"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Workspace created.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Workspace"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request — malformed body or parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Management create operations are limited to 100 per hour per IP. All create responses also carry `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` headers so agents can self-throttle before being limited.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Maximum number of create operations allowed per window.",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "RateLimit-Remaining": {
                "description": "Create operations remaining in the current window.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the current rate limit window resets.",
                "schema": {
                  "type": "integer",
                  "example": 2400
                }
              },
              "Retry-After": {
                "description": "Seconds until the rate limit window resets.",
                "schema": {
                  "type": "integer",
                  "example": 2400
                }
              },
              "RateLimit-Policy": {
                "description": "Rate limit policy as a structured field, e.g. 100;w=3600 (100 requests per 3600-second window).",
                "schema": {
                  "type": "string",
                  "example": "100;w=3600"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "$ref": "#/components/parameters/ApiVersion"
        }
      ]
    },
    "/api/auth-tokens": {
      "servers": [
        {
          "url": "https://memory-api.audaxic.com"
        }
      ],
      "get": {
        "tags": [
          "Auth Tokens"
        ],
        "operationId": "listAuthTokens",
        "summary": "List auth tokens in a workspace",
        "description": "Lists workspace auth tokens with their prefix, scopes, and creation date. Raw tokens and hashes are never returned. Paginate with limit and offset.",
        "security": [
          {
            "managementAuth": []
          }
        ],
        "parameters": [
          {
            "name": "workspace_id",
            "in": "query",
            "required": true,
            "description": "Workspace whose tokens to list.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum tokens to return (1-100).",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Tokens to skip for pagination.",
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of auth token metadata.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthTokenListResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request — malformed body or parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or not visible to these credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": [
          "Auth Tokens"
        ],
        "operationId": "createAuthToken",
        "summary": "Create an auth token",
        "description": "Creates a workspace auth token (`at_...`) with granular scopes: projects:read, projects:write, keys:read, keys:write. The raw token is returned only once. Auth tokens cannot manage other auth tokens. Management create operations are limited to 100 per hour per IP.",
        "security": [
          {
            "managementAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateAuthTokenRequest"
              },
              "examples": {
                "readOnly": {
                  "summary": "Read-only CI token",
                  "value": {
                    "name": "ci-readonly",
                    "workspace_id": "e830cb39-97ad-423f-a9b5-75ae927108d9",
                    "scopes": [
                      "projects:read"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Auth token created — `token` is shown only once.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthTokenCreatedResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request — malformed body or parameters.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or not visible to these credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Management create operations are limited to 100 per hour per IP. All create responses also carry `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` headers so agents can self-throttle before being limited.",
            "headers": {
              "RateLimit-Limit": {
                "description": "Maximum number of create operations allowed per window.",
                "schema": {
                  "type": "integer",
                  "example": 100
                }
              },
              "RateLimit-Remaining": {
                "description": "Create operations remaining in the current window.",
                "schema": {
                  "type": "integer",
                  "example": 0
                }
              },
              "RateLimit-Reset": {
                "description": "Seconds until the current rate limit window resets.",
                "schema": {
                  "type": "integer",
                  "example": 2400
                }
              },
              "Retry-After": {
                "description": "Seconds until the rate limit window resets.",
                "schema": {
                  "type": "integer",
                  "example": 2400
                }
              },
              "RateLimit-Policy": {
                "description": "Rate limit policy as a structured field, e.g. 100;w=3600 (100 requests per 3600-second window).",
                "schema": {
                  "type": "string",
                  "example": "100;w=3600"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "$ref": "#/components/parameters/ApiVersion"
        }
      ]
    },
    "/api/auth-tokens/{id}": {
      "servers": [
        {
          "url": "https://memory-api.audaxic.com"
        }
      ],
      "delete": {
        "tags": [
          "Auth Tokens"
        ],
        "operationId": "deleteAuthToken",
        "summary": "Delete an auth token",
        "description": "Revokes an auth token immediately. API clients using it stop working.",
        "security": [
          {
            "managementAuth": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Auth token ID.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Deletion result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SuccessResponse"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found or not visible to these credentials.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "parameters": [
        {
          "$ref": "#/components/parameters/ApiVersion"
        }
      ]
    }
  },
  "components": {
    "securitySchemes": {
      "apiKeyAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Project API key (`ak_...`) created in the dashboard at https://memory-dashboard.audaxic.com. Each key is scoped to a single project."
      },
      "managementAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Management credentials: a Clerk session JWT (used by the dashboard) or a workspace auth token (`at_...`). Auth tokens carry granular scopes — `projects:read`, `projects:write`, `keys:read`, `keys:write`. Requests missing the required scope receive 403; requests outside the token's workspace receive 404."
      }
    },
    "schemas": {
      "MemoryItem": {
        "type": "object",
        "description": "A single stored memory.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique memory identifier."
          },
          "memory": {
            "type": "string",
            "description": "The stored memory text."
          },
          "metadata": {
            "type": "object",
            "description": "Associated metadata.",
            "additionalProperties": true
          }
        },
        "required": [
          "id",
          "memory",
          "metadata"
        ]
      },
      "AddRequest": {
        "type": "object",
        "properties": {
          "messages": {
            "type": "array",
            "description": "Messages to extract memories from. Up to 100 messages, each up to 15,000 characters.",
            "minItems": 1,
            "maxItems": 100,
            "items": {
              "type": "string",
              "maxLength": 15000
            }
          },
          "timestamp": {
            "type": [
              "string",
              "null"
            ],
            "description": "Optional session date (ISO 8601, e.g. 2026-08-01) used to resolve relative time references. Use \"no_date\" to store memories without any resolved date. Omit to default to today."
          }
        },
        "required": [
          "messages"
        ]
      },
      "AddResponse": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemoryItem"
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "SearchRequest": {
        "type": "object",
        "properties": {
          "query": {
            "type": "string",
            "maxLength": 5000,
            "description": "Natural language search query."
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 75,
            "default": 10,
            "description": "Maximum number of results."
          }
        },
        "required": [
          "query"
        ]
      },
      "SearchResponse": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemoryItem"
            }
          }
        },
        "required": [
          "results"
        ]
      },
      "ListResponse": {
        "type": "object",
        "properties": {
          "memories": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/MemoryItem"
            }
          }
        },
        "required": [
          "memories"
        ]
      },
      "UpdateRequest": {
        "type": "object",
        "properties": {
          "memory_id": {
            "type": "string",
            "description": "ID of the memory to update."
          },
          "data": {
            "type": "string",
            "maxLength": 15000,
            "description": "New text for the memory."
          }
        },
        "required": [
          "memory_id",
          "data"
        ]
      },
      "UpdateResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "memory": {
            "type": "string"
          },
          "metadata": {
            "type": "object",
            "additionalProperties": true
          }
        },
        "required": [
          "id",
          "memory",
          "metadata"
        ]
      },
      "DeleteResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "deleted_count": {
            "type": "integer",
            "description": "Number of memories deleted."
          }
        },
        "required": [
          "success"
        ]
      },
      "SuccessResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          }
        },
        "required": [
          "success"
        ]
      },
      "Error": {
        "type": "object",
        "description": "JSON error response returned by every endpoint.",
        "properties": {
          "error": {
            "type": "string",
            "description": "Human-readable error message."
          }
        },
        "required": [
          "error"
        ]
      },
      "Project": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "userId": {
            "type": "string"
          },
          "workspaceId": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "createdAt": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "userId",
          "name"
        ]
      },
      "ProjectListResponse": {
        "type": "object",
        "properties": {
          "projects": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Project"
            }
          }
        },
        "required": [
          "projects"
        ]
      },
      "CreateProjectRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Project name. Defaults to \"Untitled Project\"."
          },
          "workspace_id": {
            "type": "string",
            "description": "Target workspace. Defaults to the account's Default workspace; auth tokens always create in their own workspace."
          }
        }
      },
      "ApiKey": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "userId": {
            "type": "string"
          },
          "projectId": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "createdAt": {
            "type": "string"
          },
          "projectName": {
            "type": "string",
            "description": "Joined project name for display."
          }
        },
        "required": [
          "id",
          "projectId"
        ]
      },
      "ApiKeyListResponse": {
        "type": "object",
        "properties": {
          "apiKeys": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApiKey"
            }
          }
        },
        "required": [
          "apiKeys"
        ]
      },
      "CreateApiKeyRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Display name for the key."
          },
          "project_id": {
            "type": "string",
            "description": "Project the key belongs to."
          }
        },
        "required": [
          "project_id"
        ]
      },
      "ApiKeyCreatedResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "key": {
            "type": "string",
            "description": "The raw API key (`ak_...`). Shown only once."
          },
          "name": {
            "type": "string"
          },
          "project_id": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "key",
          "project_id"
        ]
      },
      "Workspace": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "userId": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "createdAt": {
            "type": "string"
          },
          "project_count": {
            "type": "integer"
          }
        },
        "required": [
          "id",
          "name"
        ]
      },
      "WorkspaceListResponse": {
        "type": "object",
        "properties": {
          "workspaces": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Workspace"
            }
          }
        },
        "required": [
          "workspaces"
        ]
      },
      "CreateWorkspaceRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Workspace name, up to 80 characters. Defaults to \"Untitled Workspace\"."
          }
        }
      },
      "AuthToken": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "prefix": {
            "type": "string",
            "description": "First 8 characters of the token, for identification."
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "projects:read",
                "projects:write",
                "keys:read",
                "keys:write"
              ]
            }
          },
          "workspace_id": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "scopes",
          "workspace_id"
        ]
      },
      "AuthTokenListResponse": {
        "type": "object",
        "properties": {
          "authTokens": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AuthToken"
            }
          }
        },
        "required": [
          "authTokens"
        ]
      },
      "CreateAuthTokenRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Display name for the token."
          },
          "workspace_id": {
            "type": "string",
            "description": "Workspace the token is scoped to."
          },
          "scopes": {
            "type": "array",
            "description": "Permissions for the token. Defaults to all four scopes.",
            "items": {
              "type": "string",
              "enum": [
                "projects:read",
                "projects:write",
                "keys:read",
                "keys:write"
              ]
            }
          }
        },
        "required": [
          "workspace_id"
        ]
      },
      "AuthTokenCreatedResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "token": {
            "type": "string",
            "description": "The raw auth token (`at_...`). Shown only once."
          },
          "name": {
            "type": "string"
          },
          "prefix": {
            "type": "string"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "workspace_id": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "token",
          "workspace_id"
        ]
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid request — malformed body or parameters.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing or invalid credentials.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Authenticated but not permitted — e.g. the auth token lacks the required scope or the resource is outside its workspace.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found or not visible to these credentials.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "PaymentRequired": {
        "description": "No active subscription or the plan's usage quota is exhausted.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded. Management create operations are limited to 100 per hour per IP. All create responses also carry `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset` headers so agents can self-throttle before being limited.",
        "headers": {
          "RateLimit-Limit": {
            "description": "Maximum number of create operations allowed per window.",
            "schema": {
              "type": "integer",
              "example": 100
            }
          },
          "RateLimit-Remaining": {
            "description": "Create operations remaining in the current window.",
            "schema": {
              "type": "integer",
              "example": 0
            }
          },
          "RateLimit-Reset": {
            "description": "Seconds until the current rate limit window resets.",
            "schema": {
              "type": "integer",
              "example": 2400
            }
          },
          "Retry-After": {
            "description": "Seconds until the rate limit window resets.",
            "schema": {
              "type": "integer",
              "example": 2400
            }
          },
          "RateLimit-Policy": {
            "description": "Rate limit policy as a structured field, e.g. 100;w=3600 (100 requests per 3600-second window).",
            "schema": {
              "type": "string",
              "example": "100;w=3600"
            }
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "InternalError": {
        "description": "Unexpected server error.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "parameters": {
      "ApiVersion": {
        "name": "X-Api-Version",
        "in": "header",
        "required": false,
        "description": "API version (date-based). Current version: 2026-09-25. Breaking changes are released only in new dated versions; deprecated versions are announced with Deprecation and Sunset response headers (RFC 9745) at least 90 days in advance. Omit to use the current version. Every response includes an X-Api-Version header stating the version that served it.",
        "schema": {
          "type": "string",
          "example": "2026-09-25"
        }
      }
    }
  }
}
