> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sidenet.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Stream chat

> Build and stream responses from an agent or network of agents. Provide either agentId or copilotId (the id of a network).

Authenticate with a session token (`snat_…`) minted by POST /v1/token on your backend. The session already carries the organization and the end user, so no identity headers are needed — send nothing but `Authorization`.

Your organization API key must never reach a browser; it is what mints the session, server-side.



## OpenAPI

````yaml /api-reference/openapi.json post /v1/chat
openapi: 3.1.0
info:
  title: Sidenet API
  version: 1.0.0
  description: >-
    Sidenet HTTP endpoints exposed by the Sidenet Studio. All routes require an
    api key that can be generated through the studio in studio.sidenet.ai.
servers:
  - url: https://api.sidenet.ai
security:
  - bearerAuth: []
paths:
  /v1/chat:
    post:
      tags:
        - Chat
      summary: Stream chat
      description: >-
        Build and stream responses from an agent or network of agents. Provide
        either agentId or copilotId (the id of a network).


        Authenticate with a session token (`snat_…`) minted by POST /v1/token on
        your backend. The session already carries the organization and the end
        user, so no identity headers are needed — send nothing but
        `Authorization`.


        Your organization API key must never reach a browser; it is what mints
        the session, server-side.
      parameters: []
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                messages:
                  type: array
                  default: []
                  description: >-
                    The conversation, in AI SDK UIMessage format: `[{ "role":
                    "user", "parts": [{ "type": "text", "text": "..." }] }]`.
                    Send the whole exchange you want the agent to see; with a
                    `threadId` the stored history is loaded too, so the new turn
                    is usually the only entry. May be empty only on an
                    `approval` continuation.
                  example:
                    - role: user
                      parts:
                        - type: text
                          text: Where is my order?
                approval:
                  type: object
                  properties:
                    runId:
                      type: string
                      minLength: 1
                      description: runId from the data-tool-call-approval chunk
                    toolCallId:
                      type: string
                      minLength: 1
                      description: >-
                        Disambiguates when multiple tool calls are pending;
                        defaults to the most recent
                    approved:
                      type: boolean
                      description: true = run the tool, false = decline it
                  required:
                    - runId
                    - approved
                  additionalProperties: false
                  description: >-
                    Approve or decline a tool call that paused the previous
                    stream
                  example:
                    runId: run_6d20a95c
                    toolCallId: call_a17f3b
                    approved: true
                agentId:
                  type: string
                  description: Agent id — runs the agent's active published version
                  example: 6f1c0f4e-2b7a-4a51-9a2f-0c9d1b3e5a10
                agentVersionId:
                  type: string
                  description: >-
                    Optional override: run a specific agent version (e.g.
                    preview a draft or an earlier published version) instead of
                    the active one
                  example: b3f7a2c8-5d19-4e6b-8f02-1a4c9e7d3b55
                copilotId:
                  type: string
                  description: Network id to route through (alternative to agentId)
                  example: a5e91c07-3f24-4b68-9d15-8c72e0b4a396
                threadId:
                  type: string
                  description: Conversation thread id
                  example: thread_2f81c04a
                context:
                  type: array
                  items:
                    type: string
                  description: Additional context messages to provide to the agent.
                  example:
                    - The customer is on the enterprise plan.
                variables:
                  type: object
                  additionalProperties: {}
                  description: >-
                    Values for {{variable}} placeholders in the agent's prompt
                    blocks. Scalars (string, number, boolean) or arrays of them.
                    A dot path up to 3 segments may be sent nested or as a
                    dotted key — `{ "user": { "language": "FR" } }` and `{
                    "user.language": "FR" }` both fill `{{user.language}}`. This
                    is the shape `GET /v1/copilots/{id}` and `GET
                    /v1/agents/{id}` return under `variables`: fill in the
                    leaves you have and send the object back. A null leaf is
                    ignored (the placeholder falls back to its own default), so
                    leaving one unfilled is the same as omitting it.
                    Display-only — never used for authorization or identity.
                    Reserved: `now.*`. Entries with an unsupported key or value
                    are dropped, not rejected: a display-only field must not
                    fail a chat turn.
                  example:
                    locale: English
                    instance:
                      store_count: 12
                trigger:
                  type: string
                  enum:
                    - submit-message
                    - regenerate-message
                  description: AI SDK trigger type
                tools:
                  type: object
                  additionalProperties: {}
                  description: AI SDK client-side tools
                  example:
                    Acme_CRM_get_customer:
                      enabled: true
                metadata:
                  type: object
                  additionalProperties: {}
                  description: AI SDK session metadata
                  example:
                    source: web-widget
                use_routing:
                  type: boolean
                  default: true
                  description: >-
                    Default true. When the request targets an orchestrator
                    agent, routing picks whether to stream the orchestrator
                    (multi-step / synthesis) or a single subagent directly
                    (domain-specific ask). No effect when the resolved agent is
                    not an orchestrator. Pass false to disable.
                suggest_followups:
                  type: boolean
                  default: true
                  description: >-
                    Default true. After the answer finishes streaming, a small
                    model proposes up to 3 questions the user could ask next,
                    emitted as a `data-followups` chunk for the client to render
                    as chips. Costs one extra model call per turn and holds the
                    stream open slightly longer — pass false to disable. Only
                    applies to copilotId requests: an agentId run has no UI to
                    render chips into, so suggestions never run there.
              additionalProperties: false
      responses:
        '200':
          description: AI SDK v6 UIMessageStream response
          content:
            text/event-stream:
              schema:
                type: string
        '400':
          description: Bad request - missing required fields
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  details:
                    type: string
        '404':
          description: Agent version not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  details:
                    type: string
        '429':
          description: Usage limit exceeded
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  message:
                    type: string
                  details:
                    type: object
                    properties:
                      currentUsage:
                        type: number
                      limit:
                        type: number
                      groupLimitRemaining:
                        type: number
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                  details:
                    type: string
      security:
        - sessionToken: []
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        Organization API key, generated in studio.sidenet.ai. Backend only —
        never in a browser.
    sessionToken:
      type: http
      scheme: bearer
      description: >-
        Session token (`snat_…`) minted by POST /v1/token. Carries the
        organization and the end user; safe in a browser.

````