Chat
SSE streaming chat endpoint with AI SDK compatibility. Send messages and receive streaming responses.
Send Message
Sends a message to the agent and returns an SSE stream of the response.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| slug | string | Required | Agent slug |
Request Body
| Name | Type | Required | Description |
|---|---|---|---|
| messages | Message[] | Required | AI SDK-style message array. The relay uses the last user message as the next turn. |
| sandboxId | string | Required | Sandbox ID returned by your server, for example the id from POST /v1/sandboxes |
| threadId | string | Optional | Thread ID to continue. If omitted, the latest thread in the sandbox is reused or created if none exists |
| options | object | Optional | Per-request runtime overrides |
| options.systemPrompt | object | Optional | System prompt override (type, preset, append) |
| options.maxTurns | number | Optional | Maximum number of agent turns |
| options.maxBudgetUsd | number | Optional | Maximum cost in USD for this request |
| options.disallowedTools | string[] | Optional | Tools the agent cannot use |
sandboxId + threadId: continue a specific thread in that sandbox.
sandboxId only: reuse the latest thread in the sandbox. If none exists yet, a new thread is created.
Need a fresh conversation in the same sandbox: create a new thread explicitly via /v1/sandboxes/:id/threads and send that threadId.
No sandboxId: returns a 400 error.
History persistence: the relay appends only the new turn to stored thread history. It does not replace thread history with the full request body.
{
"sandboxId": "uuid-of-existing-sandbox",
"options": {
"systemPrompt": {
"type": "preset",
"preset": "claude_code",
"append": "Focus on regressions, risky edge cases, and missing tests. Do not edit files."
},
"maxTurns": 4,
"maxBudgetUsd": 0.2,
"disallowedTools": ["Bash"]
},
"messages": [
{
"id": "msg-1",
"role": "user",
"parts": [{ "type": "text", "text": "Your message" }]
}
]
}curl -N -X POST https://relay.an.dev/v1/chat/YOUR_AGENT_SLUG \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"sandboxId": "uuid-of-existing-sandbox",
"messages": [{
"id": "msg-1",
"role": "user",
"parts": [{ "type": "text", "text": "Hello" }]
}]
}'SSE Response Format
The response is a Server-Sent Events stream. Each event is a JSON object prefixed with data: . The stream ends with data: [DONE].
data: {"type":"start"}
data: {"type":"text-start","id":"..."}
data: {"type":"text-delta","id":"...","delta":"Hello world"}
data: {"type":"text-end","id":"..."}
data: {"type":"message-metadata","messageMetadata":{
"sessionId":"...",
"totalCostUsd":0.034,
"inputTokens":3,
"outputTokens":5,
"durationMs":2487
}}
data: {"type":"finish"}
data: [DONE]Resume Stream
Reconnect to an active SSE stream for a sandbox. Use this when a client connection drops and you need to resume receiving events.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| slug | string | Required | Agent slug |
| sandboxId | string | Required | Sandbox ID |
Cancel Stream
Cancel an active stream. Use this for deterministic server-side cancellation.
Path Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| slug | string | Required | Agent slug |
| sandboxId | string | Required | Sandbox ID |
Returns 204 No Content on success.
React (AI SDK)
Direct usage with AI SDK — useful for custom transports or non-Next.js frameworks.
import { Chat, DefaultChatTransport } from "ai"
import { useChat } from "@ai-sdk/react"
const sandboxId = "sb_abc123" // Use the sandbox ID returned by your server
const chat = new Chat({
transport: new DefaultChatTransport({
api: "https://relay.an.dev/v1/chat/YOUR_AGENT_SLUG",
headers: async () => ({
Authorization: "Bearer YOUR_API_KEY",
}),
body: {
sandboxId,
// threadId: "uuid-of-existing-thread",
},
}),
})
export function AgentChat() {
const { messages, sendMessage } = useChat({ chat })
return (
<div>
{messages.map((m) => <div key={m.id}>{m.content}</div>)}
<button onClick={() => sendMessage({ text: "Hello" })}>
Send
</button>
</div>
)
}SDK Integration
@21st-sdk/nextjs with server-side token exchange, see the Get Started guide. For server-side sandbox and thread management, see the Server SDK page.