Create chat
Answers one turn of a conversation with four things: the model's `reply`, the `actions` the server executed on the caller's behalf, the `ops` the client…
POST /v1/agent/chat
| Address | https://api.hanzo.ai/v1/agent/chat |
| Method | POST |
| Operation | post_agent_chat |
| Auth | Authorization: Bearer $HANZO_API_KEY |
Answers one turn of a conversation with four things: the model's reply, the actions the server executed on the caller's behalf, the ops the client must apply itself, and the conversationId the turn was recorded under.
The split between actions and ops is the rule most easily got wrong. A tool call is executed HERE only when the chosen preset is server-executing AND the tool resolves in the caller's own scope; every other call is handed back as an op for the client to apply to its own graph or UI. A tool that fails still comes back as an action, carrying its error rather than failing the round.
preset selects the system prompt and the tool set (capability is a legacy alias for it); an unknown one is refused. conversationId continues an existing thread, and its absence starts one. A validated principal with a non-empty org is required — the org is the sole authority for both persistence and tool scope, and is NEVER read from the body.
A completion refused for the caller's own reason — 402 insufficient balance, 429, 403 — is relayed with its own status and body verbatim, so the real billing message reaches the client instead of an opaque gateway error. Only a genuine upstream fault becomes a 502.
Request
The document declares no body for POST /v1/agent/chat. The handler is typed in cloud but its shape is not yet emitted, so the fields are not listed here — ask MCP's describe for post_agent_chat, which answers from the running route.
Response
The document declares no response body for this operation. It answers 200 on success and the platform error shape on failure — see Errors.
Examples
hanzo agent chat createimport { Configuration, AgentApi } from 'hanzoai';
const api = new AgentApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.postAgentChat();from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import AgentApi
client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = AgentApi(client).post_agent_chat()cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)
resp, _, err := client.AgentAPI.PostAgentChat(context.Background()).Execute()
if err != nil {
return err
}use hanzo_client::apis::{configuration::Configuration, agent_api};
let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();
let result = agent_api::post_agent_chat(&cfg, Default::default()).await?;import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.AgentApi;
ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));
var result = new AgentApi(client).postAgentChat();The method above is the one at the current release of the document. [email protected] (npm) was generated from an earlier release, where this operation carried a different id, so it spells the method differently — regenerating the clients is what makes the two agree. SDKs →
curl -X POST https://api.hanzo.ai/v1/agent/chat \
-H "Authorization: Bearer $HANZO_API_KEY"MCP reaches agent through the agents tool, which names its 36 operations with its own verbs — this one among them, under a name only MCP declares. describe explains any of them:
curl -X POST https://api.hanzo.ai/v1/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "describe",
"arguments": {
"op": "list_agent_conversations"
}
}
}'How is this guide?