openapi: 3.0.3
info:
  title: SOAT Ingestion Rules API
  version: 1.0.0
  description: >-
    API for managing ingestion rules, which route a file content_type to a
    converter (tool or agent) so non-text files (images, audio, scanned PDFs)
    can be ingested into Documents.
  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: Ingestion Rules
    description: Route content types to converter tools or agents during ingestion
security:
  - bearerAuth: []
paths:
  /api/v1/ingestion-rules:
    get:
      tags:
        - Ingestion Rules
      summary: List ingestion rules
      description: Returns the ingestion rules for a project
      operationId: listIngestionRules
      parameters:
        - name: project_id
          in: query
          description: Project ID (required if not using project key auth)
          schema:
            type: string
            example: proj_V1StGXR8Z5jdHi6B
        - name: limit
          in: query
          description: Number of results per page
          schema:
            type: integer
            default: 25
        - name: offset
          in: query
          description: Number of results to skip
          schema:
            type: integer
            default: 0
      responses:
        '200':
          description: List of ingestion rules
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/IngestionRule'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '500':
          description: Internal server error
    post:
      tags:
        - Ingestion Rules
      summary: Create an ingestion rule
      description: >-
        Creates a rule mapping a content_type glob to a converter. Exactly one
        of tool_id or agent_id must be set.
      operationId: createIngestionRule
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - content_type_glob
              properties:
                project_id:
                  x-soat-ref: projects
                  type: string
                  description: Project ID (required if not using project key auth)
                  example: proj_V1StGXR8Z5jdHi6B
                content_type_glob:
                  type: string
                  description: MIME type glob matched against a file's content_type
                  example: image/*
                tool_id:
                  x-soat-ref: tools
                  type: string
                  description: Converter tool id (mutually exclusive with agent_id)
                  example: tool_V1StGXR8Z5jdHi6B
                agent_id:
                  x-soat-ref: agents
                  type: string
                  description: Converter agent id (mutually exclusive with tool_id)
                  example: agent_V1StGXR8Z5jdHi6B
                action:
                  type: string
                  description: Operation id, required for soat/mcp tool converters
                preset_parameters:
                  type: object
                  description: Merged into the tool input before invocation (tool converters only)
                native_extraction:
                  type: string
                  enum: [first, skip]
                  description: >-
                    For native types (PDF/text): `first` (default) converts only
                    when native extraction yields no text; `skip` always converts.
                file_delivery:
                  type: string
                  enum: [base64, download_url]
                  description: How the file reaches a tool converter (default base64)
                chunk_strategy:
                  type: string
                  enum: [page, whole, size]
                  description: Default chunk strategy, overridable per ingest request
                chunk_size:
                  type: integer
                  description: Default window size in characters for the size strategy
                chunk_overlap:
                  type: integer
                  description: Default overlap in characters for the size strategy
                metadata:
                  type: object
                  description: Arbitrary JSON metadata
      responses:
        '201':
          description: Ingestion rule created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IngestionRule'
        '400':
          description: Validation failed (e.g. tool_id and agent_id both set or both missing)
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '409':
          description: A rule for this content_type_glob already exists in the project
        '500':
          description: Internal server error
  /api/v1/ingestion-rules/{ingestion_rule_id}:
    get:
      tags:
        - Ingestion Rules
      summary: Get an ingestion rule
      description: Returns a specific ingestion rule
      operationId: getIngestionRule
      parameters:
        - name: ingestion_rule_id
          in: path
          required: true
          description: Ingestion rule ID
          schema:
            type: string
            example: igr_V1StGXR8Z5jdHi6B
      responses:
        '200':
          description: Ingestion rule details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IngestionRule'
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Ingestion rule not found
    patch:
      tags:
        - Ingestion Rules
      summary: Update an ingestion rule
      description: Updates fields of an ingestion rule
      operationId: updateIngestionRule
      parameters:
        - name: ingestion_rule_id
          in: path
          required: true
          description: Ingestion rule ID
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                content_type_glob:
                  type: string
                tool_id:
                  x-soat-ref: tools
                  type: string
                  nullable: true
                agent_id:
                  x-soat-ref: agents
                  type: string
                  nullable: true
                action:
                  type: string
                  nullable: true
                preset_parameters:
                  type: object
                  nullable: true
                native_extraction:
                  type: string
                  enum: [first, skip]
                file_delivery:
                  type: string
                  enum: [base64, download_url]
                chunk_strategy:
                  type: string
                  enum: [page, whole, size]
                  nullable: true
                chunk_size:
                  type: integer
                  nullable: true
                chunk_overlap:
                  type: integer
                  nullable: true
                metadata:
                  type: object
                  nullable: true
      responses:
        '200':
          description: Ingestion rule updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IngestionRule'
        '400':
          description: Validation failed
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Ingestion rule not found
        '409':
          description: A rule for this content_type_glob already exists in the project
    delete:
      tags:
        - Ingestion Rules
      summary: Delete an ingestion rule
      description: Deletes an ingestion rule
      operationId: deleteIngestionRule
      parameters:
        - name: ingestion_rule_id
          in: path
          required: true
          description: Ingestion rule ID
          schema:
            type: string
      responses:
        '204':
          description: Ingestion rule deleted
        '401':
          description: Unauthorized
        '403':
          description: Forbidden
        '404':
          description: Ingestion rule not found
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: JWT token or sk_ api key
  schemas:
    IngestionRule:
      type: object
      properties:
        id:
          type: string
          example: igr_V1StGXR8Z5jdHi6B
        project_id:
          x-soat-ref: projects
          type: string
        content_type_glob:
          type: string
          example: image/*
        tool_id:
          x-soat-ref: tools
          type: string
          nullable: true
        agent_id:
          x-soat-ref: agents
          type: string
          nullable: true
        action:
          type: string
          nullable: true
        preset_parameters:
          type: object
          nullable: true
        native_extraction:
          type: string
          enum: [first, skip]
        file_delivery:
          type: string
          enum: [base64, download_url]
        chunk_strategy:
          type: string
          nullable: true
        chunk_size:
          type: integer
          nullable: true
        chunk_overlap:
          type: integer
          nullable: true
        metadata:
          type: object
          nullable: true
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
