Tool use
Add function calling to your app: define tools, read tool_use blocks, control tool_choice and run parallel calls. Works in both Anthropic and OpenAI styles.
Function-calling on the Anthropic-native endpoint. The API normalizes tool_choice so legacy SDKs that emit {type:any} or {type:tool} keep working.
All models, capabilities, and prices Documentation index for AI agents:https://oneprovider.dev/docs/llms.txt Request shape
Declare tools as an array. Each tool has a name, a description, and a JSON-Schema input_schema. The model emits a tool_use content block whenever it decides to call one.
{
"model": "claude-sonnet-5-5",
"max_tokens": 1024,
"tools": [
{
"name": "get_weather",
"description": "Return current weather for a city.",
"input_schema": {
"type": "object",
"properties": {
"city": { "type": "string" },
"units": { "type": "string", "enum": ["c", "f"] }
},
"required": ["city"]
}
}
],
"messages": [
{ "role": "user", "content": "What's the weather in Berlin in celsius?" }
]
} Response with a tool call
json{
"id": "msg_01...",
"stop_reason": "tool_use",
"content": [
{ "type": "text", "text": "Let me check that for you." },
{
"type": "tool_use",
"id": "toolu_bdrk_01...",
"name": "get_weather",
"input": { "city": "Berlin", "units": "c" }
}
]
} Continuing the loop
After your code executes the tool, send the result back as a user message containing a tool_result block. The model then either emits another tool call or a final text answer.
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_bdrk_01...",
"content": "{\"city\":\"Berlin\",\"temp_c\":18,\"sky\":\"clear\"}"
}
]
} tool_choice — how we normalize
Anthropic accepts four tool_choice forms. The OneProvider API accepts all four from your client, but passes two of them to the model in a different form:
| Client sends | Model receives | Why |
|---|---|---|
{"type":"auto"} (or absent) | unchanged | Model decides — happy path. |
{"type":"none"} | unchanged | Force text-only response. |
{"type":"any"} | {"type":"auto"} + system hint | Not every model supports forced tool calls; the hint tells the model "you MUST call a tool". |
{"type":"tool","name":"X"} | {"type":"auto"} + system hint | Same; the hint names the tool. |
tool_choice:any and tool_choice:tool would fail on some models. With auto + a strong system hint, about 95% of these requests succeed in our tests. If you see a tool-call you expected get replaced with prose, the hint failed to nudge the model — tighten your user prompt or switch to a more capable model. Parallel tool calls
A single response can contain multiple tool_use blocks — the model decides whether to fan out. Execute all of them, then send back one user message with multipletool_result blocks (one per tool_use_id). Order doesn’t matter.
Tool naming
- Names are case-sensitive and pass through verbatim — the model echoes whatever you registered.
- Both
snake_caseandPascalCasework. The Claude Code CLI uses PascalCase (Read,Bash,Edit); generic SDKs typically use snake_case. - Keep names <64 chars and ASCII
[a-zA-Z0-9_].
OpenAI-style tool calling
On the /v1/chat/completions endpoint, use the standard OpenAI tools /tool_calls shape — we translate it to Anthropic tool_use blocks under the hood.
Quick answers
Which base URL do I use?
Claude Code and Anthropic SDKs use https://api.oneprovider.dev. OpenAI SDKs and OpenAI-compatible clients use https://api.oneprovider.dev/v1. One key works behind both; the model list is on the models page ; rates are on the pricing page .
How do I authenticate?
Send the raw sk-… key in x-api-key or Authorization: Bearer: one of them, never both. Keep the key in an environment variable, not in a file that gets committed. More on authentication .
Where do I get a key?
Open your cabinet in the Telegram bot @oneprovider_robot or at app.oneprovider.dev, top up the balance and press “Issue a key”. Each key can carry its own spend limit. Cabinet & API keys .
What do 401, 404 and 429 mean?
401: the key is missing, mistyped or sent in the wrong header; paste the whole key without quotes or spaces. 404: usually a wrong base URL, for example a missing or doubled /v1. 429 with “Insufficient balance”: the cabinet balance or the key’s spend limit is used up, so top up instead of retrying; any other 429 is a rate limit, so wait for Retry-After. Details: error codes and troubleshooting .
Why do streams cut off or reset?
VPN and VLESS proxies often buffer SSE or break HTTP/2 negotiation. OneProvider has no regional restrictions and does not buffer streams, so turn the proxy off and retry.
Where do I ask if this is not enough?
Message @Oneproviderhelpbot on Telegram or open “Support” in the web cabinet, with the HTTP status code and the exact error message. How support works .
Last updated: 2026-10-05 Found a bug? @Oneproviderhelpbot