openapi: 3.0.3
info:
  title: SOAT Memory Stores API
  version: 1.0.0
  description: API for managing memory store configurations for RAG (Retrieval-Augmented Generation)
  contact:
    name: SOAT Team
    url: https://github.com/ttoss/soat
servers:
  - url: '{baseUrl}'
    description: Base URL of your SOAT deployment (e.g. https://your-soat.com or http://localhost:5047)
    variables:
      baseUrl:
        description: The base URL of your SOAT deployment
        default: http://localhost:5047
tags:
  - name: MemoryStores
    description: Manage memory store configurations for document retrieval
security:
  - bearerAuth: []
paths:
  /api/v1/memory-stores:
    get:
      tags:
        - MemoryStores
      summary: List memory stores
      description: Returns a list of memory store configurations for a project
      operationId: listMemoryStores
      parameters:
        - name: project_id
          in: query
          description: Project ID (required if not using project key auth)
          schema:
            type: string
            example: proj_V1StGXR8Z5jdHi6B
        - $ref: './tags.yaml#/components/parameters/TagsQuery'
        - $ref: './pagination.yaml#/components/parameters/Limit'
        - $ref: './pagination.yaml#/components/parameters/Offset'
      responses:
        '200':
          description: List of memory stores
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                  - total
                  - limit
                  - offset
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/MemoryStore'
                  total:
                    type: integer
                  limit:
                    type: integer
                  offset:
                    type: integer
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
    post:
      tags:
        - MemoryStores
      summary: Create a memory store
      description: Creates a new memory store configuration in a project
      operationId: createMemoryStore
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - name
              additionalProperties: false
              properties:
                project_id:
                  x-soat-ref: projects
                  type: string
                  description: Project ID (required if not using project key auth)
                  example: proj_V1StGXR8Z5jdHi6B
                name:
                  type: string
                  description: Memory store name
                  example: Product Documentation
                description:
                  type: string
                  description: Optional description
                  example: Retrieves product docs for support queries
                tags:
                  description: >-
                    Optional key-value tags. Scopes the memory store in knowledge
                    search, where every requested pair must match exactly.
                  allOf:
                    - $ref: './tags.yaml#/components/schemas/TagBag'
                duplicate_threshold:
                  type: number
                  nullable: true
                  description: >-
                    The store's dedup policy: cosine similarity at or above
                    which an incoming fact is already known and the write is
                    skipped. `null` (the default) uses the algorithm constant
                    `0.95`. A single `POST /api/v1/memories` call may override
                    it; the agent tool and the post-turn rule never can.
                  minimum: 0
                  maximum: 1
                  example: 0.95
                supersede_threshold:
                  type: number
                  nullable: true
                  description: >-
                    Cosine similarity at or above which an incoming fact
                    restates a known one that has changed: the matched memory is
                    invalidated and replaced. `null` (the default) uses the
                    algorithm constant `0.90`. Must be lower than the effective
                    `duplicate_threshold`, or the write is rejected with
                    `400 VALIDATION_FAILED` — equal makes `superseded`
                    unreachable and inverted swallows `skipped`.
                  minimum: 0
                  maximum: 1
                  example: 0.9
      responses:
        '201':
          description: Memory store created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MemoryStore'
        '400':
          description: >-
            Bad request — a missing required field, a threshold outside
            `[0, 1]`, or a pair that is not
            `supersede_threshold < duplicate_threshold`.
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
  /api/v1/memory-stores/{memory_store_id}:
    get:
      tags:
        - MemoryStores
      summary: Get a memory store
      description: Returns a single memory store configuration by ID
      operationId: getMemoryStore
      x-soat-resource:
        kind: memory_store
        from: memory_store_id
      parameters:
        - name: memory_store_id
          in: path
          required: true
          schema:
            type: string
            example: mstore_V1StGXR8Z5jdHi6B
      responses:
        '200':
          description: Memory store found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MemoryStore'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Memory store not found
        '500':
          description: Internal server error
    put:
      tags:
        - MemoryStores
      summary: Update a memory store
      description: Updates an existing memory store configuration
      operationId: updateMemoryStore
      x-soat-resource:
        kind: memory_store
        from: memory_store_id
      parameters:
        - name: memory_store_id
          in: path
          required: true
          schema:
            type: string
            example: mstore_V1StGXR8Z5jdHi6B
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                name:
                  type: string
                  description: Memory store name
                description:
                  type: string
                  nullable: true
                  description: Optional description
                tags:
                  description: >-
                    Optional key-value tags. Replaces the stored bag; `null`
                    clears it.
                  allOf:
                    - $ref: './tags.yaml#/components/schemas/NullableTagBag'
                duplicate_threshold:
                  type: number
                  nullable: true
                  description: >-
                    The store's dedup policy: cosine similarity at or above
                    which an incoming fact is already known and the write is
                    skipped. `null` (the default) uses the algorithm constant
                    `0.95`. A single `POST /api/v1/memories` call may override
                    it; the agent tool and the post-turn rule never can.
                  minimum: 0
                  maximum: 1
                  example: 0.95
                supersede_threshold:
                  type: number
                  nullable: true
                  description: >-
                    Cosine similarity at or above which an incoming fact
                    restates a known one that has changed: the matched memory is
                    invalidated and replaced. `null` (the default) uses the
                    algorithm constant `0.90`. Must be lower than the effective
                    `duplicate_threshold`, or the write is rejected with
                    `400 VALIDATION_FAILED` — equal makes `superseded`
                    unreachable and inverted swallows `skipped`.
                  minimum: 0
                  maximum: 1
                  example: 0.9
      responses:
        '200':
          description: Memory store updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MemoryStore'
        '400':
          description: >-
            Bad request — a threshold outside `[0, 1]`, or a pair that is not
            `supersede_threshold < duplicate_threshold` once the stored values
            this request does not replace are applied.
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Memory store not found
        '500':
          description: Internal server error
    delete:
      tags:
        - MemoryStores
      summary: Delete a memory store
      description: Deletes a memory store configuration
      operationId: deleteMemoryStore
      x-soat-resource:
        kind: memory_store
        from: memory_store_id
      parameters:
        - name: memory_store_id
          in: path
          required: true
          schema:
            type: string
            example: mstore_V1StGXR8Z5jdHi6B
      responses:
        '204':
          description: Memory store deleted
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Memory store not found
        '500':
          description: Internal server error
  /api/v1/memory-stores/{memory_store_id}/assertions:
    get:
      tags:
        - MemoryStores
      summary: List a memory store's write assertions
      description: >-
        Returns the store's write ledger, newest first: one row per write
        attempt, skips included. This is how "which write path is filling this
        store?" is asked — a question no column on a memory row could answer,
        because a skipped write produced no memory at all.
      operationId: listMemoryStoreAssertions
      x-soat-resource:
        kind: memory_store
        from: memory_store_id
      x-iam-action: memories:ListMemoryAssertions
      parameters:
        - name: memory_store_id
          in: path
          required: true
          schema:
            type: string
            example: mstore_V1StGXR8Z5jdHi6B
        - name: mechanism
          in: query
          required: false
          description: Only assertions that came through this door.
          schema:
            type: string
            enum: [tool, rule, api, formation]
        - name: outcome
          in: query
          required: false
          description: Only assertions that resolved this way.
          schema:
            type: string
            enum: [created, superseded, skipped]
        - name: generation_id
          in: query
          required: false
          description: >-
            Only assertions made during this generation. A generation that does
            not exist matches nothing rather than widening to the whole store.
          schema:
            type: string
            example: gen_V1StGXR8Z5jdHi6B
        - name: from
          in: query
          required: false
          description: Only assertions recorded at or after this instant (ISO 8601).
          schema:
            type: string
            format: date-time
        - name: to
          in: query
          required: false
          description: Only assertions recorded at or before this instant (ISO 8601).
          schema:
            type: string
            format: date-time
        - $ref: './pagination.yaml#/components/parameters/Limit'
        - $ref: './pagination.yaml#/components/parameters/Offset'
      responses:
        '200':
          description: List of assertions
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                  - total
                  - limit
                  - offset
                properties:
                  data:
                    type: array
                    items:
                      $ref: './memory-assertions.yaml#/components/schemas/MemoryAssertion'
                  total:
                    type: integer
                  limit:
                    type: integer
                  offset:
                    type: integer
        '400':
          description: An unknown `mechanism` or `outcome`, or a `from` or `to` that is not a timestamp
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Memory store not found
        '500':
          description: Internal server error
  /api/v1/memory-stores/{memory_store_id}/export:
    get:
      tags:
        - MemoryStores
      summary: Export a memory store's memories as NDJSON
      description: >-
        Streams one store's memories as newline-delimited JSON — one memory
        object per line, oldest first. Invalidated memories (retracted or
        superseded) are left out unless `include_invalidated` asks for them, so
        the file holds what the store currently asserts. The rows are the rows
        the listing returns for the same caller.
      operationId: exportMemories
      x-soat-resource:
        kind: memory_store
        from: memory_store_id
      # Not a tool: the response is a stream with no JSON projection, and an
      # export is deliberately unbounded, so the callable form of "read the
      # memories" is `listMemories`, which is paged.
      x-soat-mcp-exclude: true
      parameters:
        - name: memory_store_id
          in: path
          required: true
          description: Memory store whose memories are exported
          schema:
            type: string
            example: mem_store_V1StGXR8Z5jdHi6B
        - name: include_invalidated
          in: query
          description: Include memories that were retracted or superseded
          schema:
            type: boolean
            default: false
        - $ref: './tags.yaml#/components/parameters/TagsQuery'
      responses:
        '200':
          description: >-
            A newline-delimited stream of memories. Each line is a JSON object
            with the same fields as `Memory`.
          content:
            application/x-ndjson:
              schema:
                type: string
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Memory store not found
  /api/v1/memory-stores/{memory_store_id}/tags:
    get:
      tags:
        - MemoryStores
      summary: Get memory store tags
      description: Returns all tags attached to the memory store
      operationId: getMemoryStoreTags
      x-soat-resource:
        kind: memory_store
        from: memory_store_id
      x-iam-action: memories:GetMemoryStore
      parameters:
        - name: memory_store_id
          in: path
          required: true
          description: Memory store ID
          schema:
            type: string
            example: mstore_V1StGXR8Z5jdHi6B
      responses:
        '200':
          description: Memory store tags
          content:
            application/json:
              schema:
                $ref: './tags.yaml#/components/schemas/TagBag'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Memory store not found
    put:
      tags:
        - MemoryStores
      summary: Replace memory store tags
      description: Replaces all tags on the memory store with the provided tags (not merged)
      operationId: replaceMemoryStoreTags
      x-soat-resource:
        kind: memory_store
        from: memory_store_id
      x-iam-action: memories:UpdateMemoryStore
      parameters:
        - name: memory_store_id
          in: path
          required: true
          description: Memory store ID
          schema:
            type: string
            example: mstore_V1StGXR8Z5jdHi6B
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: './tags.yaml#/components/schemas/TagBag'
      responses:
        '200':
          description: Tags replaced
          content:
            application/json:
              schema:
                $ref: './tags.yaml#/components/schemas/TagBag'
        '400':
          description: Body is not an object of string values
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Memory store not found
    patch:
      tags:
        - MemoryStores
      summary: Merge memory store tags
      description: Merges provided tags into the memory store's existing tags (existing tags are preserved unless overridden)
      operationId: mergeMemoryStoreTags
      x-soat-resource:
        kind: memory_store
        from: memory_store_id
      x-iam-action: memories:UpdateMemoryStore
      parameters:
        - name: memory_store_id
          in: path
          required: true
          description: Memory store ID
          schema:
            type: string
            example: mstore_V1StGXR8Z5jdHi6B
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: './tags.yaml#/components/schemas/TagBag'
      responses:
        '200':
          description: Tags merged
          content:
            application/json:
              schema:
                $ref: './tags.yaml#/components/schemas/TagBag'
        '400':
          description: Body is not an object of string values
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Memory store not found
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
  schemas:
    MemoryStore:
      type: object
      properties:
        id:
          type: string
          example: mstore_V1StGXR8Z5jdHi6B
        project_id:
          x-soat-ref: projects
          type: string
          example: proj_V1StGXR8Z5jdHi6B
        name:
          type: string
          example: Product Documentation
        description:
          type: string
          nullable: true
          example: Retrieves product docs for support queries
        tags:
          description: >-
            Key-value tags for filtering in knowledge search.
          allOf:
            - $ref: './tags.yaml#/components/schemas/TagBag'
        duplicate_threshold:
          type: number
          nullable: true
          description: >-
            The store's duplicate cutoff, or `null` when it has never been set.
            Reported as `null` rather than as the constant it resolves to: a
            store with no policy must read differently from one pinned to
            today's default.
          example: 0.95
        supersede_threshold:
          type: number
          nullable: true
          description: >-
            The store's supersede cutoff, or `null` when it has never been set.
          example: 0.9
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
