---
title: "Send a CPA chat message and receive Server-Sent Events as the turn progresses."
method: POST
path: "/internal/api/cpa-chat/messages/stream"
tags: ["CPA CHAT"]
---

# Send a CPA chat message and receive Server-Sent Events as the turn progresses.

`POST /internal/api/cpa-chat/messages/stream`

## Request

- Base URL: `https://api.signalshq.io` (the document declares no server; this is the origin it was published from)
- URL: `https://api.signalshq.io/internal/api/cpa-chat/messages/stream`
- Auth: OAuth 2
  - Password
  - Token URL: `/auth/login`

Stream the agent's thinking as Server-Sent Events.

Event types (each ``data:`` line is a JSON object with a ``type`` field):

- ``iteration``     — top of each agent loop iteration: ``{iteration, max_iterations}``
- ``progress``      — tool dispatch started: ``{tool, stage, tool_use_id}``
- ``tool_complete`` — tool finished: ``{tool, status, elapsed_ms, tool_use_id}``
- ``text_delta``    — assistant text token: ``{text}``
- ``done``          — turn done; carries cumulative ``{usage}``
- ``result``        — terminal payload (full ``SendMessageResponse`` shape)
- ``error``         — turn failed; carries ``{message}``

The browser opens an EventSource and renders each event as it arrives.

## Request body

- SendMessageRequest: Body for POST /internal/api/cpa-chat/messages. ``tenant_id`` and ``cpa_user_id`` are derived server-side from the JWT bearer token and are intentionally not part of this payload. Clarification-reply fields (``selected_option_id``, ``expected_clarification_version``) are optional and additive. When the server-side conversation state is ``AWAITING_CLARIFICATION``, the router dispatches to ``Agent.resolve_clarification`` regardless of whether ``selected_option_id`` was supplied; the agent treats option-id absence as a "free-text reply" path.
  - `client_id` string, uuid, required
  - `tax_year` integer
  - `message` string, required: Free-text user message.
  - `selected_option_id` string, nullable: When the prior turn was a ClarificationRequest, the id of the option the CPA picked. Mutually compatible with ``message`` (free-text addendum).
  - `expected_clarification_version` integer, nullable: Monotonic clarification version the client expects to resolve. If the server's version is higher, another caller (e.g. second browser tab) already resolved the pending clarification — the router returns 409 ``StaleClarificationReply``.

## Response `200`

Successful Response

- unknown

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/signalshq/apis/signals-api.md) - [All operations](https://skmtc.dev/signalshq/apis/signals-api/llms.txt) - [OpenAPI document](https://skmtc.dev/signalshq/apis/signals-api/revisions/2c22af3b5576?raw)
