openapi: 3.1.0
info:
  title: ANTARES API
  version: "2026-09-24"
  summary: Prepaid access to the models ANTARES serves, for server-side applications.
  description: |
    The ANTARES developer API. Every call is prepaid from the account's API
    balance (separate from any chat subscription): the request's maximum
    charge is held first, and the measured usage is charged when the model
    has answered. Amounts are integer micro-euros (millionths of a euro) sent
    as decimal strings.

    Authentication is an API key from the console, in `x-api-key` or in
    `Authorization: Bearer`. Keys are for servers: a request that carries an
    `Origin` header (a browser) is refused with `server_side_only`.

    The `antares-version` header selects the API version; without it the
    newest version answers. An unknown version is refused, never guessed.

    This document is checked against the server's request schemas by
    `tests/developer-api/openapi.test.ts`.
  contact:
    name: ANTARES
    url: https://emtantares.com/docs/api
servers:
  - url: https://emtantares.com/api/developer
    description: The API on the ANTARES web host.
security:
  - apiKey: []
  - bearer: []
tags:
  - name: Messages
  - name: Models
  - name: Requests
  - name: Compatibility
  - name: Files
  - name: Batches
  - name: Admin
  - name: Skills
  - name: Agents
paths:
  /v1/messages:
    post:
      operationId: createMessage
      tags: [Messages]
      summary: Create a message
      description: |
        Generates the assistant's next turn for a conversation of user and
        assistant turns made of content blocks (text, images, tool calls and
        tool results). With `stream: true` the answer arrives as server-sent
        events (`message_start`, `content_block_start`, `content_block_delta`,
        `content_block_stop`, `message_delta`, `message_stop`, plus `ping`
        every 15 seconds); an error after the stream started is sent as one
        final `error` event carrying the error object.

        Needs the `messages:write` scope. Paid: the maximum charge
        (`max_tokens` included) is held before the model runs.
      parameters:
        - $ref: "#/components/parameters/Version"
        - $ref: "#/components/parameters/IdempotencyKey"
        - $ref: "#/components/parameters/Funding"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: "#/components/schemas/MessageCreateRequest"
                - $ref: "#/components/schemas/PlatformMessageCreateRequest"
            examples:
              text:
                summary: A single question
                value:
                  model: model-id-from-v1-models
                  max_tokens: 256
                  system: Answer in one paragraph.
                  messages:
                    - role: user
                      content: What is a prepaid API balance?
              tools:
                summary: A tool the model may call
                value:
                  model: model-id-from-v1-models
                  max_tokens: 512
                  tools:
                    - name: get_weather
                      description: Current weather for a city.
                      input_schema:
                        type: object
                        properties:
                          city: { type: string }
                        required: [city]
                  tool_choice: { type: auto }
                  messages:
                    - role: user
                      content: What is the weather in Rome?
              tool_result:
                summary: Answering a tool call
                value:
                  model: model-id-from-v1-models
                  max_tokens: 512
                  tools:
                    - name: get_weather
                      input_schema:
                        type: object
                        properties:
                          city: { type: string }
                  messages:
                    - role: user
                      content: What is the weather in Rome?
                    - role: assistant
                      content:
                        - type: tool_use
                          id: call_1
                          name: get_weather
                          input: { city: Rome }
                    - role: user
                      content:
                        - type: tool_result
                          tool_use_id: call_1
                          content: 21 °C and sunny
              stream:
                summary: A streamed answer
                value:
                  model: model-id-from-v1-models
                  max_tokens: 256
                  stream: true
                  messages:
                    - role: user
                      content: Tell me a short story.
      responses:
        "200":
          description: The message, or the event stream when `stream` is true.
          headers:
            request-id: { $ref: "#/components/headers/RequestId" }
            idempotency-key: { $ref: "#/components/headers/IdempotencyKey" }
            antares-idempotency-key-generated: { $ref: "#/components/headers/IdempotencyKeyGenerated" }
            antares-ratelimit-tier: { $ref: "#/components/headers/RateLimitTier" }
            antares-ratelimit-requests-limit: { $ref: "#/components/headers/RateLimitLimit" }
            antares-ratelimit-requests-remaining: { $ref: "#/components/headers/RateLimitRemaining" }
            antares-ratelimit-requests-reset: { $ref: "#/components/headers/RateLimitReset" }
            antares-ratelimit-input-tokens-limit: { $ref: "#/components/headers/RateLimitLimit" }
            antares-ratelimit-input-tokens-remaining: { $ref: "#/components/headers/RateLimitRemaining" }
            antares-ratelimit-input-tokens-reset: { $ref: "#/components/headers/RateLimitReset" }
            antares-ratelimit-output-tokens-limit: { $ref: "#/components/headers/RateLimitLimit" }
            antares-ratelimit-output-tokens-remaining: { $ref: "#/components/headers/RateLimitRemaining" }
            antares-ratelimit-output-tokens-reset: { $ref: "#/components/headers/RateLimitReset" }
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Message"
            text/event-stream:
              schema:
                type: string
                description: Server-sent events; each `data:` line is one MessageStreamEvent as JSON.
              x-event-schema:
                $ref: "#/components/schemas/MessageStreamEvent"
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "402": { $ref: "#/components/responses/Billing" }
        "403": { $ref: "#/components/responses/Permission" }
        "404": { $ref: "#/components/responses/NotFound" }
        "409": { $ref: "#/components/responses/Conflict" }
        "413": { $ref: "#/components/responses/TooLarge" }
        "422": { $ref: "#/components/responses/Unprocessable" }
        "429": { $ref: "#/components/responses/RateLimited" }
        "502": { $ref: "#/components/responses/ServerError" }
        "503": { $ref: "#/components/responses/ServerError" }
  /v1/messages/count_tokens:
    post:
      operationId: countMessageTokens
      tags: [Messages]
      summary: Count a prompt's tokens
      description: |
        A free estimate of the prompt's input tokens (nothing is generated or
        charged), plus `reservation_input_tokens`, the conservative bound a
        `/v1/messages` call with the same prompt is held and rate-limited with.
        The header `antares-token-count-source: estimate` says how it was
        counted. Needs the `messages:write` scope.
      parameters:
        - $ref: "#/components/parameters/Version"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CountTokensRequest"
            examples:
              text:
                value:
                  model: model-id-from-v1-models
                  messages:
                    - role: user
                      content: How many tokens is this?
      responses:
        "200":
          description: The count.
          headers:
            request-id: { $ref: "#/components/headers/RequestId" }
            antares-token-count-source:
              description: How the count was made.
              schema: { type: string, enum: [estimate] }
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CountTokensResponse"
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "403": { $ref: "#/components/responses/Permission" }
        "404": { $ref: "#/components/responses/NotFound" }
        "413": { $ref: "#/components/responses/TooLarge" }
        "429": { $ref: "#/components/responses/RateLimited" }
        "503": { $ref: "#/components/responses/ServerError" }
  /v1/models:
    get:
      operationId: listModels
      tags: [Models]
      summary: List models
      description: |
        The models this API serves right now, ordered by id, with their
        prices. Any active key may list them. Page with `limit` and either
        `after_id` (next page) or `before_id` (previous page).
      parameters:
        - $ref: "#/components/parameters/Version"
        - name: limit
          in: query
          schema: { type: integer, minimum: 1, maximum: 100, default: 20 }
        - name: after_id
          in: query
          description: Return models after this id. Not together with before_id.
          schema: { $ref: "#/components/schemas/ModelId" }
        - name: before_id
          in: query
          description: Return models before this id. Not together with after_id.
          schema: { $ref: "#/components/schemas/ModelId" }
      responses:
        "200":
          description: One page of models.
          headers:
            request-id: { $ref: "#/components/headers/RequestId" }
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ModelList"
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "429": { $ref: "#/components/responses/RateLimited" }
        "503": { $ref: "#/components/responses/ServerError" }
  /v1/models/{model_id}:
    get:
      operationId: getModel
      tags: [Models]
      summary: Get a model
      parameters:
        - $ref: "#/components/parameters/Version"
        - name: model_id
          in: path
          required: true
          description: The model id, URL-encoded.
          schema: { $ref: "#/components/schemas/ModelId" }
      responses:
        "200":
          description: The model.
          headers:
            request-id: { $ref: "#/components/headers/RequestId" }
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Model"
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
        "429": { $ref: "#/components/responses/RateLimited" }
        "503": { $ref: "#/components/responses/ServerError" }
  /v1/requests/{idempotency_key}:
    get:
      operationId: getRequestStatus
      tags: [Requests]
      summary: Get the outcome of a paid request
      description: |
        What happened to a paid request made with this key: its status and
        charge, never its content. Only the key that made the request can read
        it. Use it after a timeout or a lost connection instead of sending the
        request again.
      parameters:
        - $ref: "#/components/parameters/Version"
        - name: idempotency_key
          in: path
          required: true
          schema: { $ref: "#/components/schemas/IdempotencyKey" }
      responses:
        "200":
          description: The recorded outcome.
          headers:
            request-id: { $ref: "#/components/headers/RequestId" }
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/RequestStatus"
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
        "429": { $ref: "#/components/responses/RateLimited" }
  /v1/chat/completions:
    post:
      operationId: createChatCompletion
      tags: [Compatibility]
      summary: Create a chat completion (compatibility)
      description: |
        The Chat Completions request shape many existing SDKs and tools send,
        on the same prepaid path as `/v1/messages`. Only what ANTARES can
        honour is accepted: one choice, inline `data:` images only, temperature
        up to 1, `store` false. Without `max_tokens` the hold uses up to 4,096
        output tokens (or the model's own limit if lower). Streams are
        data-only server-sent events ending with `data: [DONE]`. Errors on this
        route use the `{ "error": { "message", "type", "param", "code" } }`
        body. Needs the `messages:write` scope.
      parameters:
        - $ref: "#/components/parameters/Version"
        - $ref: "#/components/parameters/IdempotencyKey"
        - $ref: "#/components/parameters/Funding"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ChatCompletionRequest"
            examples:
              text:
                value:
                  model: model-id-from-v1-models
                  max_tokens: 256
                  messages:
                    - role: system
                      content: Answer in one paragraph.
                    - role: user
                      content: What is a prepaid API balance?
      responses:
        "200":
          description: The completion, or the event stream when `stream` is true.
          headers:
            request-id: { $ref: "#/components/headers/RequestId" }
            idempotency-key: { $ref: "#/components/headers/IdempotencyKey" }
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChatCompletion"
            text/event-stream:
              schema:
                type: string
                description: "Data-only server-sent events: chat.completion.chunk objects, then [DONE]."
        "400": { $ref: "#/components/responses/ChatError" }
        "401": { $ref: "#/components/responses/ChatError" }
        "402": { $ref: "#/components/responses/ChatError" }
        "403": { $ref: "#/components/responses/ChatError" }
        "404": { $ref: "#/components/responses/ChatError" }
        "409": { $ref: "#/components/responses/ChatError" }
        "413": { $ref: "#/components/responses/ChatError" }
        "422": { $ref: "#/components/responses/ChatError" }
        "429": { $ref: "#/components/responses/ChatError" }
        "502": { $ref: "#/components/responses/ChatError" }
        "503": { $ref: "#/components/responses/ChatError" }
  /v1/responses:
    post:
      operationId: createResponse
      tags: [Compatibility]
      summary: Create a text response (first API version)
      description: |
        The first, text-only endpoint of this API, kept for existing callers.
        New integrations use `/v1/messages`. Needs the `responses:write` scope.
      parameters:
        - $ref: "#/components/parameters/Version"
        - $ref: "#/components/parameters/IdempotencyKey"
        - $ref: "#/components/parameters/Funding"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ResponseCreateRequest"
            examples:
              text:
                value:
                  model: model-id-from-v1-models
                  input: What is a prepaid API balance?
                  max_output_tokens: 256
      responses:
        "200":
          description: The response.
          headers:
            request-id: { $ref: "#/components/headers/RequestId" }
            idempotency-key: { $ref: "#/components/headers/IdempotencyKey" }
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TextResponse"
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "402": { $ref: "#/components/responses/Billing" }
        "403": { $ref: "#/components/responses/Permission" }
        "404": { $ref: "#/components/responses/NotFound" }
        "409": { $ref: "#/components/responses/Conflict" }
        "413": { $ref: "#/components/responses/TooLarge" }
        "422": { $ref: "#/components/responses/Unprocessable" }
        "429": { $ref: "#/components/responses/RateLimited" }
        "502": { $ref: "#/components/responses/ServerError" }
        "503": { $ref: "#/components/responses/ServerError" }
  /v1/files:
    post:
      operationId: uploadFile
      tags: [Files]
      summary: Upload a file
      description: |
        Developer platform (the platform must be enabled on the installation; otherwise every route below answers 404
        NOT_ENABLED). One `file` part in multipart/form-data, at most 32 MiB. The stored type is read from the bytes
        (PDF, plain text, Markdown, CSV, JSON, DOCX, XLSX, PPTX, JPEG, PNG, GIF, WebP). A project holds at most 500 files
        and 512 MiB. Free. Needs `messages:write`.
      parameters:
        - $ref: "#/components/parameters/Version"
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required: [file]
              properties:
                file: { type: string, format: binary }
      responses:
        "200":
          description: The stored file.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/File" }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
        "409": { $ref: "#/components/responses/Conflict" }
        "413": { $ref: "#/components/responses/TooLarge" }
    get:
      operationId: listFiles
      tags: [Files]
      summary: List files
      description: The project's files, newest first.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: limit, in: query, required: false, schema: { type: integer, minimum: 1, maximum: 1000, default: 20 } }
        - { name: after_id, in: query, required: false, schema: { type: string } }
        - { name: before_id, in: query, required: false, schema: { type: string } }
      responses:
        "200":
          description: One page of files.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/FilePage" }
        "401": { $ref: "#/components/responses/Authentication" }
  /v1/files/{file_id}:
    get:
      operationId: getFile
      tags: [Files]
      summary: Get a file's metadata
      parameters:
        - $ref: "#/components/parameters/Version"
        - $ref: "#/components/parameters/FileId"
      responses:
        "200":
          description: The file.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/File" }
        "404": { $ref: "#/components/responses/NotFound" }
    delete:
      operationId: deleteFile
      tags: [Files]
      summary: Delete a file
      description: The file and its bytes are deleted at once. Needs `messages:write`.
      parameters:
        - $ref: "#/components/parameters/Version"
        - $ref: "#/components/parameters/FileId"
      responses:
        "200":
          description: Deleted.
          content:
            application/json:
              schema:
                type: object
                required: [id, type]
                properties: { id: { type: string }, type: { const: file_deleted } }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/files/{file_id}/content:
    get:
      operationId: downloadFile
      tags: [Files]
      summary: Download a file
      parameters:
        - $ref: "#/components/parameters/Version"
        - $ref: "#/components/parameters/FileId"
      responses:
        "200":
          description: The stored bytes, as an attachment.
          content:
            application/octet-stream:
              schema: { type: string, format: binary }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/messages/batches:
    post:
      operationId: createMessageBatch
      tags: [Batches]
      summary: Create a message batch
      description: |
        Up to 1,000 /v1/messages requests, checked now and run in the background within 24 hours. Each request is an
        ordinary paid call, recorded under the Idempotency-Key `batch_<batch hex>_<position>` (so its outcome can also be
        read at /v1/requests/{idempotency_key}) and charged like the same call made directly: there is no batch price.
        `antares-funding` applies to every request. Results are kept 29 days after the batch ends. Needs `messages:write`.
      parameters:
        - $ref: "#/components/parameters/Version"
        - $ref: "#/components/parameters/Funding"
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/MessageBatchCreateRequest" }
            examples:
              two:
                summary: Two questions
                value:
                  requests:
                    - custom_id: first
                      params: { model: model-id-from-v1-models, max_tokens: 128, messages: [{ role: user, content: Name a prime number. }] }
                    - custom_id: second
                      params: { model: model-id-from-v1-models, max_tokens: 128, messages: [{ role: user, content: Name a planet. }] }
      responses:
        "200":
          description: The batch, in progress.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/MessageBatch" }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "429": { $ref: "#/components/responses/RateLimited" }
    get:
      operationId: listMessageBatches
      tags: [Batches]
      summary: List message batches
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: limit, in: query, required: false, schema: { type: integer, minimum: 1, maximum: 100, default: 20 } }
        - { name: after_id, in: query, required: false, schema: { type: string } }
      responses:
        "200":
          description: One page of batches, newest first.
          content:
            application/json:
              schema:
                type: object
                required: [data, has_more, first_id, last_id]
                properties:
                  data: { type: array, items: { $ref: "#/components/schemas/MessageBatch" } }
                  has_more: { type: boolean }
                  first_id: { type: [string, "null"] }
                  last_id: { type: [string, "null"] }
  /v1/messages/batches/{batch_id}:
    get:
      operationId: getMessageBatch
      tags: [Batches]
      summary: Get a message batch
      parameters:
        - $ref: "#/components/parameters/Version"
        - $ref: "#/components/parameters/BatchId"
      responses:
        "200":
          description: The batch with its request counts.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/MessageBatch" }
        "404": { $ref: "#/components/responses/NotFound" }
    delete:
      operationId: deleteMessageBatch
      tags: [Batches]
      summary: Delete an ended message batch
      parameters:
        - $ref: "#/components/parameters/Version"
        - $ref: "#/components/parameters/BatchId"
      responses:
        "200":
          description: Deleted with its results.
          content:
            application/json:
              schema:
                type: object
                required: [id, type]
                properties: { id: { type: string }, type: { const: message_batch_deleted } }
        "404": { $ref: "#/components/responses/NotFound" }
        "409": { $ref: "#/components/responses/Conflict" }
  /v1/messages/batches/{batch_id}/cancel:
    post:
      operationId: cancelMessageBatch
      tags: [Batches]
      summary: Cancel a message batch
      description: Requests not yet started are canceled at once; a request already running finishes and keeps its result.
      parameters:
        - $ref: "#/components/parameters/Version"
        - $ref: "#/components/parameters/BatchId"
      responses:
        "200":
          description: The batch, canceling or ended.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/MessageBatch" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/messages/batches/{batch_id}/results:
    get:
      operationId: getMessageBatchResults
      tags: [Batches]
      summary: Get a message batch's results
      description: One JSON object per line, in request order, once the batch has ended.
      parameters:
        - $ref: "#/components/parameters/Version"
        - $ref: "#/components/parameters/BatchId"
      responses:
        "200":
          description: JSON Lines of MessageBatchResult.
          content:
            application/x-jsonlines:
              schema: { $ref: "#/components/schemas/MessageBatchResult" }
        "404": { $ref: "#/components/responses/NotFound" }
        "409": { $ref: "#/components/responses/Conflict" }
  /v1/organizations/me:
    get:
      operationId: getOrganization
      tags: [Admin]
      summary: The organization of the admin key
      description: |
        Admin API. Every /v1/organizations route needs an admin key (ant_admin_v1_…, created in the console) in
        `x-api-key`; an API key is refused with admin_key_required, and an admin key can never call a model.
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
      responses:
        "200":
          description: The organization.
          content:
            application/json:
              schema:
                type: object
                required: [id, type, name]
                properties: { id: { type: string }, type: { const: organization }, name: { type: string } }
        "401": { $ref: "#/components/responses/Authentication" }
  /v1/organizations/workspaces:
    get:
      operationId: listWorkspaces
      tags: [Admin]
      summary: List workspaces
      description: The account's API projects, which the Admin API calls workspaces.
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: limit, in: query, required: false, schema: { type: integer, minimum: 1, maximum: 100, default: 20 } }
        - { name: after_id, in: query, required: false, schema: { type: string } }
        - { name: include_archived, in: query, required: false, schema: { type: boolean, default: false } }
      responses:
        "200":
          description: One page of workspaces.
          content:
            application/json:
              schema:
                type: object
                required: [data, has_more]
                properties:
                  data: { type: array, items: { $ref: "#/components/schemas/Workspace" } }
                  has_more: { type: boolean }
                  first_id: { type: [string, "null"] }
                  last_id: { type: [string, "null"] }
    post:
      operationId: createWorkspace
      tags: [Admin]
      summary: Create a workspace
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/WorkspaceCreateRequest" }
            examples:
              basic:
                summary: A workspace with a 25 EUR spending cap
                value: { name: Production, spending_cap_micros: "25000000" }
      responses:
        "200":
          description: The new workspace.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Workspace" }
        "409": { $ref: "#/components/responses/Conflict" }
  /v1/organizations/workspaces/{workspace_id}:
    get:
      operationId: getWorkspace
      tags: [Admin]
      summary: Get a workspace
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: The workspace.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Workspace" }
        "404": { $ref: "#/components/responses/NotFound" }
    post:
      operationId: updateWorkspace
      tags: [Admin]
      summary: Rename a workspace
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/WorkspaceUpdateRequest" }
            examples:
              rename:
                summary: A new name
                value: { name: Staging }
      responses:
        "200":
          description: The workspace.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Workspace" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/organizations/workspaces/{workspace_id}/archive:
    post:
      operationId: archiveWorkspace
      tags: [Admin]
      summary: Archive a workspace
      description: Archives the workspace and revokes every one of its API keys, permanently.
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: The archived workspace.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/Workspace" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/organizations/api_keys:
    get:
      operationId: listApiKeys
      tags: [Admin]
      summary: List API keys
      description: Every API key of the organization, never a secret.
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: limit, in: query, required: false, schema: { type: integer, minimum: 1, maximum: 100, default: 20 } }
        - { name: workspace_id, in: query, required: false, schema: { type: string } }
        - { name: status, in: query, required: false, schema: { type: string, enum: [active, inactive, expired] } }
      responses:
        "200":
          description: One page of keys, newest first.
          content:
            application/json:
              schema:
                type: object
                required: [data, has_more]
                properties:
                  data: { type: array, items: { $ref: "#/components/schemas/ApiKey" } }
                  has_more: { type: boolean }
                  first_id: { type: [string, "null"] }
                  last_id: { type: [string, "null"] }
  /v1/organizations/api_keys/{api_key_id}:
    get:
      operationId: getApiKey
      tags: [Admin]
      summary: Get an API key
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
        - $ref: "#/components/parameters/ApiKeyId"
      responses:
        "200":
          description: The key.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/ApiKey" }
        "404": { $ref: "#/components/responses/NotFound" }
    post:
      operationId: updateApiKey
      tags: [Admin]
      summary: Rename or deactivate an API key
      description: "`status: inactive` revokes the key for good."
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
        - $ref: "#/components/parameters/ApiKeyId"
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/ApiKeyUpdateRequest" }
            examples:
              deactivate:
                summary: Revoke the key
                value: { status: inactive }
      responses:
        "200":
          description: The key.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/ApiKey" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/organizations/usage_report/messages:
    get:
      operationId: getMessagesUsageReport
      tags: [Admin]
      summary: Usage report
      description: Requests and tokens per UTC day (or hour), optionally by model, workspace or API key. Counts only.
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: starting_at, in: query, required: true, schema: { type: string, format: date-time } }
        - { name: ending_at, in: query, required: false, schema: { type: string, format: date-time } }
        - { name: bucket_width, in: query, required: false, schema: { type: string, enum: [1d, 1h], default: 1d } }
        - { name: "group_by[]", in: query, required: false, schema: { type: string, enum: [model, workspace_id, api_key_id] } }
        - { name: "workspace_ids[]", in: query, required: false, schema: { type: string } }
        - { name: funding, in: query, required: false, schema: { type: string, enum: [live, test], default: live } }
      responses:
        "200":
          description: One bucket per period that had requests.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/UsageReport" }
        "400": { $ref: "#/components/responses/InvalidRequest" }
  /v1/organizations/cost_report:
    get:
      operationId: getCostReport
      tags: [Admin]
      summary: Cost report
      description: The charges already recorded for settled requests, summed per UTC day (or hour), in EUR micros, and what is still held.
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: starting_at, in: query, required: true, schema: { type: string, format: date-time } }
        - { name: ending_at, in: query, required: false, schema: { type: string, format: date-time } }
        - { name: bucket_width, in: query, required: false, schema: { type: string, enum: [1d, 1h], default: 1d } }
        - { name: "group_by[]", in: query, required: false, schema: { type: string, enum: [model, workspace_id] } }
        - { name: "workspace_ids[]", in: query, required: false, schema: { type: string } }
        - { name: funding, in: query, required: false, schema: { type: string, enum: [live, test], default: live } }
      responses:
        "200":
          description: One bucket per period that had requests.
          content:
            application/json:
              schema: { $ref: "#/components/schemas/CostReport" }
        "400": { $ref: "#/components/responses/InvalidRequest" }
  /v1/skills:
    post:
      operationId: createSkill
      tags: [Skills]
      summary: Create a skill
      description: Developer platform (S-174). A SKILL.md (frontmatter with name and description, then the instructions) and optional text files. Free. Needs `messages:write`.
      parameters:
        - $ref: "#/components/parameters/Version"
      requestBody:
        required: true
        content:
          application/json:
            schema: { type: object }
            examples:
              basic:
                value: {"skill_md": "---\nname: release-notes\ndescription: Writes release notes in the house style.\n---\nWrite release notes as a short list, newest change first.", "files": [{"path": "examples/sample.md", "content": "- Fixed the export of large files."}]}
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
    get:
      operationId: listSkills
      tags: [Skills]
      summary: List skills
      description: The project's skills, newest first.
      parameters:
        - $ref: "#/components/parameters/Version"
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/skills/{skill_id}:
    get:
      operationId: getSkill
      tags: [Skills]
      summary: Get a skill
      description: One skill.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: skill_id, in: path, required: true, schema: { type: string } }
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
    delete:
      operationId: deleteSkill
      tags: [Skills]
      summary: Delete a skill
      description: Deletes the skill and every version.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: skill_id, in: path, required: true, schema: { type: string } }
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/skills/{skill_id}/versions:
    post:
      operationId: createSkillVersion
      tags: [Skills]
      summary: Create a skill version
      description: A new immutable version; the SKILL.md must keep the skill's name.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: skill_id, in: path, required: true, schema: { type: string } }
      requestBody:
        required: true
        content:
          application/json:
            schema: { type: object }
            examples:
              basic:
                value: {"skill_md": "---\nname: release-notes\ndescription: Writes release notes in the house style.\n---\nWrite release notes as a short list, newest change first."}
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
    get:
      operationId: listSkillVersions
      tags: [Skills]
      summary: List skill versions
      description: The skill's versions, newest first.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: skill_id, in: path, required: true, schema: { type: string } }
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/skills/{skill_id}/versions/{version}:
    get:
      operationId: getSkillVersion
      tags: [Skills]
      summary: Get a skill version
      description: One version with its instructions and file list.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: skill_id, in: path, required: true, schema: { type: string } }
        - { name: version, in: path, required: true, schema: { type: string } }
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/agents:
    post:
      operationId: createAgent
      tags: [Agents]
      summary: Create an agent
      description: "Hosted agents (S-178): a saved configuration (model, system prompt, tools, skills, output limit). Free."
      parameters:
        - $ref: "#/components/parameters/Version"
      requestBody:
        required: true
        content:
          application/json:
            schema: { type: object }
            examples:
              basic:
                value: {"name": "Support triage", "model": "antares-auto", "system": "Sort support requests by urgency.", "max_tokens": 1024}
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
    get:
      operationId: listAgents
      tags: [Agents]
      summary: List agents
      description: The project's agents.
      parameters:
        - $ref: "#/components/parameters/Version"
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/agents/{agent_id}:
    get:
      operationId: getAgent
      tags: [Agents]
      summary: Get an agent
      description: One agent.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: agent_id, in: path, required: true, schema: { type: string } }
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
    post:
      operationId: updateAgent
      tags: [Agents]
      summary: Update an agent
      description: Changes the given fields; sessions use the agent as it is at each turn.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: agent_id, in: path, required: true, schema: { type: string } }
      requestBody:
        required: true
        content:
          application/json:
            schema: { type: object }
            examples:
              basic:
                value: {"system": "Sort support requests by urgency and product."}
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
    delete:
      operationId: archiveAgent
      tags: [Agents]
      summary: Archive an agent
      description: The agent can no longer start sessions or turns.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: agent_id, in: path, required: true, schema: { type: string } }
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/sessions:
    post:
      operationId: createSession
      tags: [Agents]
      summary: Create a session
      description: A conversation with an agent, optionally with a memory store.
      parameters:
        - $ref: "#/components/parameters/Version"
      requestBody:
        required: true
        content:
          application/json:
            schema: { type: object }
            examples:
              basic:
                value: {"agent_id": "agent_0123456789abcdef0123456789abcdef", "title": "Ticket 42"}
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
    get:
      operationId: listSessions
      tags: [Agents]
      summary: List sessions
      description: The project's sessions, most recent first.
      parameters:
        - $ref: "#/components/parameters/Version"
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/sessions/{session_id}:
    get:
      operationId: getSession
      tags: [Agents]
      summary: Get a session
      description: One session.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: session_id, in: path, required: true, schema: { type: string } }
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
    delete:
      operationId: deleteSession
      tags: [Agents]
      summary: Delete a session
      description: Deletes the session and its events.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: session_id, in: path, required: true, schema: { type: string } }
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/sessions/{session_id}/events:
    post:
      operationId: createSessionEvent
      tags: [Agents]
      summary: Send a turn
      description: The developer's message (or the results of the agent's client tool calls). The turn is one /v1/messages request built from the agent and the session, charged as such under the Idempotency-Key; a retry with the same key returns the recorded turn.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: session_id, in: path, required: true, schema: { type: string } }
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        required: true
        content:
          application/json:
            schema: { type: object }
            examples:
              basic:
                value: {"content": "A customer cannot log in since this morning."}
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
    get:
      operationId: listSessionEvents
      tags: [Agents]
      summary: List session events
      description: The session's turns, oldest first.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: session_id, in: path, required: true, schema: { type: string } }
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/sessions/{session_id}/grades:
    post:
      operationId: createSessionGrade
      tags: [Agents]
      summary: Grade a session
      description: "Outcome grading (S-178): a grader model scores the session transcript against a rubric (0 to 10 per criterion, weighted overall) in one /v1/messages request, charged as such under the Idempotency-Key; a retry with the same key returns the recorded grade."
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: session_id, in: path, required: true, schema: { type: string } }
        - $ref: "#/components/parameters/IdempotencyKey"
      requestBody:
        required: true
        content:
          application/json:
            schema: { type: object }
            examples:
              basic:
                value: {"model": "antares-grader", "rubric": [{"criterion": "The customer's problem was solved", "weight": 3}, {"criterion": "The answer was polite"}]}
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
    get:
      operationId: listSessionGrades
      tags: [Agents]
      summary: List session grades
      description: The session's grades, newest first.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: session_id, in: path, required: true, schema: { type: string } }
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/agents/{agent_id}/deployments:
    post:
      operationId: createAgentDeployment
      tags: [Agents]
      summary: Deploy an agent on a schedule
      description: "Scheduled deployment (S-178): at each daily or weekly time (in a named time zone) a new session runs content as its first turn, as the key that created the deployment, charged like any turn."
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: agent_id, in: path, required: true, schema: { type: string } }
      requestBody:
        required: true
        content:
          application/json:
            schema: { type: object }
            examples:
              basic:
                value: {"schedule": {"frequency": "weekly", "time": "08:30", "timeZone": "Europe/Rome", "weekdays": [1, 2, 3, 4, 5]}, "content": "Summarise the open support tickets."}
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
    get:
      operationId: listAgentDeployments
      tags: [Agents]
      summary: List an agent's deployments
      description: The agent's scheduled deployments, with their next run and last session.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: agent_id, in: path, required: true, schema: { type: string } }
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/agents/{agent_id}/deployments/{deployment_id}:
    delete:
      operationId: deleteAgentDeployment
      tags: [Agents]
      summary: Delete a deployment
      description: Stops and removes a scheduled deployment; its past sessions stay.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: agent_id, in: path, required: true, schema: { type: string } }
        - { name: deployment_id, in: path, required: true, schema: { type: string } }
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/memory_stores:
    post:
      operationId: createMemoryStore
      tags: [Agents]
      summary: Create a memory store
      description: A key-value store (at most 500 entries) that sessions read and write with the memory tool. Free.
      parameters:
        - $ref: "#/components/parameters/Version"
      requestBody:
        required: true
        content:
          application/json:
            schema: { type: object }
            examples:
              basic:
                value: {"name": "Support facts"}
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
    get:
      operationId: listMemoryStores
      tags: [Agents]
      summary: List memory stores
      description: The project's memory stores.
      parameters:
        - $ref: "#/components/parameters/Version"
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/memory_stores/{memory_store_id}:
    delete:
      operationId: deleteMemoryStore
      tags: [Agents]
      summary: Delete a memory store
      description: Deletes the store and its entries.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: memory_store_id, in: path, required: true, schema: { type: string } }
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/memory_stores/{memory_store_id}/entries:
    get:
      operationId: listMemoryEntries
      tags: [Agents]
      summary: List memory entries
      description: Every entry, by key.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: memory_store_id, in: path, required: true, schema: { type: string } }
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
    put:
      operationId: putMemoryEntry
      tags: [Agents]
      summary: Write a memory entry
      description: Creates or replaces one entry.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: memory_store_id, in: path, required: true, schema: { type: string } }
      requestBody:
        required: true
        content:
          application/json:
            schema: { type: object }
            examples:
              basic:
                value: {"key": "escalation", "value": "Escalate outages to the on-call engineer."}
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
    delete:
      operationId: deleteMemoryEntry
      tags: [Agents]
      summary: Delete a memory entry
      description: Removes the entry named by `key`.
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: memory_store_id, in: path, required: true, schema: { type: string } }
        - { name: key, in: query, required: true, schema: { type: string } }
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/organizations/workspaces/{workspace_id}/otel_export:
    get:
      operationId: getOtelExport
      tags: [Admin]
      summary: Get the OpenTelemetry export
      description: S-181. Where the workspace's finished requests are sent as spans; headers are never returned.
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
    put:
      operationId: putOtelExport
      tags: [Admin]
      summary: Set the OpenTelemetry export
      description: "An OTLP/HTTP JSON endpoint (https, public) and optional headers (kept sealed). One span per finished request: model, tokens, status and the charge already recorded; never prompt or answer text."
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
        - $ref: "#/components/parameters/WorkspaceId"
      requestBody:
        required: true
        content:
          application/json:
            schema: { type: object }
            examples:
              basic:
                value: {"endpoint": "https://otel.example.com/v1/traces", "headers": {"x-collector-team": "api"}}
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
    delete:
      operationId: deleteOtelExport
      tags: [Admin]
      summary: Stop the OpenTelemetry export
      description: Deletes the setting.
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
        - $ref: "#/components/parameters/WorkspaceId"
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "401": { $ref: "#/components/responses/Authentication" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/organizations/webhooks:
    post:
      operationId: createWebhook
      tags: [Admin]
      summary: "Create a webhook"
      description: "S-180. An https address and the event types it receives (message_batch.ended, workspace.created, workspace.archived, api_key.deactivated, session.turn_completed, skill.version_created). The signing secret is returned once. Each delivery is signed: antares-webhook-signature t=<seconds>,v1=<HMAC-SHA256 of t.body>."
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
      requestBody:
        required: true
        content:
          application/json:
            schema: { type: object }
            examples:
              basic:
                value: {"url": "https://hooks.example.com/antares", "events": ["message_batch.ended", "api_key.deactivated"], "description": "Ops channel"}
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "404": { $ref: "#/components/responses/NotFound" }
    get:
      operationId: listWebhooks
      tags: [Admin]
      summary: "List webhooks"
      description: "The organization's webhooks, never a secret."
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/organizations/webhooks/{webhook_id}:
    get:
      operationId: getWebhook
      tags: [Admin]
      summary: "Get a webhook"
      description: "One webhook."
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: webhook_id, in: path, required: true, schema: { type: string } }
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "404": { $ref: "#/components/responses/NotFound" }
    post:
      operationId: updateWebhook
      tags: [Admin]
      summary: "Update a webhook"
      description: "Changes the address, the events, the description or turns it off."
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: webhook_id, in: path, required: true, schema: { type: string } }
      requestBody:
        required: true
        content:
          application/json:
            schema: { type: object }
            examples:
              basic:
                value: {"enabled": false}
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "404": { $ref: "#/components/responses/NotFound" }
    delete:
      operationId: deleteWebhook
      tags: [Admin]
      summary: "Delete a webhook"
      description: "Deletes the webhook and its delivery log."
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: webhook_id, in: path, required: true, schema: { type: string } }
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/organizations/webhooks/{webhook_id}/test:
    post:
      operationId: testWebhook
      tags: [Admin]
      summary: "Send a test event"
      description: "Delivers one signed webhook.test event at once and returns the receiver's status code."
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: webhook_id, in: path, required: true, schema: { type: string } }
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "404": { $ref: "#/components/responses/NotFound" }
  /v1/organizations/webhooks/{webhook_id}/deliveries:
    get:
      operationId: listWebhookDeliveries
      tags: [Admin]
      summary: "List deliveries"
      description: "The latest 50 deliveries with their status and attempts (kept 30 days)."
      security: [{ adminKey: [] }]
      parameters:
        - $ref: "#/components/parameters/Version"
        - { name: webhook_id, in: path, required: true, schema: { type: string } }
      responses:
        "200":
          description: The result.
          content:
            application/json:
              schema: { type: object }
        "400": { $ref: "#/components/responses/InvalidRequest" }
        "404": { $ref: "#/components/responses/NotFound" }
components:
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: An API key from the console (ant_sk_v1_...). Send it from servers only.
    bearer:
      type: http
      scheme: bearer
      description: The same API key as a bearer token. If both headers are sent they must carry the same key.
    adminKey:
      type: apiKey
      in: header
      name: x-api-key
      description: An admin key from the console (ant_admin_v1_...), for the /v1/organizations routes only.
  parameters:
    Version:
      name: antares-version
      in: header
      required: false
      description: The API version. Absent means the newest; an unknown value is refused with unsupported_version.
      schema:
        type: string
        enum: ["2026-09-24"]
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: false
      description: |
        The key this paid request is recorded under. A retry with the same key
        and the same body is never run twice (it receives 409
        request_already_recorded); the same key with a different body receives
        409 API_IDEMPOTENCY_CONFLICT. Without one the server issues a key and
        returns it in the idempotency-key response header.
      schema: { $ref: "#/components/schemas/IdempotencyKey" }
    FileId:
      name: file_id
      in: path
      required: true
      schema: { type: string, pattern: "^file_[0-9a-f]{32}$" }
    BatchId:
      name: batch_id
      in: path
      required: true
      schema: { type: string, pattern: "^msgbatch_[0-9a-f]{32}$" }
    WorkspaceId:
      name: workspace_id
      in: path
      required: true
      schema: { type: string, pattern: "^wrkspc_[0-9a-f]{32}$" }
    ApiKeyId:
      name: api_key_id
      in: path
      required: true
      schema: { type: string, pattern: "^apikey_[0-9a-f]{32}$" }
    Funding:
      name: antares-funding
      in: header
      required: false
      description: "`test` spends test credit (allowlisted test accounts only). Absent means paid credit."
      schema:
        type: string
        enum: [test]
  headers:
    RequestId:
      description: The id this request was logged under; quote it to support.
      schema: { type: string, format: uuid }
    IdempotencyKey:
      description: The key the request was recorded under (yours, or one the server issued).
      schema: { $ref: "#/components/schemas/IdempotencyKey" }
    IdempotencyKeyGenerated:
      description: "`true` when the server issued the idempotency key."
      schema: { type: string, enum: ["true"] }
    RateLimitTier:
      description: The account's usage tier (tier_0 ... tier_4).
      schema: { type: string }
    RateLimitLimit:
      description: The per-minute limit of this bucket for the key.
      schema: { type: string }
    RateLimitRemaining:
      description: What is left of it in the current minute.
      schema: { type: string }
    RateLimitReset:
      description: When the current minute ends (ISO 8601).
      schema: { type: string, format: date-time }
    RetryAfter:
      description: Seconds to wait before retrying.
      schema: { type: string }
  responses:
    InvalidRequest:
      description: The request is invalid (invalid_request_error).
      headers:
        request-id: { $ref: "#/components/headers/RequestId" }
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ErrorResponse" }
          example:
            type: error
            error: { type: invalid_request_error, code: invalid_request, message: The request contains an invalid or unknown field., request_id: 5f0c2c1e-8a47-4d3e-9d0e-2b6f1c9a7d11 }
            request_id: 5f0c2c1e-8a47-4d3e-9d0e-2b6f1c9a7d11
    Authentication:
      description: The key is missing, invalid, expired or revoked (authentication_error).
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ErrorResponse" }
    Billing:
      description: |
        The balance, the project's spending cap or its monthly limit does not
        cover the request's maximum charge (billing_error, for example
        API_INSUFFICIENT_FUNDS or API_PROJECT_CAP_REACHED).
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ErrorResponse" }
    Permission:
      description: The key lacks the scope, the request came from a browser, or the account is not eligible (permission_error).
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ErrorResponse" }
    NotFound:
      description: The model or request does not exist for this key (not_found_error).
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ErrorResponse" }
    Conflict:
      description: The Idempotency-Key was already used (request_already_recorded or API_IDEMPOTENCY_CONFLICT).
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ErrorResponse" }
    TooLarge:
      description: The body, an image or all images together exceed the limits (request_too_large).
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ErrorResponse" }
    Unprocessable:
      description: The content was refused by the safety review (content_blocked).
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ErrorResponse" }
    RateLimited:
      description: A per-minute limit of the key is spent (rate_limit_error). Wait as retry-after says.
      headers:
        retry-after: { $ref: "#/components/headers/RetryAfter" }
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ErrorResponse" }
    ServerError:
      description: |
        The service could not complete the request (api_error or
        overloaded_error). A request whose provider usage could not be
        confirmed is held for review (usage_not_verified); read its outcome at
        /v1/requests/{idempotency_key}.
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ErrorResponse" }
    ChatError:
      description: An error in the Chat Completions error shape.
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ChatErrorResponse" }
  schemas:
    ModelId:
      type: string
      pattern: "^[a-zA-Z0-9:._/-]{1,200}$"
    IdempotencyKey:
      type: string
      pattern: "^[a-zA-Z0-9._:-]{8,128}$"
    Micros:
      type: string
      pattern: "^[0-9]{1,20}$"
      description: An amount in micro-euros (millionths of a euro).
    ToolName:
      type: string
      pattern: "^[a-zA-Z0-9_-]{1,64}$"
    ToolId:
      type: string
      pattern: "^[a-zA-Z0-9_-]{1,128}$"
    TextBlock:
      type: object
      additionalProperties: false
      required: [type, text]
      properties:
        type: { const: text }
        text: { type: string, minLength: 1, maxLength: 400000 }
    ImageBlock:
      type: object
      additionalProperties: false
      required: [type, source]
      description: An inline image. At most 5 MB each, 20 per request and 24 MB together; the declared type must match the bytes. URLs are not fetched.
      properties:
        type: { const: image }
        source:
          type: object
          additionalProperties: false
          required: [type, media_type, data]
          properties:
            type: { const: base64 }
            media_type: { type: string, enum: [image/jpeg, image/png, image/gif, image/webp] }
            data: { type: string, contentEncoding: base64 }
    ToolUseBlock:
      type: object
      additionalProperties: false
      required: [type, id, name, input]
      properties:
        type: { const: tool_use }
        id: { $ref: "#/components/schemas/ToolId" }
        name: { $ref: "#/components/schemas/ToolName" }
        input: { type: object }
    ToolResultBlock:
      type: object
      additionalProperties: false
      required: [type, tool_use_id]
      description: The answer to a tool_use block of an earlier assistant turn.
      properties:
        type: { const: tool_result }
        tool_use_id: { $ref: "#/components/schemas/ToolId" }
        content:
          oneOf:
            - { type: string, maxLength: 400000 }
            - { type: array, maxItems: 20, items: { $ref: "#/components/schemas/TextBlock" } }
        is_error: { type: boolean }
    UserMessage:
      type: object
      additionalProperties: false
      required: [role, content]
      properties:
        role: { const: user }
        content:
          oneOf:
            - { type: string, minLength: 1, maxLength: 400000 }
            - type: array
              minItems: 1
              maxItems: 100
              items:
                oneOf:
                  - { $ref: "#/components/schemas/TextBlock" }
                  - { $ref: "#/components/schemas/ImageBlock" }
                  - { $ref: "#/components/schemas/ToolResultBlock" }
    AssistantMessage:
      type: object
      additionalProperties: false
      required: [role, content]
      properties:
        role: { const: assistant }
        content:
          oneOf:
            - { type: string, minLength: 1, maxLength: 400000 }
            - type: array
              minItems: 1
              maxItems: 100
              items:
                oneOf:
                  - { $ref: "#/components/schemas/TextBlock" }
                  - { $ref: "#/components/schemas/ToolUseBlock" }
    Tool:
      type: object
      additionalProperties: false
      required: [name, input_schema]
      properties:
        name: { $ref: "#/components/schemas/ToolName" }
        description: { type: string, maxLength: 4096 }
        input_schema:
          type: object
          description: A JSON Schema of an object (at most 64 KB).
          required: [type]
          properties:
            type: { const: object }
    ToolChoice:
      oneOf:
        - { type: object, additionalProperties: false, required: [type], properties: { type: { const: auto } } }
        - { type: object, additionalProperties: false, required: [type], properties: { type: { const: any } } }
        - { type: object, additionalProperties: false, required: [type], properties: { type: { const: none } } }
        - type: object
          additionalProperties: false
          required: [type, name]
          properties:
            type: { const: tool }
            name: { $ref: "#/components/schemas/ToolName" }
    System:
      oneOf:
        - { type: string, maxLength: 400000 }
        - { type: array, maxItems: 20, items: { $ref: "#/components/schemas/TextBlock" } }
    CountTokensRequest:
      type: object
      additionalProperties: false
      required: [model, messages]
      description: The first message is a user turn; tool names are unique; a tool_result answers an earlier tool_use.
      properties:
        model: { $ref: "#/components/schemas/ModelId" }
        system: { $ref: "#/components/schemas/System" }
        messages:
          type: array
          minItems: 1
          maxItems: 1000
          items:
            oneOf:
              - { $ref: "#/components/schemas/UserMessage" }
              - { $ref: "#/components/schemas/AssistantMessage" }
        tools: { type: array, maxItems: 64, items: { $ref: "#/components/schemas/Tool" } }
        tool_choice: { $ref: "#/components/schemas/ToolChoice" }
    MessageCreateRequest:
      type: object
      additionalProperties: false
      required: [model, messages, max_tokens]
      description: The first message is a user turn; tool names are unique; a tool_result answers an earlier tool_use.
      properties:
        model: { $ref: "#/components/schemas/ModelId" }
        system: { $ref: "#/components/schemas/System" }
        messages:
          type: array
          minItems: 1
          maxItems: 1000
          items:
            oneOf:
              - { $ref: "#/components/schemas/UserMessage" }
              - { $ref: "#/components/schemas/AssistantMessage" }
        tools: { type: array, maxItems: 64, items: { $ref: "#/components/schemas/Tool" } }
        tool_choice: { $ref: "#/components/schemas/ToolChoice" }
        max_tokens:
          type: integer
          minimum: 1
          maximum: 1000000
          description: The most output tokens the model may produce; also what the hold is computed with.
        temperature: { type: number, minimum: 0, maximum: 1 }
        top_p: { type: number, exclusiveMinimum: 0, maximum: 1 }
        stop_sequences: { type: array, maxItems: 4, items: { type: string, minLength: 1, maxLength: 200 } }
        metadata:
          type: object
          additionalProperties: false
          properties:
            user_id: { type: string, maxLength: 256, description: An opaque id of your end user (never an email or a name). }
        stream: { type: boolean }
        effort:
          type: string
          enum: [auto, low, medium, high, xhigh, max]
          description: How much reasoning the call may spend; accepted only where the installation offers effort levels (otherwise the request is refused as invalid).
    Usage:
      type: object
      required: [input_tokens, output_tokens, cache_read_input_tokens, cache_creation_input_tokens]
      properties:
        input_tokens: { type: integer, description: Input tokens charged at the input rate (cache reads and writes excluded). }
        output_tokens: { type: integer }
        cache_read_input_tokens: { type: integer }
        cache_creation_input_tokens: { type: integer }
        server_tool_use:
          type: object
          description: With server tools, how many searches and page reads ran.
          properties:
            web_search_requests: { type: integer }
            web_fetch_requests: { type: integer }
    Billing:
      type: object
      required: [currency, charged_micros]
      properties:
        currency: { const: EUR }
        charged_micros: { $ref: "#/components/schemas/Micros" }
        funding: { const: test, description: Present when test credit paid for the request. }
        model_calls: { type: integer, description: With server tools or MCP servers, how many model calls the request took (charged_micros is their sum). }
    StopReason:
      type: string
      enum: [end_turn, max_tokens, stop_sequence, tool_use, content_filter]
    Message:
      type: object
      required: [id, type, role, model, content, stop_reason, stop_sequence, usage]
      description: |
        A completed message always has a stop_reason and billing. In a stream,
        message_start carries the message with empty content, a null
        stop_reason, zero usage and no billing; message_delta completes them.
      properties:
        id: { type: string, description: "msg_ followed by the request's usage id." }
        type: { const: message }
        role: { const: assistant }
        model: { $ref: "#/components/schemas/ModelId" }
        content:
          type: array
          description: |
            Text and tool_use blocks. With the developer platform on, text blocks may carry `citations` (Citation), and
            server_tool_use, web_search_tool_result, web_fetch_tool_result, mcp_tool_use and mcp_tool_result blocks show
            what ANTARES ran during the request.
          items:
            oneOf:
              - { $ref: "#/components/schemas/TextBlock" }
              - { $ref: "#/components/schemas/ToolUseBlock" }
              - type: object
                required: [type]
                properties:
                  type: { type: string, enum: [server_tool_use, web_search_tool_result, web_fetch_tool_result, mcp_tool_use, mcp_tool_result] }
        stop_reason: { oneOf: [{ $ref: "#/components/schemas/StopReason" }, { const: pause_turn }, { type: "null" }] }
        stop_sequence: { type: "null" }
        usage: { $ref: "#/components/schemas/Usage" }
        billing: { $ref: "#/components/schemas/Billing" }
        parsed_output:
          type: [object, "null"]
          description: With output_format, the answer parsed and checked against the schema; null when it did not match.
    MessageStreamEvent:
      oneOf:
        - type: object
          required: [type, message]
          properties:
            type: { const: message_start }
            message: { $ref: "#/components/schemas/Message" }
        - type: object
          required: [type, index, content_block]
          properties:
            type: { const: content_block_start }
            index: { type: integer }
            content_block:
              oneOf:
                - { $ref: "#/components/schemas/TextBlock" }
                - { $ref: "#/components/schemas/ToolUseBlock" }
        - type: object
          required: [type, index, delta]
          properties:
            type: { const: content_block_delta }
            index: { type: integer }
            delta:
              oneOf:
                - type: object
                  required: [type, text]
                  properties: { type: { const: text_delta }, text: { type: string } }
                - type: object
                  required: [type, partial_json]
                  properties: { type: { const: input_json_delta }, partial_json: { type: string } }
        - type: object
          required: [type, index]
          properties:
            type: { const: content_block_stop }
            index: { type: integer }
        - type: object
          required: [type, delta, usage, billing]
          properties:
            type: { const: message_delta }
            delta:
              type: object
              properties:
                stop_reason: { $ref: "#/components/schemas/StopReason" }
                stop_sequence: { type: "null" }
            usage: { $ref: "#/components/schemas/Usage" }
            billing: { $ref: "#/components/schemas/Billing" }
        - type: object
          required: [type]
          properties:
            type: { const: message_stop }
        - type: object
          required: [type]
          properties:
            type: { const: ping }
        - type: object
          required: [type, error]
          properties:
            type: { const: error }
            error: { $ref: "#/components/schemas/ErrorObject" }
    CountTokensResponse:
      type: object
      required: [input_tokens, reservation_input_tokens]
      properties:
        input_tokens: { type: integer, description: An estimate of the prompt's input tokens. }
        reservation_input_tokens: { type: integer, description: The bound a real call with this prompt is held and rate-limited with. }
    Model:
      type: object
      required: [type, object, id, display_name, owned_by, context_window, max_output_tokens, capabilities, pricing]
      properties:
        type: { const: model }
        object: { const: model }
        id: { $ref: "#/components/schemas/ModelId" }
        display_name: { type: string }
        owned_by: { type: string, description: The provider that serves the model. }
        notice: { type: string, description: A disclosure that must accompany the model (for example the origin of open weights). }
        context_window: { type: integer }
        max_output_tokens: { type: integer }
        capabilities:
          type: array
          items: { type: string, enum: [text, vision, tools, streaming] }
        pricing:
          type: object
          required: [currency, revision, expires_at, token_rates_micros_per_million, request_micros]
          properties:
            currency: { const: EUR }
            revision: { type: string }
            expires_at: { type: string, format: date-time }
            token_rates_micros_per_million:
              type: object
              required: [input, cached_input, cache_write_input, output]
              properties:
                input: { $ref: "#/components/schemas/Micros" }
                cached_input: { $ref: "#/components/schemas/Micros" }
                cache_write_input: { $ref: "#/components/schemas/Micros" }
                output: { $ref: "#/components/schemas/Micros" }
            request_micros: { $ref: "#/components/schemas/Micros" }
    ModelList:
      type: object
      required: [object, data, has_more, first_id, last_id]
      properties:
        object: { const: list }
        data: { type: array, items: { $ref: "#/components/schemas/Model" } }
        has_more: { type: boolean }
        first_id: { oneOf: [{ $ref: "#/components/schemas/ModelId" }, { type: "null" }] }
        last_id: { oneOf: [{ $ref: "#/components/schemas/ModelId" }, { type: "null" }] }
    RequestStatus:
      type: object
      required: [id, status, fundingMode, reservedMicros, chargedMicros, createdAt, updatedAt]
      properties:
        id: { type: string, format: uuid }
        status:
          type: string
          enum: [reserved, uncertain, settled, released]
          description: |
            reserved: running; settled: charged (chargedMicros); released:
            nothing charged; uncertain: the provider's usage could not be
            confirmed and the hold is under review.
        fundingMode: { type: string, enum: [live, test] }
        reservedMicros: { $ref: "#/components/schemas/Micros" }
        chargedMicros: { oneOf: [{ $ref: "#/components/schemas/Micros" }, { type: "null" }] }
        createdAt: { type: string, format: date-time }
        updatedAt: { type: string, format: date-time }
    ErrorType:
      type: string
      enum: [invalid_request_error, authentication_error, permission_error, not_found_error, request_too_large, rate_limit_error, billing_error, api_error, overloaded_error]
    ErrorObject:
      type: object
      required: [type, code, message, request_id]
      properties:
        type: { $ref: "#/components/schemas/ErrorType" }
        code: { type: string, description: The precise, stable reason (for example API_INSUFFICIENT_FUNDS). }
        message: { type: string, description: A fixed English sentence; never echoes your input. }
        request_id: { type: string }
    ErrorResponse:
      type: object
      required: [type, error, request_id]
      properties:
        type: { const: error }
        error: { $ref: "#/components/schemas/ErrorObject" }
        request_id: { type: string }
    ChatErrorResponse:
      type: object
      required: [error]
      properties:
        error:
          type: object
          required: [message, type, param, code]
          properties:
            message: { type: string }
            type: { type: string }
            param: { type: "null" }
            code: { type: string }
    ChatTextPart:
      type: object
      additionalProperties: false
      required: [type, text]
      properties:
        type: { const: text }
        text: { type: string, maxLength: 400000 }
    ChatImagePart:
      type: object
      additionalProperties: false
      required: [type, image_url]
      properties:
        type: { const: image_url }
        image_url:
          type: object
          additionalProperties: false
          required: [url]
          properties:
            url: { type: string, description: "A data: URL (data:image/png;base64,...); other URLs are refused." }
            detail: { type: string, enum: [auto, low, high] }
    ChatToolCall:
      type: object
      additionalProperties: false
      required: [id, type, function]
      properties:
        id: { $ref: "#/components/schemas/ToolId" }
        type: { const: function }
        function:
          type: object
          additionalProperties: false
          required: [name, arguments]
          properties:
            name: { $ref: "#/components/schemas/ToolName" }
            arguments: { type: string, description: A JSON object as text. }
    ChatMessage:
      oneOf:
        - type: object
          additionalProperties: false
          required: [role, content]
          properties:
            role: { type: string, enum: [system, developer] }
            content: { oneOf: [{ type: string }, { type: array, maxItems: 20, items: { $ref: "#/components/schemas/ChatTextPart" } }] }
            name: { type: string, maxLength: 64 }
        - type: object
          additionalProperties: false
          required: [role, content]
          properties:
            role: { const: user }
            content:
              oneOf:
                - { type: string }
                - type: array
                  minItems: 1
                  maxItems: 100
                  items: { oneOf: [{ $ref: "#/components/schemas/ChatTextPart" }, { $ref: "#/components/schemas/ChatImagePart" }] }
            name: { type: string, maxLength: 64 }
        - type: object
          additionalProperties: false
          required: [role]
          properties:
            role: { const: assistant }
            content: { oneOf: [{ type: string }, { type: array, maxItems: 20, items: { $ref: "#/components/schemas/ChatTextPart" } }, { type: "null" }] }
            tool_calls: { type: array, maxItems: 64, items: { $ref: "#/components/schemas/ChatToolCall" } }
            name: { type: string, maxLength: 64 }
        - type: object
          additionalProperties: false
          required: [role, content, tool_call_id]
          properties:
            role: { const: tool }
            content: { oneOf: [{ type: string }, { type: array, maxItems: 20, items: { $ref: "#/components/schemas/ChatTextPart" } }] }
            tool_call_id: { $ref: "#/components/schemas/ToolId" }
    ChatCompletionRequest:
      type: object
      additionalProperties: false
      required: [model, messages]
      properties:
        model: { $ref: "#/components/schemas/ModelId" }
        messages: { type: array, minItems: 1, maxItems: 1000, items: { $ref: "#/components/schemas/ChatMessage" } }
        max_tokens: { type: integer, minimum: 1, maximum: 1000000 }
        effort: { type: string, enum: [auto, low, medium, high, xhigh, max], description: How much reasoning the call may spend; accepted only where the installation offers effort levels. }
        max_completion_tokens: { type: integer, minimum: 1, maximum: 1000000, description: Same as max_tokens; if both are sent they must be equal. }
        temperature: { type: number, minimum: 0, maximum: 1 }
        top_p: { type: number, exclusiveMinimum: 0, maximum: 1 }
        stop: { oneOf: [{ type: string, minLength: 1, maxLength: 200 }, { type: array, maxItems: 4, items: { type: string, minLength: 1, maxLength: 200 } }] }
        stream: { type: boolean }
        stream_options: { type: object, additionalProperties: false, properties: { include_usage: { type: boolean } } }
        tools:
          type: array
          maxItems: 64
          items:
            type: object
            additionalProperties: false
            required: [type, function]
            properties:
              type: { const: function }
              function:
                type: object
                additionalProperties: false
                required: [name]
                properties:
                  name: { $ref: "#/components/schemas/ToolName" }
                  description: { type: string, maxLength: 4096 }
                  parameters: { type: object }
                  strict: { type: boolean }
        tool_choice:
          oneOf:
            - { type: string, enum: [none, auto, required] }
            - type: object
              additionalProperties: false
              required: [type, function]
              properties:
                type: { const: function }
                function: { type: object, additionalProperties: false, required: [name], properties: { name: { $ref: "#/components/schemas/ToolName" } } }
        parallel_tool_calls: { type: boolean }
        response_format:
          oneOf:
            - { type: object, additionalProperties: false, required: [type], properties: { type: { const: text } } }
            - { type: object, additionalProperties: false, required: [type], properties: { type: { const: json_object } } }
            - type: object
              additionalProperties: false
              required: [type, json_schema]
              properties:
                type: { const: json_schema }
                json_schema:
                  type: object
                  additionalProperties: false
                  required: [name, schema]
                  properties:
                    name: { type: string, pattern: "^[a-zA-Z0-9_-]{1,64}$" }
                    description: { type: string, maxLength: 4096 }
                    schema: { type: object }
                    strict: { type: boolean }
        n: { const: 1 }
        seed: { type: integer }
        user: { type: string, maxLength: 256 }
        store: { const: false }
    ChatCompletion:
      type: object
      required: [id, object, created, model, choices, usage]
      properties:
        id: { type: string }
        object: { const: chat.completion }
        created: { type: integer }
        model: { $ref: "#/components/schemas/ModelId" }
        choices:
          type: array
          items:
            type: object
            required: [index, message, finish_reason, logprobs]
            properties:
              index: { const: 0 }
              message:
                type: object
                required: [role, content, refusal]
                properties:
                  role: { const: assistant }
                  content: { oneOf: [{ type: string }, { type: "null" }] }
                  tool_calls: { type: array, items: { $ref: "#/components/schemas/ChatToolCall" } }
                  refusal: { type: "null" }
              finish_reason: { type: string, enum: [stop, length, tool_calls, content_filter] }
              logprobs: { type: "null" }
        usage:
          type: object
          required: [prompt_tokens, completion_tokens, total_tokens]
          properties:
            prompt_tokens: { type: integer }
            completion_tokens: { type: integer }
            total_tokens: { type: integer }
            prompt_tokens_details: { type: object, properties: { cached_tokens: { type: integer } } }
    ResponseCreateRequest:
      type: object
      additionalProperties: false
      required: [model, input, max_output_tokens]
      properties:
        model: { $ref: "#/components/schemas/ModelId" }
        input:
          oneOf:
            - { type: string, minLength: 1, maxLength: 32000 }
            - type: array
              minItems: 1
              maxItems: 32
              items:
                type: object
                additionalProperties: false
                required: [role, content]
                properties:
                  role: { type: string, enum: [user, assistant] }
                  content: { type: string, minLength: 1, maxLength: 32000 }
        instructions: { type: string, maxLength: 8000 }
        max_output_tokens: { type: integer, minimum: 1, maximum: 16384 }
        stream: { const: false }
        store: { const: false }
    TextResponse:
      type: object
      required: [id, object, created_at, status, model, output, usage, store]
      properties:
        id: { type: string }
        object: { const: response }
        created_at: { type: integer }
        status: { type: string, enum: [completed, incomplete] }
        model: { $ref: "#/components/schemas/ModelId" }
        output:
          type: array
          items:
            type: object
            properties:
              type: { const: message }
              role: { const: assistant }
              content:
                type: array
                items:
                  type: object
                  properties:
                    type: { const: output_text }
                    text: { type: string }
        usage:
          type: object
          properties:
            input_tokens: { type: integer }
            output_tokens: { type: integer }
            total_tokens: { type: integer }
        store: { const: false }
        funding: { const: test }
    File:
      type: object
      required: [id, type, filename, mime_type, size_bytes, created_at, downloadable]
      properties:
        id: { type: string, pattern: "^file_[0-9a-f]{32}$" }
        type: { const: file }
        filename: { type: string }
        mime_type: { type: string }
        size_bytes: { type: integer }
        created_at: { type: string, format: date-time }
        downloadable: { type: boolean }
    FilePage:
      type: object
      required: [data, has_more, first_id, last_id]
      properties:
        data: { type: array, items: { $ref: "#/components/schemas/File" } }
        has_more: { type: boolean }
        first_id: { type: [string, "null"] }
        last_id: { type: [string, "null"] }
    CacheControl:
      type: object
      additionalProperties: false
      required: [type]
      description: A caching breakpoint. Only the 5-minute lifetime is available; at most 4 breakpoints a request.
      properties:
        type: { const: ephemeral }
        ttl: { const: 5m }
    DocumentBlock:
      type: object
      additionalProperties: false
      required: [type, source]
      description: |
        A document the model reads: a base64 PDF (at most 8 MiB), plain text, content blocks, or a file id. With
        `citations.enabled` the answer's text blocks carry the passages they rely on (char_location, or
        content_block_location for content blocks).
      properties:
        type: { const: document }
        source:
          oneOf:
            - { type: object, required: [type, media_type, data], properties: { type: { const: base64 }, media_type: { const: application/pdf }, data: { type: string } } }
            - { type: object, required: [type, media_type, data], properties: { type: { const: text }, media_type: { const: text/plain }, data: { type: string } } }
            - { type: object, required: [type, content], properties: { type: { const: content }, content: { oneOf: [{ type: string }, { type: array, items: { $ref: "#/components/schemas/TextBlock" } }] } } }
            - { type: object, required: [type, file_id], properties: { type: { const: file }, file_id: { type: string } } }
        title: { type: string, maxLength: 500 }
        context: { type: string, maxLength: 8000 }
        citations: { type: object, properties: { enabled: { type: boolean } } }
        cache_control: { $ref: "#/components/schemas/CacheControl" }
    WebSearchTool:
      type: object
      required: [type, name]
      description: Runs on ANTARES's self-hosted search only, while it costs nothing per query; otherwise refused with server_tool_unavailable.
      properties:
        type: { const: web_search_20250305 }
        name: { const: web_search }
        max_uses: { type: integer, minimum: 1, maximum: 10 }
        allowed_domains: { type: array, items: { type: string } }
        blocked_domains: { type: array, items: { type: string } }
    WebFetchTool:
      type: object
      required: [type, name]
      description: Reads one public https page (never private, local or metadata addresses).
      properties:
        type: { const: web_fetch_20250910 }
        name: { const: web_fetch }
        max_uses: { type: integer, minimum: 1, maximum: 10 }
        allowed_domains: { type: array, items: { type: string } }
        blocked_domains: { type: array, items: { type: string } }
        max_content_tokens: { type: integer, minimum: 100, maximum: 100000 }
    McpServer:
      type: object
      additionalProperties: false
      required: [type, url, name]
      description: A remote MCP server (public https only) whose tools ANTARES calls during the request. The token is used for this request only and never stored.
      properties:
        type: { const: url }
        url: { type: string, format: uri }
        name: { type: string, pattern: "^[a-zA-Z0-9_-]{1,64}$" }
        authorization_token: { type: string }
        tool_configuration:
          type: object
          properties:
            enabled: { type: boolean }
            allowed_tools: { type: array, items: { $ref: "#/components/schemas/ToolName" } }
    PlatformMessageCreateRequest:
      description: |
        The /v1/messages body while the developer platform is on: MessageCreateRequest plus documents and images by file
        id, `cache_control` breakpoints on text, documents, system blocks and tools, `output_format` (a JSON schema; the
        message then carries `parsed_output`), the server tools web_search and web_fetch, and `mcp_servers`. Streaming
        is not available together with citations, output_format, server tools or MCP servers. A request with server
        tools or MCP servers may take several model calls; each is charged like a direct call and `billing` reports their
        sum and `model_calls`. After 8 calls the message stops with `pause_turn`.
      allOf:
        - { $ref: "#/components/schemas/MessageCreateRequest" }
        - type: object
          properties:
            output_format:
              type: object
              required: [type, schema]
              properties: { type: { const: json_schema }, schema: { type: object } }
            mcp_servers: { type: array, maxItems: 5, items: { $ref: "#/components/schemas/McpServer" } }
            tools:
              type: array
              items:
                oneOf:
                  - { $ref: "#/components/schemas/Tool" }
                  - { $ref: "#/components/schemas/WebSearchTool" }
                  - { $ref: "#/components/schemas/WebFetchTool" }
    Citation:
      type: object
      required: [type, cited_text, document_index]
      properties:
        type: { type: string, enum: [char_location, content_block_location] }
        cited_text: { type: string }
        document_index: { type: integer }
        document_title: { type: [string, "null"] }
        start_char_index: { type: integer }
        end_char_index: { type: integer }
        start_block_index: { type: integer }
        end_block_index: { type: integer }
    MessageBatchCreateRequest:
      type: object
      additionalProperties: false
      required: [requests]
      properties:
        requests:
          type: array
          minItems: 1
          maxItems: 1000
          items:
            type: object
            additionalProperties: false
            required: [custom_id, params]
            properties:
              custom_id: { type: string, pattern: "^[a-zA-Z0-9_-]{1,64}$" }
              params: { $ref: "#/components/schemas/PlatformMessageCreateRequest" }
    MessageBatch:
      type: object
      required: [id, type, processing_status, request_counts, created_at, expires_at]
      properties:
        id: { type: string, pattern: "^msgbatch_[0-9a-f]{32}$" }
        type: { const: message_batch }
        processing_status: { type: string, enum: [in_progress, canceling, ended] }
        request_counts:
          type: object
          properties:
            processing: { type: integer }
            succeeded: { type: integer }
            errored: { type: integer }
            canceled: { type: integer }
            expired: { type: integer }
        created_at: { type: string, format: date-time }
        expires_at: { type: string, format: date-time }
        cancel_initiated_at: { type: [string, "null"], format: date-time }
        ended_at: { type: [string, "null"], format: date-time }
        archived_at: { type: "null" }
        results_expire_at: { type: [string, "null"], format: date-time }
        results_url: { type: [string, "null"], description: Relative to the API's base URL. }
    MessageBatchResult:
      type: object
      required: [custom_id, result]
      properties:
        custom_id: { type: string }
        result:
          type: object
          required: [type]
          properties:
            type: { type: string, enum: [succeeded, errored, canceled, expired] }
            message: { $ref: "#/components/schemas/Message" }
            error: { type: object, properties: { type: { $ref: "#/components/schemas/ErrorType" }, code: { type: string }, message: { type: string } } }
    Workspace:
      type: object
      required: [id, type, name, created_at, archived_at]
      properties:
        id: { type: string, pattern: "^wrkspc_[0-9a-f]{32}$" }
        type: { const: workspace }
        name: { type: string }
        created_at: { type: string, format: date-time }
        archived_at: { type: [string, "null"], format: date-time }
    WorkspaceCreateRequest:
      type: object
      additionalProperties: false
      required: [name]
      properties:
        name: { type: string, minLength: 1, maxLength: 100 }
        spending_cap_micros: { $ref: "#/components/schemas/Micros" }
    WorkspaceUpdateRequest:
      type: object
      additionalProperties: false
      required: [name]
      properties:
        name: { type: string, minLength: 1, maxLength: 100 }
    ApiKey:
      type: object
      required: [id, type, name, workspace_id, partial_key_hint, scopes, status, created_at, expires_at, last_used_at]
      properties:
        id: { type: string, pattern: "^apikey_[0-9a-f]{32}$" }
        type: { const: api_key }
        name: { type: string }
        workspace_id: { type: string }
        partial_key_hint: { type: string }
        scopes: { type: array, items: { type: string } }
        status: { type: string, enum: [active, inactive, expired] }
        created_at: { type: string, format: date-time }
        expires_at: { type: string, format: date-time }
        last_used_at: { type: [string, "null"], format: date-time }
    ApiKeyUpdateRequest:
      type: object
      additionalProperties: false
      properties:
        name: { type: string, minLength: 1, maxLength: 100 }
        status: { const: inactive }
    UsageReport:
      type: object
      required: [data, has_more]
      properties:
        data:
          type: array
          items:
            type: object
            properties:
              starting_at: { type: string, format: date-time }
              ending_at: { type: string, format: date-time }
              results:
                type: array
                items:
                  type: object
                  properties:
                    requests: { type: integer }
                    settled_requests: { type: integer }
                    uncached_input_tokens: { type: integer }
                    cache_read_input_tokens: { type: integer }
                    cache_creation_input_tokens: { type: integer }
                    output_tokens: { type: integer }
                    model: { type: [string, "null"] }
                    workspace_id: { type: [string, "null"] }
                    api_key_id: { type: [string, "null"] }
        has_more: { type: boolean }
        next_page: { type: "null" }
    CostReport:
      type: object
      required: [data, has_more]
      properties:
        data:
          type: array
          items:
            type: object
            properties:
              starting_at: { type: string, format: date-time }
              ending_at: { type: string, format: date-time }
              results:
                type: array
                items:
                  type: object
                  properties:
                    currency: { const: EUR }
                    charged_micros: { $ref: "#/components/schemas/Micros" }
                    held_micros: { $ref: "#/components/schemas/Micros" }
                    model: { type: [string, "null"] }
                    workspace_id: { type: [string, "null"] }
        has_more: { type: boolean }
        next_page: { type: "null" }
