Endpoints
Tool calling
Let models call your functions with the OpenAI tools format on api14: define tools, handle tool calls and return results to the model.
Try it in the playgroundTool calling (function calling) lets a model ask your code to run a function and then use the result in its answer. api14 uses the OpenAI tools format for every model that supports tools: OpenAI, Anthropic, Google, Mistral, Qwen, DeepSeek and others. To find tool-capable models, filter by supported parameters on the Models list (supported_parameters includes tools).
Request parameters
| Parameter | Type | Description |
|---|---|---|
tools | array | [{ "type": "function", "function": { "name", "description", "parameters" } }], where parameters is a JSON Schema. |
tool_choice | string | object | "auto" (default), "none", "required", or { "type": "function", "function": { "name": "get_weather" } }. |
parallel_tool_calls | boolean | Allow several tool calls in one turn (default true where supported). |
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api14.com/api/v1",
apiKey: process.env.API14_API_KEY,
});
const result = await client.chat.completions.create({
"model": "openai/gpt-5-mini",
"messages": [
{
"role": "user",
"content": "What is the weather in Istanbul?"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string"
}
},
"required": [
"city"
]
}
}
}
]
});
console.log(result.choices[0].message.tool_calls);
The loop
- Send
messagesandtools. - If the response has
finish_reason: "tool_calls", run each entry inmessage.tool_calls. - Add the assistant message, then one
{ "role": "tool", "tool_call_id", "content" }message per call, and send the request again. - Repeat until the model answers with plain content.
Response with a tool call:
{
"id": "gen-1760000000-tool1",
"model": "anthropic/claude-sonnet-4.5",
"choices": [
{
"index": 0,
"finish_reason": "tool_calls",
"message": {
"role": "assistant",
"content": null,
"tool_calls": [
{
"id": "call_01",
"type": "function",
"function": { "name": "get_weather", "arguments": "{\"city\":\"Istanbul\"}" }
}
]
}
}
],
"usage": { "prompt_tokens": 182, "completion_tokens": 21, "total_tokens": 203, "cost": 0.000861 }
}
The follow-up request includes the tool result:
{
"model": "anthropic/claude-sonnet-4.5",
"tools": [ ... same tools ... ],
"messages": [
{ "role": "user", "content": "What's the weather in Istanbul?" },
{ "role": "assistant", "content": null, "tool_calls": [ { "id": "call_01", "type": "function", "function": { "name": "get_weather", "arguments": "{\"city\":\"Istanbul\"}" } } ] },
{ "role": "tool", "tool_call_id": "call_01", "content": "{\"temp_c\": 21, \"sky\": \"clear\"}" }
]
}
Keep sending tools with every request in the loop. Many providers reject a tool message if the request has no tools definitions.
Tips
argumentsis a string of JSON. Parse it and validate it, because models can produce invalid JSON.- When streaming, tool calls arrive in
delta.tool_callsfragments keyed byindex. Join theargumentsstrings before parsing them. - To route only to providers that support tools, set
provider: { "require_parameters": true }. See Provider routing. - Each loop iteration is a separate billed request.
Errors
A model that doesn't support tools may return an upstream 400 or 404 ("No endpoints found that support tool use"). Other errors are the same as for Chat completions. See Errors.