Skip to content

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:

Terminal window
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:

ValueBehavior
{ "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.
  • Streamingtool_use content-block streaming.
  • Errors — error envelopes for tool-call failures and provider passthrough.