Skip to Content
AgentsAgent Integration (Advanced)Chat Endpoint (Deprecated)

Chat Endpoint

Integrate applications, websites, and widgets with agents using the streaming chat endpoint.

Deprecated. The Chat Endpoint has been superseded by the unified Run Endpoint. Use POST /api/agents/{agentId}/run with "stream": true instead — the request and response formats are identical. This endpoint remains available for backward compatibility and responds with a Deprecation: true header.

Endpoint Overview

The Chat Endpoint enables applications, websites, widgets, and custom integrations to communicate with an agent through a real-time streaming interface.

Use this endpoint when you want live responses from an agent, including support for tool execution, reasoning, and streaming message updates.

PropertyValue
MethodPOST
Endpoint/api/agents/{agentId}/chat
Response TypeStreaming SSE
ProtocolAI SDK UI Message Stream
AuthenticationAuthorization (user JWT) or cf-api-key

This endpoint returns a streaming response and is optimized for chat experiences. It is not intended for traditional request/response JSON workflows.

Authentication

You can authenticate using a user session token or a scoped API key.

Authorization: Bearer <supabase_jwt>

Use for platform users with an active Supabase session.

Optional Headers

Pass x-agent-payload additional metadata to downstream MCP integrations.

x-agent-payload: {"x-user-id":"123","x-tenant-id":"acme"}
  • Must contain valid JSON.
  • Only string, number, and boolean values are preserved.
  • Unsafe headers such as authorization, host, and content-length are automatically removed before forwarding.

Request Body

The Chat Endpoint uses the AI SDK UI Message format.

Message Object

Every message contains an identifier, a role, and one or more content parts.

{ "id": "msg-1", "role": "user", "parts": [ { "type": "text", "text": "Hello" } ] }

Request Fields

FieldTypeRequiredDescription
messageUIMessageNoLatest user message
messagesUIMessage[]NoComplete conversation history
idstringNoConversation ID or client session ID
varsRecord<string, any>NoRuntime variables injected into the agent prompt
customToolsArrayNoRuntime-defined tools for advanced scenarios

A request must contain either message or messages.

Runtime Variables

Use the optional vars field to provide runtime values that can be referenced by agent prompts, workflows, or tools.

{ "vars": { "customerName": "My Customer", "bookingId": "BK-12345", "locale": "en-SG" } }

Common use cases include:

  • User identifiers
  • Customer information
  • Locale settings
  • Tenant identifiers
  • Business-specific context

Request Modes

The endpoint supports two conversation management modes depending on where conversation history is stored.

Server-Managed History

Use this mode when Chocolate Factory should automatically persist, retrieve, and manage conversation history on behalf of your application.

Your application sends only the latest user message. The platform automatically loads previous conversation history and provides the full context to the agent.

Recommended for:

  • Customer support assistants
  • Chatbots
  • Long-running conversations
  • Applications requiring persistent history

Request Example

{ "id": "existing-conversation-id", "message": { "id": "msg-2", "role": "user", "parts": [ { "type": "text", "text": "Show me the latest booking status" } ] }, "vars": { "bookingId": "BK-12345" } }

Client-Managed History

Use this mode when your application is responsible for storing and managing the complete conversation transcript.

The complete conversation history is included in each request. The platform uses the supplied messages as the conversation context and does not load historical messages from storage.

Recommended for:

  • AI SDK applications
  • Browser-based chat clients
  • Frontend-managed state
  • Applications that already persist conversation history

Request Example

{ "id": "client-chat-session-id", "messages": [ { "id": "msg-1", "role": "user", "parts": [ { "type": "text", "text": "Hello" } ] }, { "id": "msg-2", "role": "assistant", "parts": [ { "type": "text", "text": "Hi, how can I help?" } ] } ] }

The Chat Endpoint natively returns the AI SDK UI Message Stream format, making the AI SDK the recommended integration approach. Using the AI SDK provides several advantages:

  • Automatic stream handling
  • No manual SSE parsing
  • Built-in message state management
  • Native support for streaming UI updates
  • Consistent with Chocolate Factory reference implementations
"use client"; import { useChat } from "@ai-sdk/react"; import { DefaultChatTransport } from "ai"; const agentId = "YOUR_AGENT_ID"; export function ChatWidget() { const transport = new DefaultChatTransport({ api: `${process.env.NEXT_PUBLIC_APP_URL}/api/agents/${agentId}/chat`, headers: { "x-agent-key": "YOUR_AGENT_KEY", }, }); const { messages, sendMessage, status } = useChat({ transport, id: `chat-${agentId}`, }); return ( <div> <button onClick={() => sendMessage({ text: "Hello", metadata: { agentId }, }) } disabled={status !== "ready"} > Send </button> <pre>{JSON.stringify(messages, null, 2)}</pre> </div> ); }

Integration Without AI SDK

If you are not using the AI SDK, you can integrate with the endpoint using any HTTP client that supports streaming responses.

Send only the latest user message and allow the server to manage conversation persistence.

const agentId = "YOUR_AGENT_ID"; const response = await fetch(`/api/agents/${agentId}/chat`, { method: "POST", headers: { "Content-Type": "application/json", "x-agent-key": "YOUR_AGENT_KEY", }, body: JSON.stringify({ id: "optional-conversation-id", message: { id: `msg-${Date.now()}`, role: "user", parts: [{ type: "text", text: "Summarize this order for me" }], }, vars: { locale: "en-SG", }, }), }); if (!response.ok) { throw new Error(`Chat request failed: ${response.status}`); } const reader = response.body?.getReader(); const decoder = new TextDecoder(); if (!reader) { throw new Error("Missing response body"); } let rawStream = ""; while (true) { const { done, value } = await reader.read(); if (done) break; rawStream += decoder.decode(value, { stream: true }); } rawStream += decoder.decode(); console.log(rawStream);

Do not use response.json(). The endpoint returns a stream that must be consumed incrementally.

Success Responses

The Chat Endpoint streams returns a streaming response using the AI SDK UI Message Stream  protocol.

  • Return HTTP 200
  • Stream assistant responses incrementally
  • Emit AI SDK UI Message Stream events
  • May include metadata events
  • May include tool execution events
  • May include runtime information and annotations

If you require a traditional synchronous JSON response, this endpoint may not be the best fit. It is specifically designed for live conversational streaming.

Error Responses

StatusResponse
400{ "error": "Agent is not active" }
400{ "error": "Agent must belong to an organization" }
400{ "error": "No valid messages to process" }
401{ "error": "Unauthorized" }
403{ "error": "Forbidden" }
404{ "error": "Agent not found" }
500{ "error": "Internal server error" }

Best Practices

  • Prefer AI SDK for new chat applications.
  • Use Server-Managed History when conversation persistence should be handled by Chocolate Factory.
  • Use Client-Managed History when your application owns the complete conversation state.
  • Use x-agent-key for websites, embedded chat widgets, and external integrations.
  • Use vars to inject runtime context into prompts, workflows, or business-specific information.
  • Use x-agent-payload when MCP tools require additional contextual metadata.
  • Always process responses as streams rather than JSON payloads.
  • Reuse conversation IDs to maintain context across multiple user interactions.
Last updated on