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

# Chat (Streaming)

> POST /api/sdk/chat/stream -- Send a message and receive a streaming AI response.

## Endpoint

```
POST /api/sdk/chat/stream
```

Same as the [Chat](https://docs.haloagents.ai/api-reference/chat.md) endpoint, but returns a streaming text response for progressive rendering. The widget uses this endpoint by default.

## Authentication

Requires your publishable widget key in the `Authorization` header:

```
Authorization: Bearer ab_live_xxxxxxxxxxxxxxxx
```

## Request Body

The request body is identical to the [Chat](https://docs.haloagents.ai/api-reference/chat.md) endpoint. All the same fields are accepted: `message`, `user_id`, `user_token`, `session_id`, `company_id`, `context`, `custom_fields`, `conversation_history`, `behavior_context`, and `mode`.

## Response

The response is a chunked `text/plain; charset=utf-8` stream. Read it like a regular `ReadableStream` and append chunks as they arrive. The full text accumulates over the stream.

Action payloads (highlights, ticket creation, etc.) are interleaved in the stream as records framed by the ASCII record-separator character (`\x1E`):

```
\x1E__ACTION__<json>\x1E       (per-action, emitted as it resolves)
\x1E__ACTIONS__<json-array>\x1E (final summary at end of stream)
```

If you only need the assistant's text, strip any substring matching `\x1E__ACTION(S)?__...\x1E` from each chunk before rendering. The widget SDK does this for you.

### Response Headers

The stream response includes metadata in custom headers:

| Header | Description |
| - | - |
| `X-Session-Id` | The session ID for this conversation. Use this to continue the conversation in subsequent requests. |
| `X-Agent-Id` | The ID of the agent handling the request. |

Transcripts are stored asynchronously after the stream completes.

## Example

```typescript theme={null}
const response = await fetch("https://api.haloagents.ai/api/sdk/chat/stream", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Authorization": "Bearer ab_live_xxxxxxxxxxxxxxxx",
  },
  body: JSON.stringify({
    user_id: "user_123",
    message: "How do I set up event tracking?",
  }),
});

// Read metadata from response headers
const sessionId = response.headers.get("X-Session-Id");
const agentId = response.headers.get("X-Agent-Id");

const reader = response.body?.getReader();
const decoder = new TextDecoder();
let fullText = "";

while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  const chunk = decoder.decode(value, { stream: true });
  fullText += chunk;
  // Update your UI with the partial response
  updateChatBubble(fullText);
}
```

## When to Use Streaming vs Non-Streaming

| Use Case | Endpoint |
| - | - |
| Chat widget (real-time UX) | `/chat/stream` |
| Server-side integrations | `/chat` |
| Webhooks / async processing | `/chat` |
| Mobile apps with progressive display | `/chat/stream` |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.