{
  "openapi": "3.1.0",
  "info": {
    "title": "REM Labs API",
    "version": "4.0.0",
    "summary": "The continuity layer for intelligence — memory, Dream Engine consolidation, channels, webhooks, events, and A2A.",
    "description": "The REM Labs REST API exposes the universal memory layer that powers persistent recall, the Dream Engine (9-strategy autonomous knowledge consolidation), real-time channels, outbound webhooks, and agent-to-agent interop.\n\n## Authentication\nAll endpoints (except `/health` and `/.well-known/agent-card.json`) require a `Bearer` token. Keys start with `sk-rem-` and are issued from the [REM Labs Console](https://remlabs.ai/console) or via the `/v1/keys` endpoint.\n\n```\nAuthorization: Bearer sk-rem-...\n```\n\n## Base URL\n`https://remlabs.ai/v1`\n\n## Rate limits\nSee [remlabs.ai/sla](https://remlabs.ai/sla) for per-tier quotas. All responses include `X-RateLimit-Remaining` and `X-RateLimit-Reset`.\n\n## Errors\nAll errors return JSON with `{ error: { code, message } }` and a conventional HTTP status.",
    "termsOfService": "https://remlabs.ai/terms",
    "contact": {
      "name": "REM Labs Developer Support",
      "url": "https://remlabs.ai/developers",
      "email": "developers@remlabs.ai"
    },
    "license": {
      "name": "REM Labs Commercial License",
      "url": "https://remlabs.ai/terms"
    }
  },
  "servers": [
    {
      "url": "https://remlabs.ai/v1",
      "description": "Production"
    }
  ],
  "tags": [
    { "name": "Memory", "description": "Store, search, and recall knowledge. Semantic (vector), lexical (FTS5), and hybrid retrieval." },
    { "name": "Dream Engine", "description": "Run autonomous knowledge consolidation across stored memories. 9 strategies: synthesize, pattern_extract, insight_generate, compress, associate, validate, evolve, forecast, reflect." },
    { "name": "Channels", "description": "Real-time pub/sub channels for multi-agent coordination and memory broadcasting." },
    { "name": "Webhooks", "description": "Register HTTP callbacks for memory events, dream completions, and channel messages." },
    { "name": "Events", "description": "Subscribe to memory mutations and dream lifecycle events via WebSocket, SSE, or webhook." },
    { "name": "Keys", "description": "Programmatic API key management. Rotate, revoke, and scope keys." },
    { "name": "Agents", "description": "A2A (agent-to-agent) discovery and capability negotiation. Includes `/.well-known/agent-card.json`." },
    { "name": "System", "description": "Health checks and service metadata." }
  ],
  "security": [{ "bearerAuth": [] }],
  "paths": {
    "/health": {
      "get": {
        "tags": ["System"],
        "operationId": "health",
        "summary": "Service health",
        "description": "Public liveness probe. Returns 200 when the API is reachable.",
        "security": [],
        "responses": {
          "200": {
            "description": "Service is healthy",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Health" },
                "example": { "ok": true, "service": "remlabs-api", "version": "4.0.0", "ts": "2026-04-17T12:00:00Z" }
              }
            }
          }
        }
      }
    },
    "/memory-set": {
      "post": {
        "tags": ["Memory"],
        "operationId": "memorySet",
        "summary": "Store a memory",
        "description": "Write a memory by key. Creates if absent, overwrites if present. Content can be any string; JSON values are coerced via `JSON.stringify`. Tags and metadata index for later retrieval.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/MemorySetRequest" },
              "example": {
                "key": "user.pref.dark_mode",
                "value": "Prefers dark mode across all surfaces.",
                "tags": ["preferences", "ui"],
                "metadata": { "source": "console", "confidence": 0.98 }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Memory stored",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Memory" },
                "example": {
                  "id": "mem_01HP3ZK7X9ABCDEFGHJKMNP",
                  "key": "user.pref.dark_mode",
                  "value": "Prefers dark mode across all surfaces.",
                  "tags": ["preferences", "ui"],
                  "created_at": "2026-04-17T12:00:00Z",
                  "updated_at": "2026-04-17T12:00:00Z"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" },
          "429": { "$ref": "#/components/responses/RateLimited" }
        }
      }
    },
    "/memory-search": {
      "post": {
        "tags": ["Memory"],
        "operationId": "memorySearch",
        "summary": "Lexical memory search (FTS5)",
        "description": "Full-text search powered by SQLite FTS5 with AND-first tokenization. Fastest retrieval path for exact-term matches.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/MemorySearchRequest" },
              "example": { "query": "auth flow token refresh", "limit": 10 }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Search results",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MemorySearchResponse" },
                "example": {
                  "results": [
                    {
                      "id": "mem_01HP3ZK7X9ABCDEFGHJKMNP",
                      "key": "auth.token.refresh",
                      "value": "Token refresh uses sliding window; 15 min access, 30 day refresh.",
                      "score": 0.87
                    }
                  ],
                  "total": 1,
                  "took_ms": 4
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/memory-search-semantic": {
      "post": {
        "tags": ["Memory"],
        "operationId": "memorySearchSemantic",
        "summary": "Semantic memory search (vector)",
        "description": "Dense-vector (embeddings) retrieval. Returns memories ranked by cosine similarity. Combine with `/memory-search` via Reciprocal Rank Fusion for best recall.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/MemorySearchRequest" },
              "example": { "query": "How do users prefer their UI to look?", "limit": 8, "threshold": 0.6 }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Semantic results",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/MemorySearchResponse" },
                "example": {
                  "results": [
                    {
                      "id": "mem_01HP3ZK7X9ABCDEFGHJKMNP",
                      "key": "user.pref.dark_mode",
                      "value": "Prefers dark mode across all surfaces.",
                      "score": 0.83
                    }
                  ],
                  "total": 1,
                  "took_ms": 38
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/remember": {
      "post": {
        "tags": ["Memory"],
        "operationId": "remember",
        "summary": "Natural-language remember",
        "description": "High-level write endpoint that accepts unstructured content. The system extracts key, tags, and metadata automatically. Preferred for agent integrations.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/RememberRequest" },
              "example": {
                "content": "The user hates notifications after 9pm and prefers summaries over raw logs.",
                "namespace": "user_1234"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Memory created",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Memory" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/dream": {
      "post": {
        "tags": ["Dream Engine"],
        "operationId": "dreamRun",
        "summary": "Run a Dream Engine consolidation",
        "description": "Kick off a dream cycle. Runs one or all 9 strategies over your stored memories. Returns a Dream object with status; poll `/dream/{id}` for completion.\n\nStrategies: `synthesize`, `pattern_extract`, `insight_generate`, `compress`, `associate`, `validate`, `evolve`, `forecast`, `reflect`.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/DreamRequest" },
              "example": { "namespace": "default", "strategy": "synthesize" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Dream started",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Dream" },
                "example": {
                  "id": "dream_01HP3ZK9P7QRSTUVWXYZ",
                  "status": "running",
                  "strategy": "synthesize",
                  "namespace": "default",
                  "started_at": "2026-04-17T12:00:00Z",
                  "memories_created": 0
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      },
      "get": {
        "tags": ["Dream Engine"],
        "operationId": "dreamList",
        "summary": "List recent dream runs",
        "parameters": [
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 20, "maximum": 100 } },
          { "name": "status", "in": "query", "schema": { "type": "string", "enum": ["running", "complete", "failed"] } }
        ],
        "responses": {
          "200": {
            "description": "List of dreams",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "dreams": { "type": "array", "items": { "$ref": "#/components/schemas/Dream" } }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/channels": {
      "get": {
        "tags": ["Channels"],
        "operationId": "channelList",
        "summary": "List channels",
        "responses": {
          "200": {
            "description": "Channels",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "channels": { "type": "array", "items": { "$ref": "#/components/schemas/Channel" } }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      },
      "post": {
        "tags": ["Channels"],
        "operationId": "channelCreate",
        "summary": "Create a channel",
        "description": "Create a named real-time channel for multi-agent pub/sub. Use `/v1/channels/{name}/publish` to broadcast messages.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ChannelCreateRequest" },
              "example": { "name": "agent-swarm-alpha", "mode": "broadcast", "retention": "24h" }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Channel created",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Channel" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/webhook-create": {
      "post": {
        "tags": ["Webhooks"],
        "operationId": "webhookCreate",
        "summary": "Register an outbound webhook",
        "description": "Receive HTTPS callbacks when memory events, dream runs, or channel messages occur.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/WebhookCreateRequest" },
              "example": {
                "url": "https://example.com/hooks/remlabs",
                "events": ["memory.created", "dream.completed"],
                "secret": "whsec_..."
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook registered",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Webhook" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/webhooks-register": {
      "post": {
        "tags": ["Webhooks"],
        "operationId": "webhooksRegister",
        "summary": "Bulk register webhooks",
        "description": "Register multiple webhooks in one call. Useful for setting up an integration from a manifest.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "webhooks": { "type": "array", "items": { "$ref": "#/components/schemas/WebhookCreateRequest" } }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhooks registered",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "webhooks": { "type": "array", "items": { "$ref": "#/components/schemas/Webhook" } }
                  }
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/event-subscribe": {
      "post": {
        "tags": ["Events"],
        "operationId": "eventSubscribe",
        "summary": "Subscribe to events",
        "description": "Open an SSE stream of typed events. Alternately, use WebSockets at `wss://remlabs.ai/v1/events/ws` or configure webhooks via `/webhook-create`.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/EventSubscribeRequest" },
              "example": {
                "events": ["memory.created", "memory.updated", "dream.completed"],
                "transport": "sse"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Event stream established",
            "content": {
              "text/event-stream": { "schema": { "type": "string" } },
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Event" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/memory-subscribe": {
      "post": {
        "tags": ["Events"],
        "operationId": "memorySubscribe",
        "summary": "Subscribe to memory mutations",
        "description": "Scoped event stream: only `memory.*` events. Filters by tag, key prefix, or namespace.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "tags": { "type": "array", "items": { "type": "string" } },
                  "key_prefix": { "type": "string" },
                  "namespace": { "type": "string" },
                  "transport": { "type": "string", "enum": ["sse", "websocket", "webhook"] }
                }
              },
              "example": {
                "tags": ["preferences"],
                "transport": "sse"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Subscription established",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/Event" }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/keys": {
      "post": {
        "tags": ["Keys"],
        "operationId": "keysCreate",
        "summary": "Create an API key",
        "description": "Mint a new `sk-rem-...` key scoped to the current account. Returns the full secret exactly once.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/ApiKeyCreateRequest" },
              "example": { "name": "ci-deploy", "scopes": ["memory:read", "memory:write", "dream:run"] }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Key created",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ApiKey" },
                "example": {
                  "id": "key_01HP3ZKB5C6D7E8F9GHJKM",
                  "name": "ci-deploy",
                  "key": "sk-rem-a1b2c3d4e5f6g7h8i9j0",
                  "scopes": ["memory:read", "memory:write", "dream:run"],
                  "created_at": "2026-04-17T12:00:00Z"
                }
              }
            }
          },
          "401": { "$ref": "#/components/responses/Unauthorized" }
        }
      }
    },
    "/.well-known/agent-card.json": {
      "get": {
        "tags": ["Agents"],
        "operationId": "agentCard",
        "summary": "A2A agent card",
        "description": "Public agent card describing REM Labs capabilities for agent-to-agent discovery. No authentication required.",
        "security": [],
        "responses": {
          "200": {
            "description": "Agent card",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/AgentCard" },
                "example": {
                  "name": "REM Labs",
                  "description": "The continuity layer for intelligence.",
                  "url": "https://remlabs.ai",
                  "version": "4.0.0",
                  "capabilities": ["memory.store", "memory.search", "dream.run", "channels.publish"]
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "sk-rem-...",
        "description": "REM Labs API keys begin with `sk-rem-`. Provision at https://remlabs.ai/console or via POST /v1/keys."
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Missing or invalid API key",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" },
            "example": { "error": { "code": "unauthorized", "message": "Missing or invalid API key." } }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded",
        "content": {
          "application/json": {
            "schema": { "$ref": "#/components/schemas/Error" },
            "example": { "error": { "code": "rate_limited", "message": "Too many requests. Retry after 60s." } }
          }
        }
      }
    },
    "schemas": {
      "Health": {
        "type": "object",
        "properties": {
          "ok": { "type": "boolean" },
          "service": { "type": "string" },
          "version": { "type": "string" },
          "ts": { "type": "string", "format": "date-time" }
        }
      },
      "Memory": {
        "type": "object",
        "required": ["id", "key", "value"],
        "properties": {
          "id": { "type": "string", "description": "Canonical memory ID (ULID)." },
          "key": { "type": "string" },
          "value": { "type": "string" },
          "tags": { "type": "array", "items": { "type": "string" } },
          "metadata": { "type": "object", "additionalProperties": true },
          "namespace": { "type": "string" },
          "created_at": { "type": "string", "format": "date-time" },
          "updated_at": { "type": "string", "format": "date-time" }
        }
      },
      "MemorySetRequest": {
        "type": "object",
        "required": ["key", "value"],
        "properties": {
          "key": { "type": "string" },
          "value": { "type": "string" },
          "tags": { "type": "array", "items": { "type": "string" } },
          "metadata": { "type": "object", "additionalProperties": true },
          "namespace": { "type": "string" }
        }
      },
      "MemorySearchRequest": {
        "type": "object",
        "required": ["query"],
        "properties": {
          "query": { "type": "string" },
          "limit": { "type": "integer", "default": 10, "maximum": 100 },
          "threshold": { "type": "number", "format": "float", "minimum": 0, "maximum": 1 },
          "tags": { "type": "array", "items": { "type": "string" } },
          "namespace": { "type": "string" }
        }
      },
      "MemorySearchResponse": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "allOf": [
                { "$ref": "#/components/schemas/Memory" },
                {
                  "type": "object",
                  "properties": { "score": { "type": "number", "format": "float" } }
                }
              ]
            }
          },
          "total": { "type": "integer" },
          "took_ms": { "type": "integer" }
        }
      },
      "RememberRequest": {
        "type": "object",
        "required": ["content"],
        "properties": {
          "content": { "type": "string" },
          "namespace": { "type": "string" },
          "tags": { "type": "array", "items": { "type": "string" } }
        }
      },
      "Dream": {
        "type": "object",
        "required": ["id", "status"],
        "properties": {
          "id": { "type": "string" },
          "status": { "type": "string", "enum": ["running", "complete", "failed"] },
          "strategy": {
            "type": "string",
            "enum": ["synthesize", "pattern_extract", "insight_generate", "compress", "associate", "validate", "evolve", "forecast", "reflect"]
          },
          "namespace": { "type": "string" },
          "started_at": { "type": "string", "format": "date-time" },
          "completed_at": { "type": "string", "format": "date-time" },
          "memories_created": { "type": "integer" },
          "insights": { "type": "array", "items": { "type": "string" } },
          "contradictions_found": { "type": "integer" }
        }
      },
      "DreamRequest": {
        "type": "object",
        "properties": {
          "namespace": { "type": "string", "default": "default" },
          "strategy": {
            "type": "string",
            "enum": ["synthesize", "pattern_extract", "insight_generate", "compress", "associate", "validate", "evolve", "forecast", "reflect", "all"]
          },
          "since": { "type": "string", "format": "date-time" }
        }
      },
      "Channel": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "name": { "type": "string" },
          "mode": { "type": "string", "enum": ["broadcast", "queue"] },
          "retention": { "type": "string" },
          "subscribers": { "type": "integer" },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "ChannelCreateRequest": {
        "type": "object",
        "required": ["name"],
        "properties": {
          "name": { "type": "string" },
          "mode": { "type": "string", "enum": ["broadcast", "queue"], "default": "broadcast" },
          "retention": { "type": "string", "default": "24h" }
        }
      },
      "Webhook": {
        "type": "object",
        "required": ["id", "url"],
        "properties": {
          "id": { "type": "string" },
          "url": { "type": "string", "format": "uri" },
          "events": { "type": "array", "items": { "type": "string" } },
          "active": { "type": "boolean" },
          "created_at": { "type": "string", "format": "date-time" }
        }
      },
      "WebhookCreateRequest": {
        "type": "object",
        "required": ["url", "events"],
        "properties": {
          "url": { "type": "string", "format": "uri" },
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": ["memory.created", "memory.updated", "memory.deleted", "dream.started", "dream.completed", "channel.message"]
            }
          },
          "secret": { "type": "string", "description": "HMAC secret used to sign the `X-RemLabs-Signature` header." }
        }
      },
      "Event": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "type": { "type": "string" },
          "data": { "type": "object", "additionalProperties": true },
          "ts": { "type": "string", "format": "date-time" }
        }
      },
      "EventSubscribeRequest": {
        "type": "object",
        "required": ["events"],
        "properties": {
          "events": { "type": "array", "items": { "type": "string" } },
          "transport": { "type": "string", "enum": ["sse", "websocket", "webhook"], "default": "sse" },
          "filter": { "type": "object", "additionalProperties": true }
        }
      },
      "ApiKey": {
        "type": "object",
        "required": ["id", "key"],
        "properties": {
          "id": { "type": "string" },
          "name": { "type": "string" },
          "key": { "type": "string", "description": "The secret. Shown only on create." },
          "scopes": { "type": "array", "items": { "type": "string" } },
          "created_at": { "type": "string", "format": "date-time" },
          "last_used_at": { "type": "string", "format": "date-time" }
        }
      },
      "ApiKeyCreateRequest": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "scopes": { "type": "array", "items": { "type": "string" } },
          "expires_at": { "type": "string", "format": "date-time" }
        }
      },
      "AgentCard": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "description": { "type": "string" },
          "url": { "type": "string", "format": "uri" },
          "version": { "type": "string" },
          "capabilities": { "type": "array", "items": { "type": "string" } }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": { "type": "string" },
              "message": { "type": "string" },
              "request_id": { "type": "string" }
            }
          }
        }
      }
    }
  },
  "externalDocs": {
    "description": "Full API documentation & guides",
    "url": "https://remlabs.ai/docs"
  }
}
