---
title: "Stream Chat"
method: POST
path: "/chat"
tags: ["Chat"]
---

# Stream Chat

`POST /chat`

Start a streaming chat session with the Greenflash AI agent.

**Requires a Growth or Enterprise plan.**

The response is a Server-Sent Events (SSE) stream (`Content-Type: text/event-stream`).
Each event follows the format:

```
event: <type>
data: <json>
```

**Event types:**
- `tool_call` — The agent is invoking a tool. Data: `{"step": 1, "toolName": "...", "displayName": "..."}`
- `tool_result` — A tool returned its result. Data: `{"step": 1, "toolName": "...", "displayName": "..."}`. For `draftTicket` and `createTicket`, the event also includes an `output` field with the tool's payload (see *Ticket creation* below).
- `text_delta` — A chunk of the agent's text response. Concatenate all deltas to build the full message. Data: `{"text": "..."}`
- `done` — The stream completed successfully. Data: `{"conversationId": "...", "status": "complete", "usage": {"toolCalls": N, "tools": ["..."]}}`
- `error` — An error occurred during processing. Data: `{"error": "...", "code": "..."}`

**Multi-turn conversations:** Pass previous messages in the `messages` array and reuse the `conversationId` returned in the `done` event.

**Rate limits:** This endpoint is rate-limited per tenant (requests/hour) and subject to token usage limits.

### Ticket creation (two-step draft → confirm)

When the tenant has an active ticket-provider connection (e.g. Linear), the agent may emit a `draftTicket` tool call. The `tool_result` event includes an `output` field shaped like:

```json
{
  "step": 2,
  "toolName": "draftTicket",
  "displayName": "Drafting ticket",
  "output": {
    "draft": {
      "provider": "linear",
      "title": "Billing page 500 for enterprise users",
      "description": "...",
      "target": { "teamId": "t_123", "teamName": "Core", "teamKey": "CORE" },
      "labelIds": ["lbl_bug"],
      "source": { "type": "conversation", "conversationId": "conv-abc-123" }
    },
    "availableLabels": [
      { "id": "lbl_bug", "name": "bug", "color": "#f00" }
    ],
    "dedupWarning": null
  }
}
```

API consumers should render this draft to the end user. To confirm (optionally with edits), send a follow-up user message asking the agent to call `createTicket` with the final payload. The `createTicket` `tool_result` event contains:

```json
{
  "step": 3,
  "toolName": "createTicket",
  "displayName": "Creating ticket",
  "output": {
    "status": "created",
    "providerIdentifier": "LIN-99",
    "providerTicketUrl": "https://linear.app/acme/issue/LIN-99"
  }
}
```

`status` is `"created"` on success, `"already_exists"` when deduplication matched an existing ticket (the existing `providerIdentifier` / `providerTicketUrl` are returned), or the event may carry an `error` field (e.g. `"provider_needs_setup"`).

## Request body

- StreamChatRequest
  - `question` string, required — The current user question to send to the AI agent.
  - `messages` object[] — Prior conversation history (NOT including the current question). Used for multi-turn context.
    - `role` 'user' | 'assistant', required — The role of the message sender.
    - `content` string, required — The text content of the message.
  - `conversationId` string — Stable identifier for multi-turn conversations. If omitted, a new ID is generated.
  - `context` string — Free-form hint injected into the system prompt for this turn only.
  - `productId` string, uuid — Scope the chat to a specific product. If omitted, the agent can access all products.

## Response `200`

SSE stream of chat events (text/event-stream). See endpoint description for event format.

**Example SSE stream:**
```
event: tool_call
data: {"step":1,"toolName":"getConversations","displayName":"Searching conversations"}

event: tool_call
data: {"step":2,"toolName":"getUserRanking","displayName":"Ranking users by metrics"}

event: tool_result
data: {"step":1,"toolName":"getConversations","displayName":"Searching conversations"}

event: tool_result
data: {"step":2,"toolName":"getUserRanking","displayName":"Ranking users by metrics"}

event: text_delta
data: {"text":"Based on your"}

event: text_delta
data: {"text":" conversation data, the top complaints"}

event: text_delta
data: {"text":" from enterprise customers this week are..."}

event: done
data: {"conversationId":"conv-abc-123","status":"complete","usage":{"toolCalls":2,"tools":["getConversations","getUserRanking"]}}
```

## Other responses

- `400` — Bad request — invalid or missing parameters
- `403` — Forbidden — requires a Growth or Enterprise plan
- `429` — Rate limit or token usage limit exceeded
- `500` — Server error

## Changes

- **2026-05-01** `f52e699d4abf` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/greenflash-ai/apis/greenflash-api-reference/changes/chat/post.md)

---

[API](https://skmtc.dev/greenflash-ai/apis/greenflash-api-reference.md) · [All operations](https://skmtc.dev/greenflash-ai/apis/greenflash-api-reference/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/greenflash-ai/greenflash-api-reference/revisions/c566e560677d/schema)
