openapi: 3.0.3
info:
  title: REM Labs Memory API
  description: |
    Persistent memory for AI applications. Store, search, retrieve, and delete memories.
    94.6% recall accuracy on LongMemEval (vs 66.9% Mem0, 52.9% GPT-4).
  version: 1.0.0
  contact:
    email: hello@remlabs.ai
    url: https://remlabs.ai
  license:
    name: MIT
    url: https://github.com/remlabs/memory/blob/main/LICENSE

servers:
  - url: https://remlabs.ai/v1
    description: Production (proxied)
  - url: https://remlabs.ai/v1
    description: Production

security:
  - bearerAuth: []

paths:
  /memory-set:
    post:
      operationId: memorySet
      summary: Store a memory
      description: Store a key-value memory in the specified namespace. Overwrites if key exists.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [key, value]
              properties:
                key:
                  type: string
                  description: Unique identifier for this memory
                  example: user-pref-theme
                value:
                  type: string
                  description: The memory content to store
                  example: User prefers dark mode and compact layouts
                namespace:
                  type: string
                  default: default
                  description: Namespace to organize memories
                  example: preferences
                metadata:
                  type: object
                  description: Optional metadata tags
                  example: { "source": "conversation", "confidence": 0.95 }
      responses:
        '200':
          description: Memory stored successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  key:
                    type: string
                    example: user-pref-theme
        '401':
          description: Unauthorized - invalid or missing bearer token

  /memory/ask:
    post:
      operationId: memoryAsk
      summary: Ask a natural-language question against stored memory (94.6% LongMemEval)
      description: |
        The retrieval endpoint that scored 94.6% on LongMemEval (473/500, byte-exact upstream GPT-4o judge).
        Runs the full 6-stage pipeline:
          1. Fact lookup (knowledge graph)
          2. Multi-query expansion
          3. Vector search (chunked, HNSW)
          4. Keyword fallback (FTS5 AND-first)
          5. Full-context fallback
          6. LLM reranking
        Returns a synthesized answer with citations to the underlying memories.
        Use this instead of /memory-search when you want the system to compose an answer rather than a ranked list.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [question]
              properties:
                question:
                  type: string
                  description: Natural-language question
                  example: What did the user decide about Q2 OKRs last week?
                namespace:
                  type: string
                  default: default
                  description: Namespace to search within
      responses:
        '200':
          description: Answer with citations
          content:
            application/json:
              schema:
                type: object
                properties:
                  answer:
                    type: string
                    example: The user committed to shipping the self-host quickstart by Q2 W3.
                  citations:
                    type: array
                    items:
                      type: object
                      properties:
                        key:
                          type: string
                        value:
                          type: string
                        score:
                          type: number
                  latency_ms:
                    type: integer
                    example: 420
        '401':
          description: Unauthorized

  /memory/store-batch:
    post:
      operationId: memoryStoreBatch
      summary: Bulk-ingest memories in a single call
      description: Store many memories at once. Used by importers (Obsidian, ChatGPT export, Notion) and the LongMemEval harness.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [items]
              properties:
                items:
                  type: array
                  items:
                    type: object
                    required: [value]
                    properties:
                      value:
                        type: string
                        description: The memory content to store (required — fields named "content" or "text" are not accepted)
                      key:
                        type: string
                        description: Optional stable key; auto-generated if omitted
                      namespace:
                        type: string
                        description: Namespace to organize memories (default "default")
                      metadata:
                        type: object
                        description: Optional metadata object (category, tags, entities, source, etc.)
      responses:
        '200':
          description: Batch accepted
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  count:
                    type: integer
                  ids:
                    type: array
                    items:
                      type: string
        '401':
          description: Unauthorized

  /memory/clear:
    post:
      operationId: memoryClear
      summary: Clear all memories in a namespace
      description: Irreversibly delete every memory in the given namespace. Intended for evaluation resets and test setups, not for GDPR forget() (use /memory-delete for that).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [namespace]
              properties:
                namespace:
                  type: string
                  example: eval-run-2026-04-17
      responses:
        '200':
          description: Namespace cleared
        '401':
          description: Unauthorized

  /memory/dream/start:
    post:
      operationId: dreamStart
      summary: Trigger a Dream Engine consolidation run
      description: |
        Kicks off an asynchronous Dream Engine cycle over the specified namespace.
        9 strategies available (summarize, connect, pattern, contradict, reflect, synthesize, refine, sleep, rem).
        Returns a job id to poll via /memory/dream/status/{id}.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                namespace:
                  type: string
                  default: default
                strategies:
                  type: array
                  items:
                    type: string
                task:
                  type: string
                  description: Optional directed-dream task (e.g., "Why is churn up?")
      responses:
        '202':
          description: Dream job accepted
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    example: drm_9kQ2abc
                  status:
                    type: string
                    example: queued
        '401':
          description: Unauthorized

  /memory/dream/status/{id}:
    get:
      operationId: dreamStatus
      summary: Poll the status of a dream job
      description: Returns current progress (stages complete, insights emitted, duration).
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Dream status
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                  status:
                    type: string
                    enum: [queued, running, complete, failed]
                  stages:
                    type: integer
                  insights:
                    type: integer
                  started_at:
                    type: string
                    format: date-time
                  completed_at:
                    type: string
                    format: date-time
        '401':
          description: Unauthorized
        '404':
          description: Dream job not found

  /memory-search:
    post:
      operationId: memorySearch
      summary: Search memories by natural language query (raw ranked results)
      description: |
        Semantic search across stored memories. Returns ranked results with relevance scores.
        This is the low-level retrieval primitive. For the 94.6% LongMemEval pipeline (multi-query expansion, keyword fallback, LLM reranking, synthesized answer), use /memory/ask instead.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [query]
              properties:
                query:
                  type: string
                  description: Natural language search query
                  example: what does the user prefer?
                namespace:
                  type: string
                  default: default
                  description: Namespace to search within
                limit:
                  type: integer
                  default: 10
                  description: Max number of results
                  example: 5
                threshold:
                  type: number
                  default: 0.0
                  description: Minimum relevance score (0-1)
                  example: 0.5
      responses:
        '200':
          description: Search results
          content:
            application/json:
              schema:
                type: object
                properties:
                  results:
                    type: array
                    items:
                      type: object
                      properties:
                        key:
                          type: string
                          example: user-pref-theme
                        value:
                          type: string
                          example: User prefers dark mode and compact layouts
                        score:
                          type: number
                          example: 0.94
                        namespace:
                          type: string
                          example: preferences
                  count:
                    type: integer
                    example: 3
        '401':
          description: Unauthorized

  /memory-get:
    post:
      operationId: memoryGet
      summary: Get a specific memory by key
      description: Retrieve a single memory by its exact key.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [key]
              properties:
                key:
                  type: string
                  description: The memory key to retrieve
                  example: user-pref-theme
                namespace:
                  type: string
                  default: default
      responses:
        '200':
          description: Memory found
          content:
            application/json:
              schema:
                type: object
                properties:
                  key:
                    type: string
                    example: user-pref-theme
                  value:
                    type: string
                    example: User prefers dark mode and compact layouts
                  namespace:
                    type: string
                    example: preferences
                  metadata:
                    type: object
                  created_at:
                    type: string
                    format: date-time
                  updated_at:
                    type: string
                    format: date-time
        '404':
          description: Memory not found
        '401':
          description: Unauthorized

  /memory-delete:
    post:
      operationId: memoryDelete
      summary: Delete a memory
      description: Permanently delete a memory by key.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [key]
              properties:
                key:
                  type: string
                  description: The memory key to delete
                  example: user-pref-theme
                namespace:
                  type: string
                  default: default
      responses:
        '200':
          description: Memory deleted
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
                  deleted:
                    type: string
                    example: user-pref-theme
        '404':
          description: Memory not found
        '401':
          description: Unauthorized

  /memory-list:
    post:
      operationId: memoryList
      summary: List all memories
      description: List all memories in a namespace with optional pagination.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                namespace:
                  type: string
                  default: default
                limit:
                  type: integer
                  default: 50
                  example: 20
                offset:
                  type: integer
                  default: 0
                  example: 0
      responses:
        '200':
          description: List of memories
          content:
            application/json:
              schema:
                type: object
                properties:
                  memories:
                    type: array
                    items:
                      type: object
                      properties:
                        key:
                          type: string
                        value:
                          type: string
                        namespace:
                          type: string
                        created_at:
                          type: string
                          format: date-time
                  total:
                    type: integer
                    example: 42
                  limit:
                    type: integer
                    example: 20
                  offset:
                    type: integer
                    example: 0
        '401':
          description: Unauthorized

  /auth/bot-signup:
    post:
      operationId: botSignup
      summary: Zero-friction signup for AI agents
      description: |
        Create a provisional API key with just an email. No password required.
        The key works immediately with free tier limits (1K recalls, 100 stores).
        User must confirm their email within 7 days or the key expires.
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email]
              properties:
                email:
                  type: string
                  format: email
                  description: Email address for the account
                  example: user@example.com
      responses:
        '201':
          description: Provisional API key created
          content:
            application/json:
              schema:
                type: object
                properties:
                  api_key:
                    type: string
                    description: Provisional API key (active immediately)
                    example: rem_a1b2c3d4e5f6...
                  status:
                    type: string
                    enum: [provisional]
                    example: provisional
                  expires_in:
                    type: string
                    example: 7 days
                  expires_at:
                    type: string
                    format: date-time
                  confirm_url:
                    type: string
                    format: uri
                    description: URL for user to confirm email
                  limits:
                    type: object
                    properties:
                      max_recalls:
                        type: integer
                        example: 1000
                      max_stores:
                        type: integer
                        example: 100
                      tier:
                        type: string
                        example: free
                  message:
                    type: string
                    example: API key active immediately. User must confirm email within 7 days.
        '400':
          description: Invalid or missing email
        '429':
          description: Rate limited (3 per email per day, 10 per IP per hour)

  /auth/confirm:
    get:
      operationId: confirmEmail
      summary: Confirm provisional API key
      description: Confirms the email and upgrades the provisional key to permanent.
      security: []
      parameters:
        - name: token
          in: query
          required: true
          schema:
            type: string
          description: Confirmation token from email
      responses:
        '200':
          description: Key confirmed successfully
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum: [confirmed, already_confirmed]
                  message:
                    type: string
                  key_prefix:
                    type: string
                  email:
                    type: string
                  tier:
                    type: string
        '404':
          description: Token not found
        '410':
          description: Token expired

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: Get your API key at https://remlabs.ai/console
