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

# Stream message

> Send a message and receive the AI reply as a stream of events.

Same behaviour as [Send message](/api-reference/vouch-ai/send-message), but the AI reply is streamed back token-by-token for real-time rendering. The user message and the final AI message are still persisted to the chat.

<Note>
  Requires a positive wallet balance. Billed at ₦100 per 1,000 tokens consumed by the request, and rate limited to 10 AI requests per minute.
</Note>

## Path parameters

<ParamField path="chatId" type="string" required>
  The chat session ID.
</ParamField>

## Body

<ParamField body="message" type="string" required>
  Your message, 1–4000 characters.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -N -X POST https://api.vouchmark.com/v1/chat/chat_aBcD.../stream \
    -H "Authorization: Bearer $TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"message": "Summarise my monitoring alerts from last week"}'
  ```
</RequestExample>

## Response format

The response is sent with `Content-Type: application/x-ndjson`. The body is a sequence of newline-delimited JSON objects, one per line. Each object has the shape `{ "type": <string>, "data": <any> }`. This is NDJSON, not Server-Sent Events, so read it with a streaming body reader rather than `EventSource`:

```
{"type":"text","data":"Based on"}
{"type":"text","data":" your monitoring"}
{"type":"text","data":" data from the past week..."}
{"type":"grounding_sources","data":{"groundingChunks":[{"web":{"uri":"https://...","title":"FIRS"}}]}}
{"type":"finish","data":{"complete":true}}
```

### Event types

| `type`              | `data`                                   | Description                                                                          |
| ------------------- | ---------------------------------------- | ------------------------------------------------------------------------------------ |
| `text`              | string                                   | A text fragment of the reply. Concatenate all `text` events for the full message.    |
| `tool_call`         | `{ toolName, args }`                     | The AI invoked a tool (e.g. web search) mid-response. Informational.                 |
| `grounding_sources` | `{ groundingChunks, searchEntryPoint? }` | Sources used to ground the answer. Emitted once, before `finish`, only when present. |
| `finish`            | `{ complete: true }`                     | The stream is complete.                                                              |
| `error`             | `{ message }`                            | An error occurred mid-stream. The connection then closes.                            |

## Client example

```ts theme={null}
const response = await fetch(`/v1/chat/${chatId}/stream`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${token}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ message: "..." }),
});

const reader = response.body!.getReader();
const decoder = new TextDecoder();
let buffer = "";

while (true) {
  const { done, value } = await reader.read();
  if (done) break;

  buffer += decoder.decode(value, { stream: true });
  const lines = buffer.split("\n");
  buffer = lines.pop() ?? "";

  for (const line of lines) {
    if (!line.trim()) continue;
    const event = JSON.parse(line);
    if (event.type === "text") {
      appendToUI(event.data);
    }
  }
}
```
