openapi: 3.0.3
info:
  title: MemoryKit API
  version: "1.0"
  description: |
    Memory infrastructure for AI applications. Store content, search with hybrid retrieval, and query with RAG.
  contact:
    name: MemoryKit
    url: https://memorykit.io

servers:
  - url: https://api.memorykit.io/v1
    description: Production

security:
  - BearerAuth: []

paths:
  /memories:
    post:
      operationId: createMemory
      summary: Create Memory
      description: Store a new memory. Content is processed asynchronously.
      tags: [Memories]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateMemoryRequest"
      responses:
        "202":
          description: Accepted — processing asynchronously
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Memory"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
    get:
      operationId: listMemories
      summary: List Memories
      description: List memories with cursor-based pagination and filters.
      tags: [Memories]
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
            minimum: 1
            maximum: 100
        - name: cursor
          in: query
          schema:
            type: string
        - name: status
          in: query
          schema:
            type: string
            enum: [processing, completed, failed]
        - name: type
          in: query
          schema:
            type: string
        - name: userId
          in: query
          schema:
            type: string
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MemoryList"

  /memories/{id}:
    get:
      operationId: getMemory
      summary: Get Memory
      description: Retrieve a single memory by ID.
      tags: [Memories]
      parameters:
        - $ref: "#/components/parameters/MemoryId"
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Memory"
        "404":
          $ref: "#/components/responses/NotFound"
    delete:
      operationId: deleteMemory
      summary: Delete Memory
      description: Soft delete a memory.
      tags: [Memories]
      parameters:
        - $ref: "#/components/parameters/MemoryId"
      responses:
        "204":
          description: No Content

  /memories/search:
    post:
      operationId: searchMemories
      summary: Search Memories
      description: Hybrid search with vector similarity, full-text, and reranking.
      tags: [Memories]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SearchRequest"
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SearchResults"

  /memories/query:
    post:
      operationId: queryMemories
      summary: Query Memories (RAG)
      description: |
        Retrieve context and generate an answer using an LLM.
        Set `stream: true` to receive Server-Sent Events instead of JSON.
      tags: [Memories]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/QueryRequest"
      responses:
        "200":
          description: JSON response (stream=false) or SSE stream (stream=true)
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/QueryResult"
            text/event-stream:
              schema:
                type: string
                description: Server-Sent Events when stream=true

  /chats:
    post:
      operationId: createChat
      summary: Create Chat
      description: Create a new chat session.
      tags: [Chats]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateChatRequest"
      responses:
        "201":
          description: Created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Chat"
    get:
      operationId: listChats
      summary: List Chats
      description: List chat sessions with pagination.
      tags: [Chats]
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
        - name: cursor
          in: query
          schema:
            type: string
        - name: userId
          in: query
          schema:
            type: string
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChatList"

  /chats/{id}:
    get:
      operationId: getChatHistory
      summary: Get Chat History
      description: Retrieve the full message history for a chat session.
      tags: [Chats]
      parameters:
        - $ref: "#/components/parameters/ChatId"
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChatHistory"

  /chats/{id}/messages:
    post:
      operationId: sendMessage
      summary: Send Message
      description: Send a message and get a RAG-powered response.
      tags: [Chats]
      parameters:
        - $ref: "#/components/parameters/ChatId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SendMessageRequest"
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/MessageResponse"

  /chats/{id}/messages/stream:
    post:
      operationId: streamMessage
      summary: Stream Message
      description: Stream a chat response with Server-Sent Events.
      tags: [Chats]
      parameters:
        - $ref: "#/components/parameters/ChatId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SendMessageRequest"
      responses:
        "200":
          description: Server-Sent Events stream
          content:
            text/event-stream:
              schema:
                type: string

  /users:
    post:
      operationId: upsertUser
      summary: Upsert User
      description: Create or update a user. Upsert is idempotent.
      tags: [Users]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpsertUserRequest"
      responses:
        "200":
          description: Success
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"

  /users/{userId}:
    delete:
      operationId: deleteUser
      summary: Delete User
      description: Delete a user and optionally cascade-delete all associated data.
      tags: [Users]
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
        - name: cascade
          in: query
          schema:
            type: boolean
            default: false
          description: If true, delete all memories, chats, and events for this user
      responses:
        "204":
          description: No Content

  /users/{userId}/events:
    post:
      operationId: createEvent
      summary: Create Event
      description: Log a custom event for a user.
      tags: [Users]
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateEventRequest"
      responses:
        "201":
          description: Created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Event"

components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: "ctx_*"

  parameters:
    MemoryId:
      name: id
      in: path
      required: true
      schema:
        type: string
    ChatId:
      name: id
      in: path
      required: true
      schema:
        type: string

  responses:
    BadRequest:
      description: Bad Request
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    Unauthorized:
      description: Unauthorized
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    NotFound:
      description: Not Found
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"

  schemas:
    Memory:
      type: object
      properties:
        id:
          type: string
          example: mem_abc123
        status:
          type: string
          enum: [processing, completed, failed]
        content:
          type: string
        title:
          type: string
        type:
          type: string
        tags:
          type: array
          items:
            type: string
        metadata:
          type: object
          additionalProperties: true
        userId:
          type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    CreateMemoryRequest:
      type: object
      required: [content]
      properties:
        content:
          type: string
          description: The text content to store
        title:
          type: string
          description: Title (auto-extracted if omitted)
        type:
          type: string
          description: Content type (auto-detected if omitted)
        tags:
          type: array
          items:
            type: string
          description: Tags for filtering (auto-extracted if omitted)
        metadata:
          type: object
          additionalProperties: true
          description: Arbitrary key-value pairs
        userId:
          type: string
          description: Associate with a user

    MemoryList:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Memory"
        has_more:
          type: boolean
        cursor:
          type: string

    SearchRequest:
      type: object
      required: [query]
      properties:
        query:
          type: string
        filters:
          type: object
          additionalProperties: true
        limit:
          type: integer
          default: 10
        includeGraph:
          type: boolean
          default: false
        userId:
          type: string

    SearchResult:
      type: object
      properties:
        id:
          type: string
        content:
          type: string
        score:
          type: number
        memory_id:
          type: string
        metadata:
          type: object

    SearchResults:
      type: object
      properties:
        results:
          type: array
          items:
            $ref: "#/components/schemas/SearchResult"
        total_results:
          type: integer

    QueryRequest:
      type: object
      required: [query]
      properties:
        query:
          type: string
        stream:
          type: boolean
          default: false
          description: When true, return Server-Sent Events instead of JSON
        mode:
          type: string
          enum: [fast, balanced, precise]
          default: balanced
        maxSources:
          type: integer
        instructions:
          type: string
        userId:
          type: string

    QueryResult:
      type: object
      properties:
        answer:
          type: string
        sources:
          type: array
          items:
            $ref: "#/components/schemas/SearchResult"
        usage:
          type: object
          properties:
            tokens_used:
              type: integer

    Chat:
      type: object
      properties:
        id:
          type: string
          example: chat_abc123
        userId:
          type: string
        title:
          type: string
        created_at:
          type: string
          format: date-time

    CreateChatRequest:
      type: object
      properties:
        userId:
          type: string
        title:
          type: string

    ChatList:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Chat"
        has_more:
          type: boolean

    ChatHistory:
      type: object
      properties:
        id:
          type: string
        title:
          type: string
        messages:
          type: array
          items:
            $ref: "#/components/schemas/Message"

    Message:
      type: object
      properties:
        id:
          type: string
        role:
          type: string
          enum: [user, assistant]
        content:
          type: string
        sources:
          type: array
          items:
            $ref: "#/components/schemas/SearchResult"
        created_at:
          type: string
          format: date-time

    SendMessageRequest:
      type: object
      required: [message]
      properties:
        message:
          type: string
        mode:
          type: string
          enum: [fast, balanced, precise]
          default: balanced

    MessageResponse:
      type: object
      properties:
        message:
          $ref: "#/components/schemas/Message"

    User:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        email:
          type: string
        metadata:
          type: object
          additionalProperties: true
        created_at:
          type: string
          format: date-time

    UpsertUserRequest:
      type: object
      required: [id]
      properties:
        id:
          type: string
          description: Your app's user ID
        name:
          type: string
        email:
          type: string
        metadata:
          type: object
          additionalProperties: true

    Event:
      type: object
      properties:
        id:
          type: string
        userId:
          type: string
        type:
          type: string
        data:
          type: object
        created_at:
          type: string
          format: date-time

    CreateEventRequest:
      type: object
      required: [type]
      properties:
        type:
          type: string
          description: Event type (e.g., page_view, purchase)
        data:
          type: object
          description: Event payload

    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
            status:
              type: integer
