Skip to Content

Run Endpoint

Invoke an agent through the unified run endpoint, with streaming or JSON responses.

Endpoint Overview

The Run Endpoint is the single entry point for invoking an agent over HTTP. It replaces the deprecated Chat and Execute endpoints.

The stream field in the request body selects the response mode:

  • stream: true — real-time streaming response (AI SDK UI Message Stream over SSE), equivalent to the old Chat Endpoint.
  • stream: false (default) — a single JSON response with text, usage, and finishReason, equivalent to the old Execute Endpoint.
PropertyValue
MethodPOST
Endpoint/api/agents/{agentId}/run
Response TypeJSON (default) or Streaming SSE (stream: true)
AuthenticationAuthorization (user JWT) or cf-api-key

Both modes invoke the same agent configuration, including its model, system prompt, tools, and knowledge sources.

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

Request Fields

FieldTypeRequiredDescription
streambooleanNotrue for a streaming SSE response, false (default) for a single JSON response
messagestring or UIMessageNoLatest user message. Plain strings are wrapped into a user message automatically
messagesUIMessage[]NoComplete conversation history (client-managed mode)
idstringNoConversation ID or client session ID
varsRecord<string, any>NoRuntime variables injected into the agent prompt
customToolsArrayNoRuntime-defined tools for advanced scenarios

In non-streaming mode, both message and messages may be omitted — the agent runs from its rendered system prompt and the supplied vars (template-driven execution). In streaming mode, provide either message or messages.

Message Object

Structured messages use the AI SDK UI Message format.

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

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" } }

Non-Streaming Mode (default)

With stream omitted or set to false, the endpoint executes the agent synchronously and returns a single JSON payload.

Use non-streaming mode when:

  • You want a simple request/response integration.
  • You are generating content from prompt templates and variables.
  • You are calling agents from forms, backend services, scheduled jobs, or workflows.

Request Example

{ "message": "Write a product announcement email", "vars": { "productName": "Chocolate Factory AI", "audience": "existing customers" } }

Template-Driven Execution

If your agent already contains a prompt template that expects variables, you can run the agent using only vars — no message required.

{ "vars": { "title": "AI in logistics", "tone": "professional", "keywords": "automation, supply chain, forecasting" } }

Response Fields

FieldTypeDescription
textstringGenerated output from the agent
usageobjectToken usage information
finishReasonstringReason generation stopped
conversationIdstring | nullConversation ID when server-managed history is used

Response Example

{ "text": "Generated output from the agent", "usage": { "inputTokens": 123, "outputTokens": 456, "totalTokens": 579 }, "finishReason": "stop", "conversationId": null }

Streaming Mode

With stream: true, the endpoint returns a streaming response using the AI SDK UI Message Stream  protocol over SSE.

Use streaming mode when:

  • You are building chat widgets, copilots, or multi-turn conversational UIs.
  • You want live responses including tool execution, reasoning, and incremental message updates.

Conversation Management Modes

Streaming requests support two history modes:

  • Server-Managed History — send only the latest message plus an optional conversation id; the platform loads and persists history automatically. The first response returns an X-Conversation-Id header.
  • Client-Managed History — send the complete messages array with each request; nothing is stored server-side.

The streaming mode natively returns the AI SDK UI Message Stream format, making the AI SDK the recommended integration approach.

"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}/run`, headers: { "cf-api-key": "YOUR_API_KEY", }, body: { stream: true, }, }); 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> ); }

In streaming mode, do not use response.json(). The endpoint returns a stream that must be consumed incrementally.

Integration Examples

The most common request/response integration pattern.

const agentId = "YOUR_AGENT_ID"; const response = await fetch(`/api/agents/${agentId}/run`, { method: "POST", headers: { "Content-Type": "application/json", "cf-api-key": "YOUR_API_KEY", }, body: JSON.stringify({ message: "Write a product announcement email", vars: { productName: "Chocolate Factory AI", audience: "existing customers", tone: "friendly", }, }), }); if (!response.ok) { const errorBody = await response.text(); throw new Error(`Run request failed: ${response.status} ${errorBody}`); } const data = await response.json(); console.log(data.text); console.log(data.usage); console.log(data.finishReason);

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" }

Migrating from /chat and /execute

The deprecated endpoints remain available as thin wrappers around /run and respond with a Deprecation: true header.

Old endpointReplacement
POST /api/agents/{agentId}/chatPOST /api/agents/{agentId}/run with "stream": true
POST /api/agents/{agentId}/executePOST /api/agents/{agentId}/run (default "stream": false)

Request and response formats are unchanged — only the URL and the stream field differ.

Best Practices

  • Use streaming mode for conversational UIs; use non-streaming mode for forms, content generation, workflows, and backend jobs.
  • Use Server-Managed History when conversation persistence should be handled by Chocolate Factory.
  • Use vars to inject runtime context into prompts, workflows, or business-specific information.
  • Use x-agent-payload when MCP tools require additional contextual metadata.
  • Reuse conversation IDs to maintain context across multiple user interactions.
  • Inspect the usage object to monitor token consumption.
Last updated on