Skip to content

Chat API

The Chat API sends messages to the NimbleBrain agent and receives responses. Two endpoints are available: a synchronous endpoint that returns the full response, and a streaming endpoint that delivers events over SSE as the agent works.

Send a message and receive the complete response when the agent finishes. This endpoint blocks until the agent completes all iterations, including any tool calls.

Request body:

FieldTypeRequiredDescription
messagestringYesThe user message to send
conversationIdstringNoContinue an existing conversation. Omit to start a new one.
modelstringNoOverride the default model for this request
appContextobjectNoScope the chat to a specific app (see below)

The appContext object:

FieldTypeDescription
appNamestringName of the installed app
serverNamestringMCP server name backing the app

Response:

{
"response": "The current weather in San Francisco is 62°F with partly cloudy skies.",
"conversationId": "conv_a1b2c3d4",
"skillName": null,
"toolCalls": [
{
"id": "tc_x7y8z9",
"name": "weather__get_forecast",
"input": { "city": "San Francisco" },
"output": "{\"temp\":62,\"condition\":\"partly cloudy\"}",
"ok": true,
"ms": 340
}
],
"inputTokens": 1250,
"outputTokens": 45,
"stopReason": "end_turn",
"usage": {
"inputTokens": 1250,
"outputTokens": 45,
"cacheCreationTokens": 0,
"cacheReadTokens": 980,
"costUsd": 0.0042,
"model": "claude-sonnet-4-5-20250929",
"llmMs": 1820,
"iterations": 2
}
}

Response fields:

FieldTypeDescription
responsestringThe agent’s text response
conversationIdstringThe conversation ID (new or existing)
skillNamestring | nullMatched skill name, or null if none matched
toolCallsarrayTool calls made during this turn
inputTokensnumberTotal input tokens consumed
outputTokensnumberTotal output tokens generated
stopReasonstringWhy the agent stopped: "end_turn", "token_budget", "max_iterations"
usageobjectDetailed usage breakdown including cache tokens, cost, and timing

Error responses:

StatusCondition
400Missing or non-string message field
400Invalid JSON body
401Not authenticated

Example:

Terminal window
curl -X POST http://localhost:3000/v1/chat \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-secret-key" \
-d '{
"message": "What is the weather in San Francisco?",
"conversationId": "conv_a1b2c3d4"
}'

Send a message and receive events over SSE as the agent works. The request body is identical to POST /v1/chat.

The response has Content-Type: text/event-stream. Each event follows the SSE format:

event: <type>
data: <json>

A chunk of the agent’s text response. Concatenate all text.delta payloads to build the full response.

event: text.delta
data: {"runId":"run_abc123","text":"The current weather"}
FieldTypeDescription
runIdstringUnique identifier for this agent run
textstringText fragment to append

The agent is calling a tool. Fired before the tool executes.

event: tool.start
data: {"runId":"run_abc123","name":"weather__get_forecast","id":"tc_x7y8z9","resourceUri":"ui://weather/dashboard"}
FieldTypeDescription
runIdstringUnique identifier for this agent run
namestringFully qualified tool name (server__tool)
idstringTool call ID
resourceUristring?UI resource URI, if the tool’s app has one

A tool call completed.

event: tool.done
data: {"runId":"run_abc123","name":"weather__get_forecast","id":"tc_x7y8z9","ok":true,"ms":340,"result":"{\"temp\":62}"}
FieldTypeDescription
runIdstringUnique identifier for this agent run
namestringFully qualified tool name
idstringTool call ID
okbooleanWhether the tool succeeded
msnumberExecution time in milliseconds
resourceUristring?UI resource URI, if applicable
resultstring?Tool result content

The agent finished. The payload contains the full ChatResult, identical to the synchronous POST /v1/chat response.

event: done
data: {"response":"The current weather...","conversationId":"conv_a1b2c3d4","skillName":null,"toolCalls":[...],"inputTokens":1250,"outputTokens":45,"stopReason":"end_turn","usage":{...}}

An error occurred during processing. The stream closes after this event.

event: error
data: {"error":"Model returned an empty response"}
FieldTypeDescription
errorstringError message
Terminal window
curl -X POST http://localhost:3000/v1/chat/stream \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-secret-key" \
-d '{"message": "What is 2 + 2?"}' \
--no-buffer