Chat API
Endpoints for sending messages and receiving streaming responses. See API Conventions for authentication and error format.
POST /api/chat
Send a message and receive a streaming response.
Request
POST /api/chat
Content-Type: application/json
Authorization: Bearer <token>{
"parts": [{ "type": "text", "text": "Hello" }],
"threadId": "abc123"
}To include file attachments, add file parts alongside the text. Files must be sent as data URLs:
{
"parts": [
{ "type": "text", "text": "What's in this image?" },
{ "type": "file", "mediaType": "image/png", "url": "data:image/png;base64,...", "filename": "photo.png" }
],
"threadId": "abc123"
}| Field | Type | Required | Description |
|---|---|---|---|
parts | ContentPart[] | Yes | User message parts — see request parts. At minimum one text part. |
threadId | string | No | Thread to continue. Omit to start a new conversation (server generates a UUID). |
Response
Status 200 — Server-Sent Events (SSE) stream.
Headers:
| Header | Description |
|---|---|
Content-Type | text/event-stream |
X-Thread-Id | The thread ID. Always present — read this when creating new threads. |
The stream body is a UIMessageStream delivering response parts (text, tool calls, reasoning, citations, etc.). AI SDK client libraries can consume it directly.
Errors
| Status | Format | Cause |
|---|---|---|
400 | JSON { "error": "parts must be a non-empty array" } | parts is missing, empty, or not an array |
500 | JSON { "error": "<message>" } | AI or provider failure (unsupported file type, rate limit, etc.) |
POST /api/chat/approve
Approve or deny a pending tool call. When a tool requires user approval, the stream pauses and the tool part enters the approval-requested state. Use this endpoint to resume.
Request
POST /api/chat/approve
Content-Type: application/json
Authorization: Bearer <token>{
"runId": "run-abc123",
"toolCallId": "tc-456",
"approved": true,
"threadId": "thread-789",
"messageId": "msg-012"
}| Field | Type | Required | Description |
|---|---|---|---|
runId | string | Yes | The suspended run ID |
threadId | string | Yes | The thread containing the pending tool call |
toolCallId | string | No | The specific tool call to approve/deny |
approved | boolean | No | true to approve, false to deny. Defaults to undefined. |
messageId | string | No | The message containing the tool call |
Response
Status 200 — Server-Sent Events (SSE) stream, same format as POST /api/chat.
Errors
| Status | Format | Cause |
|---|---|---|
400 | JSON { "error": "runId and threadId are required" } | Missing required fields |
500 | JSON { "error": "<message>" } | AI or provider failure |
GET /api/chat/:threadId/stream
Reconnect to an in-progress stream. This is the server-side half of the AI SDK resumable streams protocol.
GET /api/chat/:threadId/stream
Authorization: Bearer <token>| Status | Meaning |
|---|---|
200 | Active stream found — returns buffered SSE stream from current position |
204 | No active stream (already finished, or serverless mode) |
The server buffers each SSE stream in memory so clients can reconnect mid-stream. Buffers are cleaned up 60 seconds after the stream completes. In serverless mode (e.g. Cloudflare Workers), this endpoint always returns 204.
SDK Types
These types are available from @pandorakit/sdk/client:
import type { ChatSendInput, ChatApproveInput } from '@pandorakit/sdk/client'See SDK Client for the typed client that wraps these endpoints.