Messages API tool use
POST /v1/messages accepts Anthropic’s standard tool definitions.
tool_use and tool_result content blocks pass through to the
upstream provider with no Kindo-specific wrapping.
Define a function tool
{ "model": "claude-sonnet-4-5-20250929", "max_tokens": 512, "tools": [ { "name": "get_weather", "description": "Get the current weather for a city.", "input_schema": { "type": "object", "properties": { "location": { "type": "string" } }, "required": ["location"] } } ], "messages": [ { "role": "user", "content": "What is the weather in San Francisco?" } ]}Anthropic tool definitions use name / description /
input_schema (different from Chat Completions’ nested function
object).
Round trip
Step 1 — initial request
Submit the request above.
Step 2 — assistant message with tool_use
{ "id": "msg_01", "role": "assistant", "content": [ { "type": "tool_use", "id": "toolu_01", "name": "get_weather", "input": { "location": "San Francisco, CA" } } ], "stop_reason": "tool_use"}stop_reason: "tool_use" is the canonical signal that the model
wants you to run a tool.
Step 3 — execute the tool client-side
Run get_weather({ location: "San Francisco, CA" }) in your
application.
Step 4 — submit the result
Return the result as a tool_result content block in a user
message. Re-include the prior assistant message and re-include
tools so the model has the schema:
curl -X POST https://api.kindo.ai/v1/messages \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $KINDO_API_KEY" \ -H "anthropic-version: 2023-06-01" \ -d '{ "model": "claude-sonnet-4-5-20250929", "max_tokens": 512, "tools": [ { "name": "get_weather", "description": "Get the current weather for a city.", "input_schema": { "type": "object", "properties": { "location": { "type": "string" } }, "required": ["location"] } } ], "messages": [ { "role": "user", "content": "What is the weather in San Francisco?" }, { "role": "assistant", "content": [ { "type": "tool_use", "id": "toolu_01", "name": "get_weather", "input": { "location": "San Francisco, CA" } } ] }, { "role": "user", "content": [ { "type": "tool_result", "tool_use_id": "toolu_01", "content": "{\"temperature\":68,\"unit\":\"fahrenheit\"}" } ] } ] }'The tool_use_id on the tool_result block must match the id
on the originating tool_use block.
Step 5 — final answer
{ "id": "msg_02", "role": "assistant", "content": [{ "type": "text", "text": "It's 68 °F in San Francisco." }], "stop_reason": "end_turn"}tool_choice
Anthropic’s tool-choice format:
| Value | Behavior |
|---|---|
{ "type": "auto" } (default) | The model decides whether to call a tool. |
{ "type": "any" } | The model must call at least one tool. |
{ "type": "tool", "name": "..." } | The model must call exactly that tool. |
See also
- Request shape — full field reference.
- Streaming —
tool_usecontent-block streaming. - Errors — error envelopes for tool-call failures and provider passthrough.