Define tools
Describe your functions in the tools array with a JSON Schema for their arguments, and use tool_choice to control when the model calls one.
Tool calling lets a chat model ask your code to run a function. You describe the functions on the request; when the model decides to use one, the turn ends with the call and its arguments, you run it, and you send the result back. This page covers the first part. Handle tool calls covers answering the calls, and Tutorial: build a tool-using agent runs the whole loop.
curl https://api.cruxy.ai/api/v1/chat \
-H "Authorization: Bearer $CRUXY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "kavi",
"stream": false,
"messages": [
{ "role": "user", "content": "What is the weather in Paris?" }
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": { "type": "string", "description": "City name, for example Paris" }
},
"required": ["city"]
}
}
}
],
"tool_choice": "auto"
}'const tools = [
{
type: 'function',
function: {
name: 'get_weather',
description: 'Get the current weather for a city',
parameters: {
type: 'object',
properties: {
city: { type: 'string', description: 'City name, for example Paris' },
},
required: ['city'],
},
},
},
]
const res = await fetch('https://api.cruxy.ai/api/v1/chat', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.CRUXY_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'kavi',
stream: false,
messages: [{ role: 'user', content: 'What is the weather in Paris?' }],
tools,
tool_choice: 'auto',
}),
})
const completion = await res.json()
console.log(completion.finish_reason) // "tool_calls" when the model wants get_weather
console.log(completion.message.tool_calls)Describe a tool
tools is an array. Each entry describes one function:
| Field | Required | What it is |
|---|---|---|
type | Yes | "function". |
function.name | Yes | The name the model calls the function by, and the name it returns in a tool call. |
function.description | No | What the function does, rendered into the prompt the model reads. |
function.parameters | No | A JSON Schema object describing the function's arguments, also rendered into the prompt. |
Write the description and each parameter's description for the model: say
what the function returns and when to use it, the way you would brief a
colleague.
Control tool use
tool_choice controls whether the model may call your tools, and which:
tool_choice | Effect |
|---|---|
| Omitted | The provider default. |
"none" | The model calls no tool. |
"auto" | The model decides whether to call a tool. |
"required" | The model calls at least one tool. |
{ "type": "function", "function": { "name": "get_weather" } } | The model calls that function. This is the only form that makes a tool call deterministic. |
A forced function must appear in tools, and "required" needs at least one
tool. Either mistake is 400 invalid_request, answered before anything goes
upstream.
Schema bounds
The gateway bounds each tool's parameters schema by size, depth, and node
count. A schema past a bound is 400 invalid_tool_schema, which adds three
fields:
| Field | Meaning |
|---|---|
tool | The function whose schema broke the bound. |
bound | Which bound: bytes, depth, or nodes. |
limit | That bound's value. |
Retrying never helps, because the fix belongs in the tool definitions your
client ships. To check them ahead of time, send the same tools to
POST /api/v1/tokens/count: it applies the same bounds with the same 400
answer, is not billed, and returns the input tokens the request would bill,
tools included.
Tools are billed input
The provider renders each function's name, description, and parameters into
the prompt, so every request that sends tools is billed for them as input
tokens. Count them with POST /api/v1/tokens/count, and keep descriptions as
long as the model needs and no longer.
Where tools work
tools and tool_choice are accepted on POST /api/v1/chat,
POST /api/v2/chat, and POST /v1/chat/completions. Each tier reports
supports_tools in GET /api/v1/models; Models
shows how to read the catalog.
Next steps
- Handle tool calls: run the calls the model returns and send the results back.
- Tutorial: build a tool-using agent: the full loop in one program.
- Chat: the rest of the request and the response.