API reference
POST /v1/chat/stream
The chat endpoint field by field: request body, limits, what the agent does with each request and how the streamed reply ends.
Reference2 min readUpdated 23 October 2026
Send one user message to one agent and read the reply as server-sent events. This is the only chat endpoint: replies are always streamed.
curl -N https://api.sentientone.ai/v1/chat/stream \ -H "Content-Type: application/json" \ -H "X-Api-Key: $SENTIENTONE_API_KEY" \ -H "X-Agent-Id: $AGENT_ID" \ -d '{"message": "Where is order 10482?"}'Request body
| Field | Type | Notes |
|---|---|---|
message | string, required | The user's message, up to 32,000 characters. Empty: 400 MISSING_MESSAGE. Too long: 422 VALIDATION_ERROR |
conversation_id | string, optional | Continue an earlier conversation (from meta or done). Omit it to start a new one |
agent_id | string, optional | Used only when the X-Agent-Id header is absent |
prompt | string, optional | Replaces the agent's system prompt for this request only, up to 32,000 characters. Handy for testing a prompt change |
allow_unpublished | boolean, default false | Lets a paused agent answer, for testing |
There are no history, metadata or stream fields. History is kept on the server: send the conversation_id and the agent sees the earlier turns.
Response
On success the status is 200 with Content-Type: text/event-stream, plus X-Trace-Id, X-Request-Id and the X-RateLimit-* headers. Each event is a data: line holding a JSON object with a type. The stream always starts with meta and ends with exactly one of done or error.
data: {"type": "meta", "conversation_id": "9b1c…", "trace_id": "4f2a9c1e…"}data: {"type": "sources", "sources": [{"index": 1, "id": "…", "title": "Shipping policy", "url": "https://example.com/shipping", "filename": null, "source_type": "web", "score": 0.82, "snippet": "Orders leave our warehouse…"}]}data: {"type": "tool_call", "id": "call_1", "name": "get_order", "input": {"order_id": "10482"}}data: {"type": "tool_result", "id": "call_1", "name": "get_order", "output": "{\"status\": \"shipped\"}"}data: {"type": "delta", "content": "Order 10482 left our warehouse"}data: {"type": "delta", "content": " on Tuesday."}data: {"type": "done", "conversation_id": "9b1c…", "trace_id": "4f2a9c1e…", "usage": {"input_tokens": 1830, "output_tokens": 64, "total_tokens": 1894, "cost_usd": 0}}Every event and field is listed in Streaming events.
What the agent does with a request
| Step | Detail |
|---|---|
| Credit | 1 credit is spent before the model is called and refunded if the reply fails |
| History | The last 12 messages of the conversation (up to 12,000 characters) are sent to the model |
| Knowledge | If the agent has knowledge, hybrid search runs and the best passages are added to the prompt with a grounding rule |
| Tools | The model may call MCP tools for up to 8 rounds. Each tool call has 10 seconds; the model sees at most 2,500 characters of a tool's output |
| Deadline | The whole reply must finish within 120 seconds, or the stream ends with TIMEOUT |
| Answer cache | The first question of a new conversation may be answered from a 15-minute cache (done.cached: true). It still costs 1 credit |
When the answer cache is skipped
- The request continues a conversation (
conversation_idis set). - The request overrides the prompt (
prompt) or the model key (X-Llm-Key). - The agent has MCP tools, so a live lookup could change the answer.
- Any change to the agent (prompt, model, temperature, max tokens, output format) or its knowledge also makes earlier cached answers unreachable.
Limits
| Limit | Value |
|---|---|
| Message length | 32,000 characters |
| Requests per minute | 60 per agent for new agents, shared by the API, the widget and workflow Agent steps |
| Reply time | 120 seconds |
| Tool rounds | 8 per reply |
Still stuck?
Email us with what you tried and any request id. A person replies.