openapi: 3.1.0
info:
  title: Dispatch API
  version: '1'
  summary: Talk to your Dispatch agents from your own website or backend.
  description: |
    The Dispatch API lets your website start conversations with a live agent and exchange messages with it.
    Every response is JSON except a reply to a message, which can also be Server-Sent Events, Markdown or plain text.
  contact:
    name: Dispatch
    url: https://docs.rundispatch.ai
servers:
  - url: https://api.rundispatch.ai/v1
    description: Production
tags:
  - name: Conversations
    description: Start a conversation with an agent, then send and list its messages.
security: []

paths:
  /agents/{agent}/conversations:
    post:
      operationId: startConversation
      summary: Starting a conversation with an Agent
      tags: [Conversations]
      description: |
        Starts a new conversation between a visitor and a live agent.

        Every field is optional. Send `user` when you know who the visitor is: an `email` links the conversation to
        the person the agent has already talked to with that email, and any `name` or `phone_number` you send
        updates what is stored. Without an `email`, a new visitor is created every time.

        The response includes the visitor as a participant with their `token`, which sends and lists messages in
        every conversation they take part in. Tokens last 90 days (`token_expires_at`). A visitor matched by `email`
        keeps the token they already have, unless it expires within 7 days: then they get a new one for another 90
        days.
      security:
        - apiKey: []
      parameters:
        - $ref: '#/components/parameters/AgentId'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StartConversationRequest'
            examples:
              withUser:
                summary: A known visitor on the pricing page
                value:
                  user:
                    name: Jane
                    email: jane@example.com
                    phone_number: '+639171234567'
                  context:
                    - label: Page
                      description: Page the visitor is on
                      value: /pricing
              anonymous:
                summary: An anonymous visitor
                value: {}
      responses:
        '201':
          description: The conversation was started.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConversationResponse'
              examples:
                started:
                  $ref: '#/components/examples/Conversation'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/ApiKeyForbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/ValidationFailed'
        '429':
          $ref: '#/components/responses/TooManyRequests'

  /conversations/{conversation}:
    get:
      operationId: getConversation
      summary: Getting a conversation
      tags: [Conversations]
      description: |
        Returns a conversation with its participants, including each participant's `token`. Use it to resume a
        conversation or to recover a token you lost. A token in its last 7 days, or already expired, is replaced by a new
        one valid for another 90 days.

        Only the API key that started the conversation can get it. Any other key gets `404`.
      security:
        - apiKey: []
      parameters:
        - $ref: '#/components/parameters/ConversationId'
      responses:
        '200':
          description: The conversation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConversationResponse'
              examples:
                conversation:
                  $ref: '#/components/examples/Conversation'
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/NotLive'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'

  /conversations/{conversation}/messages:
    get:
      operationId: listMessages
      summary: Listing a conversation's messages
      tags: [Conversations]
      description: |
        Lists the conversation's messages, **newest first**, with cursor pagination. Load the first page to show
        the latest messages, then follow `links.next` for older ones.

        Authenticate with the participant's `token`, not the API key. A token of a visitor outside the conversation
        gets `403`.

        Only what the visitor sees is listed: the visitor's messages, the agent's replies and files the agent
        shared. A file that no longer exists keeps its place with `url` set to `null`. File URLs are signed and stop
        working at `expires_at`; list the messages again to get new ones.

        When a scheduled task runs, it runs in a child conversation, and the parent conversation gets a message of
        type `conversation` pointing to it through `conversation_id`. List the child's messages with this same
        endpoint and the same token. A child conversation is a record of the run, so sending a message to it fails
        with `422`.
      security:
        - participantToken: []
      parameters:
        - $ref: '#/components/parameters/ConversationId'
        - name: per_page
          in: query
          required: false
          description: How many messages to return.
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 20
        - name: cursor
          in: query
          required: false
          description: The cursor of the page to load. Take it from `links.next`/`links.prev` or `meta.next_cursor`.
          schema:
            type: string
      responses:
        '200':
          description: A page of messages, newest first.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessagePage'
              examples:
                page:
                  value:
                    data:
                      - id: 0199d2f4-1c4e-7a1b-9e0e-3b1f5c6d7e80
                        role: agent
                        type: file
                        content: ''
                        file:
                          name: menu.pdf
                          mime_type: application/pdf
                          url: https://files.rundispatch.ai/menu.pdf?signature=4f9c2e7a
                          preview_url: null
                          download_url: https://files.rundispatch.ai/menu.pdf?download=1&signature=4f9c2e7a
                          expires_at: '2026-10-13T09:00:00+00:00'
                        failed: false
                        created_at: '2026-10-13T08:00:05+00:00'
                      - id: 0199d2f4-1a2b-7c3d-8e4f-5a6b7c8d9e0f
                        role: agent
                        type: text
                        content: Here's our menu.
                        failed: false
                        citations:
                          - url: https://docs.example.com/menu
                            title: Our menu
                        created_at: '2026-10-13T08:00:04+00:00'
                      - id: 0199d2f4-0f1e-7d2c-9b3a-4c5d6e7f8091
                        role: user
                        type: text
                        participant_id: 0199e4a0-5b6c-7d8e-9f01-23456789abcd
                        content: Show me the menu
                        context:
                          - label: Page
                            description: Page the visitor is on
                            value: /menu
                        created_at: '2026-10-13T08:00:00+00:00'
                    links:
                      first: null
                      last: null
                      prev: null
                      next: https://api.rundispatch.ai/v1/conversations/0199d2f4-0a1b-7c2d-8e3f-405162738495/messages?cursor=eyJpZCI6MX0
                    meta:
                      path: https://api.rundispatch.ai/v1/conversations/0199d2f4-0a1b-7c2d-8e3f-405162738495/messages
                      per_page: 20
                      next_cursor: eyJpZCI6MX0
                      prev_cursor: null
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '403':
          $ref: '#/components/responses/ParticipantForbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/ValidationFailed'
        '429':
          $ref: '#/components/responses/TooManyRequests'

    post:
      operationId: sendMessage
      summary: Sending a message to an Agent
      tags: [Conversations]
      description: |
        Sends the visitor's message and returns the agent's reply. The `Accept` header picks how the reply comes
        back:

        | `Accept` | Reply |
        | --- | --- |
        | `application/json` (or none) | All at once, as JSON: the Markdown and the files the agent shared. |
        | `text/event-stream` | Streamed as it is written. See *Streaming* below. |
        | `text/markdown` | All at once, as Markdown. Shared files appear as images or links where they were written. |
        | `text/plain` | All at once, as plain text without Markdown, for places such as SMS. The agent shares no files. |

        Any other type returns `406`.

        Authenticate with the participant's `token`. The message is sent as that participant, who must take part in
        the conversation; anyone else gets `403`.

        ### Streaming

        The reply is a stream of `data:` lines, each holding one JSON event, and ends with `data: [DONE]`. Append
        the `delta` of every `text_delta` event to show the reply as it is written. An `embed_file` event is a file
        the agent shared. Ignore event types you don't use; new ones may be added.

        ```
        data: {"type":"stream_start", …}
        data: {"type":"text_start","message_id":"…", …}
        data: {"type":"text_delta","message_id":"…","delta":"Here's ", …}
        data: {"type":"text_delta","message_id":"…","delta":"our menu.", …}
        data: {"type":"embed_file","name":"menu.pdf","mime_type":"application/pdf","url":"…", …}
        data: {"type":"stream_end","reason":"stop", …}
        data: [DONE]
        ```
      security:
        - participantToken: []
      x-codeSamples:
        - id: curl
          lang: bash
          label: cURL
          source: |
            curl -N -X POST "https://api.rundispatch.ai/v1/conversations/$CONVERSATION_ID/messages" \
              -H "Authorization: Bearer $PARTICIPANT_TOKEN" \
              -H "Accept: text/event-stream" \
              -H "Content-Type: application/json" \
              -d '{"content": "Do you deliver on Sundays?"}'
        - id: js
          lang: js
          label: JavaScript
          source: |
            const participant = conversation._embedded.participants[0];

            const response = await fetch(conversation._links.send_message.href, {
              method: 'POST',
              headers: {
                Authorization: `Bearer ${participant.token}`,
                Accept: 'text/event-stream',
                'Content-Type': 'application/json',
              },
              body: JSON.stringify({ content: 'Do you deliver on Sundays?' }),
            });
        - id: python
          lang: python
          label: Python
          source: |
            import requests

            participant = conversation["_embedded"]["participants"][0]

            response = requests.post(
                conversation["_links"]["send_message"]["href"],
                headers={"Authorization": f"Bearer {participant['token']}", "Accept": "application/json"},
                json={"content": "Do you deliver on Sundays?"},
            )
            print(response.json()["data"]["markdown"])
      parameters:
        - $ref: '#/components/parameters/ConversationId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SendMessageRequest'
            examples:
              withContext:
                summary: A message with what the visitor is looking at
                value:
                  content: How do I go back home from this page?
                  context:
                    - label: Page
                      description: Page the visitor is on
                      value: /checkout/step-2
                    - label: Local time
                      description: Visitor's local time
                      value: 2026-10-13T16:02:00+08:00 (Asia/Manila)
      responses:
        '200':
          description: The agent's reply.
          content:
            text/event-stream:
              schema:
                type: string
                description: '`data:` lines, each a JSON stream event, ending with `data: [DONE]`.'
              examples:
                streaming:
                  value: |
                    data: {"type":"text_start","message_id":"msg_1","timestamp":1760342520}

                    data: {"type":"text_delta","message_id":"msg_1","delta":"Use the ","timestamp":1760342520}

                    data: {"type":"text_delta","message_id":"msg_1","delta":"Home link at the top.","timestamp":1760342521}

                    data: [DONE]
            application/json:
              schema:
                $ref: '#/components/schemas/BufferedReply'
              examples:
                json:
                  value:
                    data:
                      markdown: |-
                        Here's our menu.

                        [menu.pdf](https://files.rundispatch.ai/menu.pdf?signature=4f9c2e7a)
                      attachments:
                        - id: 0199c1a2-3b4c-7d5e-8f60-718293a4b5c6
                          type: file
                          name: menu.pdf
                          mime_type: application/pdf
                          url: https://files.rundispatch.ai/menu.pdf?signature=4f9c2e7a
                          preview_url: null
                          download_url: https://files.rundispatch.ai/menu.pdf?download=1&signature=4f9c2e7a
                          expires_at: '2026-10-13T09:00:00+00:00'
            text/markdown:
              schema:
                type: string
                description: The whole reply as Markdown, with shared files where they were written.
              examples:
                markdown:
                  value: |-
                    Here's our menu.

                    [menu.pdf](https://files.rundispatch.ai/menu.pdf?signature=4f9c2e7a)
            text/plain:
              schema:
                type: string
                description: The whole reply as plain text. No files are shared.
              examples:
                plain:
                  value: |-
                    We deliver every day, Sundays included, from 9 AM to 9 PM.
        '401':
          $ref: '#/components/responses/Unauthenticated'
        '402':
          $ref: '#/components/responses/InsufficientWallet'
        '403':
          $ref: '#/components/responses/ParticipantForbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/ValidationFailed'
        '406':
          description: The `Accept` header asks for none of the reply types above.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                notAcceptable:
                  value:
                    message: Not Acceptable
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '502':
          description: |
            The agent could not reply (not when streaming). Your message was saved. As JSON, `data` holds what the
            agent wrote before it failed, if anything; as Markdown or plain text, the body is the error message.
          content:
            application/json:
              schema:
                type: object
                required: [message, data]
                properties:
                  message:
                    type: string
                  data:
                    $ref: '#/components/schemas/Reply'
              examples:
                failed:
                  value:
                    message: The agent could not reply.
                    data:
                      markdown: ''
                      attachments: []
            text/markdown:
              schema:
                type: string
              examples:
                failed:
                  value: The agent could not reply.
            text/plain:
              schema:
                type: string
              examples:
                failed:
                  value: The agent could not reply.

components:
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: |
        Your Dispatch API key, sent as `Authorization: Bearer <key>`. Used to start and get conversations. The key
        is visible in your website's source, so it only allows starting conversations with the agents you chose.
    participantToken:
      type: http
      scheme: bearer
      description: |
        A participant's `token`, from the conversation's `_embedded.participants`, sent as
        `Authorization: Bearer <token>`. Used to send and list messages as that participant, in every conversation
        they take part in. It lasts 90 days.

  parameters:
    AgentId:
      name: agent
      in: path
      required: true
      description: |
        The agent's ID. It is in the agent's address in Dispatch (`https://app.rundispatch.ai/agents/<id>`) and in
        the agent's Channels dialog, which can copy it.
      schema:
        type: string
        format: uuid
    ConversationId:
      name: conversation
      in: path
      required: true
      description: The conversation's `id`.
      schema:
        type: string
        format: uuid

  schemas:
    ContextItem:
      type: object
      description: |
        Something the agent should know, such as the page the visitor is on. The `description` tells the agent
        what the value means.
      required: [label, description, value]
      properties:
        label:
          type: string
          maxLength: 100
          examples: [Page]
        description:
          type: string
          maxLength: 500
          examples: [Page the visitor is on]
        value:
          type: string
          maxLength: 2000
          examples: [/pricing]

    UserInput:
      type: object
      description: Who the visitor is. Every field is optional.
      properties:
        name:
          type: [string, 'null']
          maxLength: 255
        email:
          type: [string, 'null']
          format: email
          maxLength: 255
          description: Links this conversation to the visitor the agent already knows with this email.
        phone_number:
          type: [string, 'null']
          maxLength: 50

    StartConversationRequest:
      type: object
      properties:
        user:
          $ref: '#/components/schemas/UserInput'
        context:
          type: array
          maxItems: 17
          description: |
            What the agent should know for the whole conversation. Dispatch adds the visitor's name, email and
            phone number in front of these.
          items:
            $ref: '#/components/schemas/ContextItem'

    SendMessageRequest:
      type: object
      required: [content]
      properties:
        content:
          type: string
          maxLength: 10000
          description: The visitor's message.
        context:
          type: array
          maxItems: 20
          description: What the agent should know for this message only, such as the visitor's current page and local time.
          items:
            $ref: '#/components/schemas/ContextItem'

    Link:
      type: object
      required: [href]
      properties:
        href:
          type: string
          format: uri
          description: An absolute URL. Use it exactly as given.

    Agent:
      type: object
      required: [id, name, title]
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        title:
          type: [string, 'null']

    Participant:
      type: object
      description: A visitor taking part in the conversation.
      required: [id, type, name, email, phone_number, token, token_expires_at]
      properties:
        id:
          type: string
          format: uuid
        type:
          type: string
          const: end_user
        name:
          type: [string, 'null']
        email:
          type: [string, 'null']
        phone_number:
          type: [string, 'null']
        token:
          type: string
          description: |
            The participant's token, for sending and listing messages in every conversation they take part in. Keep
            it private to this visitor.
        token_expires_at:
          type: string
          format: date-time
          description: |
            When the token stops working, 90 days after it was issued. From 7 days before this, even once it has
            passed, getting the conversation or starting one for the same `email` issues a new one.

    Conversation:
      type: object
      required: [id, agent, context, created_at, _links, _embedded]
      properties:
        id:
          type: string
          format: uuid
        agent:
          $ref: '#/components/schemas/Agent'
        context:
          type: array
          description: The conversation's context as the agent sees it, including the visitor details Dispatch adds.
          items:
            $ref: '#/components/schemas/ContextItem'
        created_at:
          type: string
          format: date-time
        _links:
          type: object
          required: [self, list_messages, send_message]
          properties:
            self:
              $ref: '#/components/schemas/Link'
            list_messages:
              $ref: '#/components/schemas/Link'
            send_message:
              $ref: '#/components/schemas/Link'
        _embedded:
          type: object
          required: [participants]
          properties:
            participants:
              type: array
              items:
                $ref: '#/components/schemas/Participant'

    ConversationResponse:
      type: object
      required: [data]
      properties:
        data:
          $ref: '#/components/schemas/Conversation'

    UserMessage:
      type: object
      required: [id, role, type, participant_id, content, context, created_at]
      properties:
        id:
          type: string
          format: uuid
        role:
          type: string
          const: user
        type:
          type: string
          const: text
        participant_id:
          type: string
          format: uuid
          description: The participant who sent it.
        content:
          type: string
        context:
          type: array
          items:
            $ref: '#/components/schemas/ContextItem'
        created_at:
          type: string
          format: date-time

    AgentTextMessage:
      type: object
      required: [id, role, type, content, failed, citations, created_at]
      properties:
        id:
          type: string
          format: uuid
        role:
          type: string
          const: agent
        type:
          type: string
          const: text
        content:
          type: string
          description: Markdown.
        failed:
          type: boolean
          description: True when the agent could not finish this reply.
        citations:
          $ref: '#/components/schemas/Citations'
        posted_from:
          type: object
          description: Set when a scheduled task posted this message on its own; list `conversation_id`'s messages to see the run.
          required: [conversation_id, title]
          properties:
            conversation_id:
              type: string
              format: uuid
            title:
              type: string
        created_at:
          type: string
          format: date-time

    File:
      type: object
      required: [name, mime_type, url, preview_url, download_url, expires_at]
      properties:
        name:
          type: string
        mime_type:
          type: string
        url:
          type: [string, 'null']
          format: uri
          description: '`null` when the file no longer exists.'
        preview_url:
          type: [string, 'null']
          format: uri
        download_url:
          type: [string, 'null']
          format: uri
        expires_at:
          type: [string, 'null']
          format: date-time
          description: When the URLs stop working.

    AgentFileMessage:
      type: object
      required: [id, role, type, content, file, failed, created_at]
      properties:
        id:
          type: string
          format: uuid
        role:
          type: string
          const: agent
        type:
          type: string
          const: file
        content:
          type: string
        file:
          $ref: '#/components/schemas/File'
        failed:
          type: boolean
          const: false
        created_at:
          type: string
          format: date-time

    AgentConversationMessage:
      type: object
      required: [id, role, type, conversation_id, title, created_at]
      properties:
        id:
          type: string
          format: uuid
        role:
          type: string
          const: agent
        type:
          type: string
          const: conversation
        conversation_id:
          type: string
          format: uuid
          description: The child conversation a scheduled task ran in. List its messages with the same endpoint.
        title:
          type: string
          description: The title of the scheduled task.
        created_at:
          type: string
          format: date-time

    Message:
      oneOf:
        - $ref: '#/components/schemas/UserMessage'
        - $ref: '#/components/schemas/AgentTextMessage'
        - $ref: '#/components/schemas/AgentFileMessage'
        - $ref: '#/components/schemas/AgentConversationMessage'

    MessagePage:
      type: object
      required: [data, links, meta]
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Message'
        links:
          type: object
          properties:
            first:
              type: [string, 'null']
            last:
              type: [string, 'null']
            prev:
              type: [string, 'null']
              description: Newer messages.
            next:
              type: [string, 'null']
              description: Older messages.
        meta:
          type: object
          properties:
            path:
              type: string
            per_page:
              type: integer
            next_cursor:
              type: [string, 'null']
            prev_cursor:
              type: [string, 'null']

    Attachment:
      type: object
      required: [id, type, name, mime_type, url, preview_url, download_url, expires_at]
      properties:
        id:
          type: string
        type:
          type: string
        name:
          type: string
        mime_type:
          type: string
        url:
          type: string
          format: uri
        preview_url:
          type: [string, 'null']
          format: uri
        download_url:
          type: [string, 'null']
          format: uri
        expires_at:
          type: [string, 'null']
          format: date-time

    Citations:
      type: array
      description: The web pages the agent cited in this reply, each once. Empty when it cited none, or when the agent's Show sources is off.
      items:
        type: object
        required: [url, title]
        properties:
          url:
            type: string
            format: uri
          title:
            type: [string, 'null']

    Reply:
      type: object
      required: [markdown, attachments, citations]
      properties:
        markdown:
          type: string
          description: The whole reply as Markdown. Shared files appear where they were written, images as images.
        attachments:
          type: array
          description: The files the agent shared in this reply.
          items:
            $ref: '#/components/schemas/Attachment'
        citations:
          $ref: '#/components/schemas/Citations'

    BufferedReply:
      type: object
      required: [data]
      properties:
        data:
          $ref: '#/components/schemas/Reply'

    Error:
      type: object
      required: [message]
      properties:
        message:
          type: string

    WalletError:
      type: object
      required: [message, code]
      properties:
        message:
          type: string
        code:
          type: string
          enum: [insufficient_credits, insufficient_minutes]

    ValidationError:
      type: object
      required: [message, errors]
      properties:
        message:
          type: string
        errors:
          type: object
          description: The messages for each invalid field.
          additionalProperties:
            type: array
            items:
              type: string

  examples:
    Conversation:
      value:
        data:
          id: 0199d2f4-0a1b-7c2d-8e3f-405162738495
          agent:
            id: 0199a1b2-c3d4-7e5f-8a9b-0c1d2e3f4a5b
            name: Ava
            title: Support Agent
          context:
            - label: Name
              description: The visitor's name
              value: Jane
            - label: Page
              description: Page the visitor is on
              value: /pricing
          created_at: '2026-10-13T08:00:00+00:00'
          _links:
            self:
              href: https://api.rundispatch.ai/v1/conversations/0199d2f4-0a1b-7c2d-8e3f-405162738495
            list_messages:
              href: https://api.rundispatch.ai/v1/conversations/0199d2f4-0a1b-7c2d-8e3f-405162738495/messages
            send_message:
              href: https://api.rundispatch.ai/v1/conversations/0199d2f4-0a1b-7c2d-8e3f-405162738495/messages
          _embedded:
            participants:
              - id: 0199e4a0-5b6c-7d8e-9f01-23456789abcd
                type: end_user
                name: Jane
                email: jane@example.com
                phone_number: '+639171234567'
                token: 8d1kQ2vX7bN4mR9tY3wZ6pL0sH5jF2cA
                token_expires_at: '2027-01-11T08:00:00+00:00'
    NotLive:
      summary: The agent is in draft
      value:
        message: This agent is not live.

  responses:
    Unauthenticated:
      description: The `Authorization` header is missing or its key or token is not valid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            unauthenticated:
              value:
                message: Unauthenticated.
    NotLive:
      description: The agent is in draft. It answers again once it goes live.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            notLive:
              $ref: '#/components/examples/NotLive'
    ApiKeyForbidden:
      description: The agent is in draft, or the API key is not allowed to start conversations with this agent.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            notLive:
              $ref: '#/components/examples/NotLive'
            notAllowed:
              summary: The key doesn't allow this agent
              value:
                message: This action is unauthorized.
    ParticipantForbidden:
      description: The token's visitor doesn't take part in this conversation, or the agent is in draft.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            notLive:
              $ref: '#/components/examples/NotLive'
            notParticipant:
              summary: The visitor doesn't take part in this conversation
              value:
                message: This action is unauthorized.
    InsufficientWallet:
      description: >-
        The workspace can't run the agent because a wallet is empty. `code` says which: `insufficient_credits` when the
        AI credits are used up, `insufficient_minutes` when the usage minutes are. The reply works again once the
        workspace tops up or its auto-reload lands.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/WalletError'
          examples:
            insufficientCredits:
              summary: Out of AI credits
              value:
                message: This workspace is out of credits.
                code: insufficient_credits
            insufficientMinutes:
              summary: Out of usage minutes
              value:
                message: Your workspace is out of usage minutes. Turn on usage auto-reload or upgrade your plan.
                code: insufficient_minutes
    NotFound:
      description: The agent or conversation doesn't exist, or your credential can't see it.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            notFound:
              value:
                message: Not Found
    ValidationFailed:
      description: The request is not valid. `errors` lists the messages for each field.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ValidationError'
          examples:
            invalid:
              value:
                message: The content field is required.
                errors:
                  content:
                    - The content field is required.
    TooManyRequests:
      description: More than 60 requests in a minute from the same IP address. Wait and try again.
      headers:
        Retry-After:
          description: Seconds to wait before trying again.
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            throttled:
              value:
                message: Too Many Attempts.
