openapi: 3.1.0
info:
  title: Fluent API
  version: 1.0.0
  summary: Run Fluent agents and access connected data.
  description: |
    The public Fluent API powers the CLI and customer integrations.
    Most successful responses wrap their payload in a data property. Errors
    contain detail and status properties without that envelope.
servers:
  - url: https://www.fluenterp.com
    description: Production
tags:
  - name: Discovery
    description: Find the API, its scopes, and its policies without a credential.
  - name: Agents
    description: Discover agents and prepare their input files.
  - name: Runs
    description: Start and monitor asynchronous agent runs.
  - name: Documents
    description: Read, process, and delete documents produced by agents.
  - name: Connections
    description: Discover connected systems and read their records.
  - name: Databases
    description: Discover queryable databases and schemas.
  - name: Tables
    description: Read records from a queryable table.
  - name: Queries
    description: Run queries against accessible databases.
  - name: Utilities
    description: Search the web and manage conversation resources.
  - name: MCP
    x-group: Model Context Protocol
    description: Connect an external MCP client to an agent's tools.
security:
  - ApiKey: []
  - BearerCredential: []
paths:
  /api/v1:
    get:
      tags: [Discovery]
      operationId: getApiIndex
      summary: Get the API index
      description: |
        Returns the public, unauthenticated index of the API: the base URL,
        supported authentication methods and OAuth scopes, the rate-limit and
        deprecation conventions, and links to the documentation and this
        specification. Use it to discover the current surface without a
        credential.
      security: []
      responses:
        "200":
          description: API index
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ApiIndex"
  /api/v1/agents:
    get:
      tags: [Agents]
      operationId: listAgents
      security:
        - ApiKey: []
        - BearerCredential: []
        - OAuth2: ["agents:read"]
      summary: List agents
      description: |
        Returns the agents visible to the authenticated user, ordered by name.
        OAuth tokens require the agents:read scope.
      responses:
        "200":
          description: Accessible agents
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AgentsEnvelope"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/agents/{agent_id}/upload-urls:
    post:
      tags: [Agents]
      operationId: createAgentUploadUrls
      security:
        - ApiKey: []
        - BearerCredential: []
        - OAuth2: ["runs:write"]
      summary: Create file upload URLs
      description: |
        Creates one presigned URL per file. Upload each file directly with PUT
        and the same Content-Type before creating a run. URLs expire after one
        hour. OAuth tokens require the runs:write scope.
      parameters:
        - $ref: "#/components/parameters/AgentId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UploadUrlsRequest"
            examples:
              invoice:
                value:
                  files:
                    - file_name: invoice.pdf
                      content_type: application/pdf
      responses:
        "200":
          description: Presigned upload URLs
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UploadUrlsEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/agents/{agent_id}/run:
    post:
      tags: [Runs]
      operationId: createAgentRun
      security:
        - ApiKey: []
        - BearerCredential: []
        - OAuth2: ["runs:write"]
      summary: Create an agent run
      description: |
        Starts an asynchronous run with uploaded files, a user message, or both.
        OAuth tokens require the runs:write scope. In addition to the credential
        limit, this operation is limited to 30 requests per 60 seconds per agent.
      parameters:
        - $ref: "#/components/parameters/AgentId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateRunRequest"
            examples:
              document:
                value:
                  files:
                    - file_key: agents/example/invoice.pdf
                      file_name: invoice.pdf
                      content_type: application/pdf
                  process_together: false
              text:
                value:
                  files: []
                  user_message: Summarize our open issues
      responses:
        "200":
          description: Run queued
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CreateRunEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/runs:
    get:
      tags: [Runs]
      operationId: listRuns
      security:
        - ApiKey: []
        - BearerCredential: []
        - OAuth2: ["runs:read"]
      summary: List agent runs
      description: |
        Lists API-originated runs in reverse chronological order. List items do
        not include documents or conversation IDs. OAuth tokens require the
        runs:read scope.
      parameters:
        - name: agent_id
          in: query
          description: Restrict results to one agent.
          schema:
            type: string
            format: uuid
        - name: status
          in: query
          description: Restrict results to one run status.
          schema:
            $ref: "#/components/schemas/RunStatus"
        - name: limit
          in: query
          description: Maximum number of runs to return.
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
        - name: offset
          in: query
          description: Number of matching runs to skip.
          schema:
            type: integer
            minimum: 0
            default: 0
      responses:
        "200":
          description: Paginated run summaries
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RunsListEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/runs/{id}:
    get:
      tags: [Runs]
      operationId: getRun
      security:
        - ApiKey: []
        - BearerCredential: []
        - OAuth2: ["runs:read"]
      summary: Get an agent run
      description: |
        Returns durable run status, conversations, and documents. A failed run
        can still contain documents and conversation IDs. OAuth tokens require
        the runs:read scope.
      parameters:
        - $ref: "#/components/parameters/RunId"
      responses:
        "200":
          description: Run details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RunEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/documents/{id}:
    get:
      tags: [Documents]
      operationId: getDocument
      security:
        - ApiKey: []
        - BearerCredential: []
        - OAuth2: ["runs:read"]
      summary: Get a document
      description: |
        Returns a document and its full document_data payload. OAuth tokens
        require the runs:read scope.
      parameters:
        - $ref: "#/components/parameters/DocumentId"
      responses:
        "200":
          description: Document details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DocumentEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
    post:
      tags: [Documents]
      operationId: processDocument
      security:
        - ApiKey: []
        - BearerCredential: []
        - OAuth2: ["runs:write"]
      summary: Process a document
      description: |
        Processes the document's current data into its configured system of
        record. An external-system rejection is returned as an updated document
        with status error and HTTP 200. OAuth tokens require runs:write.
      parameters:
        - $ref: "#/components/parameters/DocumentId"
      responses:
        "200":
          description: Updated document
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DocumentEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "409":
          $ref: "#/components/responses/Conflict"
        "429":
          $ref: "#/components/responses/RateLimited"
    delete:
      tags: [Documents]
      operationId: deleteDocument
      security:
        - ApiKey: []
        - BearerCredential: []
        - OAuth2: ["runs:write"]
      summary: Delete a document
      description: |
        Cancels in-flight work and moves the document to trash. This is a soft
        delete. OAuth tokens require the runs:write scope.
      parameters:
        - $ref: "#/components/parameters/DocumentId"
      responses:
        "200":
          description: Document moved to trash
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeleteDocumentEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "403":
          $ref: "#/components/responses/Forbidden"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/connections:
    get:
      tags: [Connections]
      operationId: listConnections
      summary: List connections
      description: |
        Lists connections visible to the API-key user. This legacy operation
        returns a top-level array instead of a data envelope.
      parameters:
        - $ref: "#/components/parameters/Offset"
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            default: 100
          description: Maximum number of connections to return.
      responses:
        "200":
          description: Connections
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Connection"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/connections/{connection_id}/entities:
    get:
      tags: [Connections]
      operationId: listConnectionEntities
      summary: List connection entities
      description: |
        Lists the entities exposed by a connection. This legacy operation
        returns a top-level array instead of a data envelope.
      parameters:
        - $ref: "#/components/parameters/ConnectionId"
        - $ref: "#/components/parameters/Offset"
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            default: 1000
          description: Maximum number of entities to return.
      responses:
        "200":
          description: Connection entities
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/ConnectionEntity"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/connections/{connection_id}/records:
    get:
      tags: [Connections]
      operationId: listConnectionRecords
      summary: List connection records
      description: |
        Reads records from one connection entity. Record shape and filter syntax
        depend on the connection. This legacy operation returns a top-level array.
      parameters:
        - $ref: "#/components/parameters/ConnectionId"
        - name: entity_id
          in: query
          required: true
          description: Entity identifier returned by the entities operation.
          schema:
            type: string
        - $ref: "#/components/parameters/Offset"
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            default: 100
          description: Maximum number of records to return.
        - name: filter
          in: query
          description: JSON-encoded filter understood by the connection.
          schema:
            type: string
          example: '{"status":"open"}'
      responses:
        "200":
          description: Connection records
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/FlexibleRecord"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/databases:
    get:
      tags: [Databases]
      operationId: listDatabases
      summary: List databases
      description: Lists queryable databases visible to the API-key user.
      responses:
        "200":
          description: Databases
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DatabasesEnvelope"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/databases/{id}/tables:
    get:
      tags: [Databases]
      operationId: listDatabaseTables
      summary: List database tables
      description: Lists the queryable tables in one accessible database.
      parameters:
        - $ref: "#/components/parameters/DatabaseId"
      responses:
        "200":
          description: Database tables
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TablesEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/databases/{id}/schema:
    get:
      tags: [Databases]
      operationId: getDatabaseSchema
      summary: Get a database schema
      description: Returns table and column metadata for an accessible database.
      parameters:
        - $ref: "#/components/parameters/DatabaseId"
      responses:
        "200":
          description: Database schema
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DatabaseSchemaEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/tables/{id}:
    get:
      tags: [Tables]
      operationId: listTableRecords
      summary: List table records
      description: |
        Reads records from a queryable table. The operation has an additional
        limit of 5 requests per 60 seconds per user.
      parameters:
        - $ref: "#/components/parameters/TableId"
        - $ref: "#/components/parameters/Offset"
        - name: limit
          in: query
          description: Maximum records to return.
          schema:
            type: integer
            minimum: 1
            maximum: 5000
            default: 100
        - name: order_by
          in: query
          description: Column used to order results.
          schema:
            type: [string, "null"]
        - name: order_direction
          in: query
          description: Sort direction when order_by is present.
          schema:
            type: string
            enum: [asc, desc]
            default: asc
        - name: incremental_value
          in: query
          description: |
            When order_by is also present, return rows whose order column is
            greater than this value.
          schema:
            type: [string, "null"]
      responses:
        "200":
          description: Table records
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RecordsEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/query:
    post:
      tags: [Queries]
      operationId: queryDatabase
      summary: Query a database
      description: |
        Executes a query against an accessible database. Queries can be
        long-running; clients should allow sufficient request time.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/QueryRequest"
            example:
              database_id: db_123
              query: SELECT * FROM invoices LIMIT 10
      responses:
        "200":
          description: Query records
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RecordsEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/search-web:
    post:
      tags: [Utilities]
      operationId: searchWeb
      summary: Search the web
      description: Searches the web and returns a generated summary with source URLs.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required: [query]
              properties:
                query:
                  type: string
                  description: Search request to answer.
            example:
              query: Current steel price trends in North America
      responses:
        "200":
          description: Search summary and citations
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SearchWebEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/threads/{id}:
    get:
      tags: [Utilities]
      operationId: getThread
      summary: Get thread messages
      description: Returns conversation messages in their stored order.
      parameters:
        - name: id
          in: path
          required: true
          description: Conversation identifier.
          schema:
            type: string
      responses:
        "200":
          description: Ordered messages
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ThreadEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/sandbox-snapshots:
    post:
      tags: [Utilities]
      operationId: createSandboxSnapshotUpload
      summary: Create a snapshot upload URL
      description: |
        Creates a presigned URL for uploading a sandbox snapshot and records the
        snapshot against an accessible conversation.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SnapshotUploadRequest"
            example:
              conversationId: conversation_123
              sizeBytes: 1048576
      responses:
        "200":
          description: Snapshot upload target
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SnapshotUploadEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
        "429":
          $ref: "#/components/responses/RateLimited"
    get:
      tags: [Utilities]
      operationId: getSandboxSnapshotDownload
      summary: Get a snapshot download URL
      description: Returns a presigned download URL, or null when no snapshot exists.
      parameters:
        - name: conversation_id
          in: query
          required: true
          description: Conversation whose snapshot should be restored.
          schema:
            type: string
      responses:
        "200":
          description: Snapshot download target
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SnapshotDownloadEnvelope"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "429":
          $ref: "#/components/responses/RateLimited"
  /api/v1/agents/{agent_id}/mcp:
    get:
      tags: [MCP]
      operationId: getAgentMcp
      summary: Send an MCP GET request
      description: |
        Handles a stateless Model Context Protocol Streamable HTTP GET request.
        Agent-scoped OAuth tokens and API keys are supported.
      parameters:
        - $ref: "#/components/parameters/AgentId"
      responses:
        "200":
          $ref: "#/components/responses/McpResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          description: |
            Missing or invalid credential. Missing credentials receive a
            WWW-Authenticate challenge with RFC 9728 protected-resource metadata.
          headers:
            WWW-Authenticate:
              schema:
                type: string
              description: OAuth protected-resource discovery challenge.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          $ref: "#/components/responses/NotFound"
    post:
      tags: [MCP]
      operationId: postAgentMcp
      summary: Send an MCP request
      description: |
        Handles a stateless Model Context Protocol Streamable HTTP request. The
        body is a JSON-RPC MCP message. Agent-scoped OAuth tokens and API keys
        are supported.
      parameters:
        - $ref: "#/components/parameters/AgentId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/McpRequest"
            example:
              jsonrpc: "2.0"
              id: 1
              method: tools/list
      responses:
        "200":
          $ref: "#/components/responses/McpResponse"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          description: |
            Missing or invalid credential. Missing credentials receive a
            WWW-Authenticate challenge with RFC 9728 protected-resource metadata.
          headers:
            WWW-Authenticate:
              schema:
                type: string
              description: OAuth protected-resource discovery challenge.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"
        "404":
          $ref: "#/components/responses/NotFound"
    delete:
      tags: [MCP]
      operationId: deleteAgentMcpSession
      summary: Close an MCP session
      description: |
        Acknowledges session cleanup requests. The transport is stateless, so
        there is no server-side session to remove.
      parameters:
        - $ref: "#/components/parameters/AgentId"
      responses:
        "200":
          description: Cleanup acknowledged
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"
components:
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: A Fluent API key beginning with fl-.
    BearerCredential:
      type: http
      scheme: bearer
      bearerFormat: Fluent API key or OAuth access token
      description: |
        A Fluent API key beginning with fl-, or an OAuth access token beginning
        with flpt_ on operations that support OAuth.
    OAuth2:
      type: oauth2
      description: |
        A Fluent OAuth access token beginning with flpt_, sent as a bearer
        credential. Tokens are granted only the scopes they request, and each
        operation below lists the scopes it requires.
      flows:
        authorizationCode:
          authorizationUrl: https://www.fluenterp.com/oauth/authorize
          tokenUrl: https://www.fluenterp.com/oauth/token
          refreshUrl: https://www.fluenterp.com/oauth/token
          scopes:
            agents:read: List the agents the credential's user can see.
            runs:read: Read agent runs and the documents they produce.
            runs:write: Upload files, create runs, process documents, and delete documents.
  parameters:
    AgentId:
      name: agent_id
      in: path
      required: true
      description: Fluent agent ID.
      schema:
        type: string
        format: uuid
    RunId:
      name: id
      in: path
      required: true
      description: Public run ID.
      schema:
        type: string
        format: uuid
    DocumentId:
      name: id
      in: path
      required: true
      description: Fluent document ID.
      schema:
        type: string
        format: uuid
    ConnectionId:
      name: connection_id
      in: path
      required: true
      description: Connection ID.
      schema:
        type: string
        format: uuid
    DatabaseId:
      name: id
      in: path
      required: true
      description: Database ID.
      schema:
        type: string
    TableId:
      name: id
      in: path
      required: true
      description: Table ID.
      schema:
        type: string
    Offset:
      name: offset
      in: query
      description: Number of records to skip.
      schema:
        type: integer
        minimum: 0
        default: 0
  responses:
    BadRequest:
      description: Invalid request
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    Unauthorized:
      description: Missing, invalid, expired, or unsupported credential
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    Forbidden:
      description: The credential lacks access or a required scope
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    NotFound:
      description: Resource not found or not visible to the caller
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    Conflict:
      description: Resource state conflicts with the operation
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    RateLimited:
      description: Rate limit exceeded
      headers:
        RateLimit-Limit:
          description: Requests allowed in the current window.
          schema:
            type: integer
        RateLimit-Remaining:
          description: Requests remaining in the current window.
          schema:
            type: integer
        RateLimit-Reset:
          description: Seconds until the current window resets.
          schema:
            type: integer
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            type: integer
        x-ratelimit-limit:
          description: Legacy alias of RateLimit-Limit.
          schema:
            type: integer
        x-ratelimit-remaining:
          description: Legacy alias of RateLimit-Remaining.
          schema:
            type: integer
        x-ratelimit-reset:
          description: |
            Unix timestamp (seconds) at which the current window resets. Unlike
            RateLimit-Reset, which is a delta.
          schema:
            type: string
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    McpResponse:
      description: MCP JSON-RPC response
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/McpResponse"
  schemas:
    ApiIndex:
      type: object
      description: |
        The public index of the API, served without a credential at /api/v1.
      additionalProperties: false
      required:
        - name
        - version
        - base_url
        - documentation_url
        - openapi_url
        - authentication
        - rate_limits
        - versioning
        - resources
      properties:
        name:
          type: string
          description: Human-readable API name.
        description:
          type: string
          description: What the API does.
        version:
          type: string
          description: Current major version, matching the URL path segment.
        base_url:
          type: string
          format: uri
          description: Absolute base URL every operation hangs off.
        documentation_url:
          type: string
          format: uri
        openapi_url:
          type: string
          format: uri
          description: This specification.
        developers_url:
          type: string
          format: uri
        llms_txt_url:
          type: string
          format: uri
        authentication:
          type: object
          additionalProperties: false
          required: [methods]
          properties:
            methods:
              type: array
              description: Every credential type the API accepts.
              items:
                type: object
                additionalProperties: false
                required: [type, documentation_url]
                properties:
                  type:
                    type: string
                    enum: [api_key, oauth2]
                  headers:
                    type: array
                    description: Accepted header forms, for api_key.
                    items:
                      type: string
                  self_serve:
                    type: boolean
                    description: Whether a caller can issue this credential themselves.
                  flow:
                    type: string
                    description: OAuth flow, for oauth2.
                  metadata_url:
                    type: string
                    format: uri
                    description: RFC 8414 authorization-server metadata, for oauth2.
                  scopes_supported:
                    type: array
                    items:
                      type: string
                  documentation_url:
                    type: string
                    format: uri
        rate_limits:
          type: object
          additionalProperties: false
          required: [requests, window_seconds, response_headers]
          properties:
            requests:
              type: integer
              description: Requests allowed per window.
            window_seconds:
              type: integer
            scope:
              type: string
              description: What the limit is counted against.
            response_headers:
              type: array
              items:
                type: string
            documentation_url:
              type: string
              format: uri
        versioning:
          type: object
          additionalProperties: false
          required: [strategy, current_version]
          properties:
            strategy:
              type: string
              enum: [url_path]
            current_version:
              type: string
            deprecation_headers:
              type: array
              items:
                type: string
            minimum_sunset_notice_days:
              type: integer
              description: Days between a Deprecation header appearing and its Sunset date.
            documentation_url:
              type: string
              format: uri
        resources:
          type: object
          description: Absolute URL per top-level resource, path templates included.
          additionalProperties:
            type: string
        clients:
          type: object
          additionalProperties: false
          properties:
            cli:
              type: string
              format: uri
              description: Package registry page for the official CLI.
            cli_documentation_url:
              type: string
              format: uri
        webhooks_documentation_url:
          type: string
          format: uri
    Error:
      type: object
      required: [detail]
      properties:
        detail:
          type: string
          description: Human-readable failure detail.
        status:
          type: integer
          description: HTTP status code.
      additionalProperties: true
      example:
        detail: Agent not found
        status: 404
    Agent:
      type: object
      additionalProperties: false
      required: [id, name, description]
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        description:
          type: [string, "null"]
    AgentsEnvelope:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          type: object
          additionalProperties: false
          required: [agents]
          properties:
            agents:
              type: array
              items:
                $ref: "#/components/schemas/Agent"
    UploadUrlsRequest:
      type: object
      additionalProperties: false
      required: [files]
      properties:
        files:
          type: array
          minItems: 1
          maxItems: 50
          items:
            type: object
            additionalProperties: false
            required: [file_name, content_type]
            properties:
              file_name:
                type: string
                minLength: 1
              content_type:
                type: string
                minLength: 1
    Upload:
      type: object
      additionalProperties: false
      required: [file_name, file_key, upload_url]
      properties:
        file_name:
          type: string
        file_key:
          type: string
        upload_url:
          type: string
          format: uri
    UploadUrlsEnvelope:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          type: object
          additionalProperties: false
          required: [uploads]
          properties:
            uploads:
              type: array
              items:
                $ref: "#/components/schemas/Upload"
    RunFile:
      type: object
      additionalProperties: false
      required: [file_key, file_name, content_type]
      properties:
        file_key:
          type: string
          minLength: 1
        file_name:
          type: string
          minLength: 1
        content_type:
          type: string
          minLength: 1
    BackgroundFile:
      type: object
      additionalProperties: false
      required: [file_key, file_name]
      properties:
        file_key:
          type: string
          minLength: 1
        file_name:
          type: string
          minLength: 1
    CreateRunRequest:
      type: object
      additionalProperties: false
      properties:
        files:
          type: array
          maxItems: 50
          default: []
          items:
            $ref: "#/components/schemas/RunFile"
        user_message:
          type: string
          description: Instruction or text input for the agent.
        process_together:
          type: boolean
          default: false
          description: Process foreground files in one agent conversation.
        notification_email:
          type: string
          format: email
          description: Email to notify when processing finishes.
        background_files:
          type: array
          maxItems: 10
          description: Files available to tools but not read directly by the agent.
          items:
            $ref: "#/components/schemas/BackgroundFile"
      anyOf:
        - required: [files]
          properties:
            files:
              minItems: 1
        - required: [user_message]
          properties:
            user_message:
              minLength: 1
      if:
        required: [process_together]
        properties:
          process_together:
            const: true
      then:
        properties:
          files:
            maxItems: 10
    RunStatus:
      type: string
      enum: [queued, running, completed, failed, cancelled]
    CreateRun:
      type: object
      additionalProperties: false
      required: [run_id, workflow_run_id, status, status_url, message]
      properties:
        run_id:
          type: string
          format: uuid
          description: Stable public run ID.
        workflow_run_id:
          type: string
          format: uuid
          deprecated: true
          description: Deprecated alias for run_id.
        status:
          $ref: "#/components/schemas/RunStatus"
        status_url:
          type: string
          format: uri
        message:
          type: string
    CreateRunEnvelope:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          $ref: "#/components/schemas/CreateRun"
    RunDocument:
      type: object
      required:
        - id
        - type
        - status
        - conversation_id
        - created_at
        - processed_at
        - error
        - trace_id
      properties:
        id:
          type: string
          format: uuid
        type:
          type: string
          description: Document type reported by its data payload.
        status:
          type: string
        conversation_id:
          type: [string, "null"]
        created_at:
          type: string
          format: date-time
        processed_at:
          type: [string, "null"]
          format: date-time
        error:
          type: [string, "null"]
        trace_id:
          type: [string, "null"]
    Document:
      allOf:
        - $ref: "#/components/schemas/RunDocument"
        - type: object
          required: [document_data]
          properties:
            document_data:
              description: Type-specific structured document content.
    RunSummary:
      type: object
      required:
        - id
        - workflow_type
        - agent_id
        - agent_name
        - status
        - trace_id
        - error
        - created_at
        - started_at
        - completed_at
      properties:
        id:
          type: string
          format: uuid
        workflow_type:
          type: [string, "null"]
        agent_id:
          type: string
          format: uuid
        agent_name:
          type: [string, "null"]
        status:
          $ref: "#/components/schemas/RunStatus"
        trace_id:
          type: [string, "null"]
        error:
          type: [string, "null"]
        created_at:
          type: string
          format: date-time
        started_at:
          type: [string, "null"]
          format: date-time
        completed_at:
          type: [string, "null"]
          format: date-time
    Run:
      allOf:
        - $ref: "#/components/schemas/RunSummary"
        - type: object
          required: [conversation_ids, documents]
          properties:
            conversation_ids:
              type: array
              items:
                type: string
            documents:
              type: array
              items:
                $ref: "#/components/schemas/RunDocument"
    RunsList:
      type: object
      additionalProperties: false
      required: [runs, total, offset, limit]
      properties:
        runs:
          type: array
          items:
            $ref: "#/components/schemas/RunSummary"
        total:
          type: integer
          minimum: 0
        offset:
          type: integer
          minimum: 0
        limit:
          type: integer
          minimum: 1
    RunsListEnvelope:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          $ref: "#/components/schemas/RunsList"
    RunEnvelope:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          $ref: "#/components/schemas/Run"
    DocumentEnvelope:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          $ref: "#/components/schemas/Document"
    DeleteDocumentEnvelope:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          type: object
          additionalProperties: false
          required: [id, deleted]
          properties:
            id:
              type: string
              format: uuid
            deleted:
              type: boolean
              const: true
    Connection:
      type: object
      additionalProperties: false
      required: [id, type]
      properties:
        id:
          type: string
        type:
          type: string
    ConnectionEntity:
      type: object
      required: [identifier, label]
      properties:
        identifier:
          type: string
        label:
          type: string
      additionalProperties: true
    FlexibleRecord:
      type: object
      description: Shape depends on the selected data source.
      additionalProperties: true
    Database:
      type: object
      additionalProperties: false
      required: [id, name, team_id]
      properties:
        id:
          type: string
        name:
          type: string
        team_id:
          type: string
    DatabasesEnvelope:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Database"
    Table:
      type: object
      additionalProperties: false
      required: [id, name]
      properties:
        id:
          type: string
        name:
          type: string
    TablesEnvelope:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/Table"
    DatabaseColumn:
      type: object
      additionalProperties: false
      required: [table_name, column_name, column_type]
      properties:
        table_name:
          type: string
        column_name:
          type: string
        column_type:
          type: string
        label:
          type: string
        comment:
          type: string
        starred:
          type: boolean
    DatabaseSchemaEnvelope:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/DatabaseColumn"
    RecordsEnvelope:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/FlexibleRecord"
    QueryRequest:
      type: object
      additionalProperties: false
      required: [database_id, query]
      properties:
        database_id:
          type: string
        query:
          type: string
    SearchWebEnvelope:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          type: object
          additionalProperties: false
          required: [summary, citations]
          properties:
            summary:
              type: string
            citations:
              type: array
              items:
                type: object
                additionalProperties: false
                required: [url]
                properties:
                  url:
                    type: string
                    format: uri
    ThreadEnvelope:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          type: object
          additionalProperties: false
          required: [messages]
          properties:
            messages:
              type: array
              description: Stored Fluent chat messages.
              items: {}
    SnapshotUploadRequest:
      type: object
      additionalProperties: false
      required: [conversationId]
      properties:
        conversationId:
          type: string
        sizeBytes:
          type: number
          minimum: 0
    SnapshotUploadEnvelope:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          type: object
          additionalProperties: false
          required: [uploadUrl, s3Key]
          properties:
            uploadUrl:
              type: string
              format: uri
            s3Key:
              type: string
    SnapshotDownloadEnvelope:
      type: object
      additionalProperties: false
      required: [data]
      properties:
        data:
          type: object
          additionalProperties: false
          required: [downloadUrl]
          properties:
            downloadUrl:
              type: [string, "null"]
              format: uri
    McpRequest:
      type: object
      required: [jsonrpc, method]
      properties:
        jsonrpc:
          type: string
          const: "2.0"
        id:
          type: [string, integer, "null"]
        method:
          type: string
        params:
          type: object
          additionalProperties: true
      additionalProperties: true
    McpResponse:
      type: object
      required: [jsonrpc]
      properties:
        jsonrpc:
          type: string
          const: "2.0"
        id:
          type: [string, integer, "null"]
        result: {}
        error:
          type: object
          required: [code, message]
          properties:
            code:
              type: integer
            message:
              type: string
            data: {}
      additionalProperties: true
