Skip to content

Tool and function calling API in every format

Let the model call your functions in every format, define a tool, read the call, send the result back, and see what each model family supports.

Updated October 2, 2026
On this page

Tool calling lets the model ask your program to run a function, such as fetching the weather or searching your database, and then answer with the result. The model never runs anything itself: it returns the function name and the arguments, your code runs it, and you send the result back in the next request.

The loop#

  1. Describe your tools#

    Send a list of tools in the request, each with a name, a description and a JSON Schema for its arguments. A clear description is what makes the model call the right tool.

  2. Read the call#

    When the model wants a tool, the reply holds a call with the tool name and its arguments instead of a final answer, and the stop reason says so.

  3. Run it and send the result#

    Run the function in your code, then send a new request with the whole conversation: the model's call, followed by your result linked to the call's id. The model then answers, or calls another tool.

The same tool in each format#

  • Chat Completions: tools in tools with type: "function" and function.parameters. The call comes in message.tool_calls with finish_reason: "tool_calls". Send the result as a message with role: "tool" and the tool_call_id.
  • Responses: tools in tools with type: "function" and parameters. The call is an output item of type function_call with a call_id. Send the result as an input item of type function_call_output with the same call_id.
  • Messages: tools in tools with input_schema. The call is a tool_use block with stop_reason: "tool_use". Send the result as a tool_result block in a user message, with the tool_use_id.
  • Gemini: tools in tools with functionDeclarations. The call is a functionCall part. Send the result as a functionResponse part in a user turn.

Full requests with captured replies: Chat Completions, Responses, Messages and Gemini.

Sending the result back#

In Chat Completions, the second request repeats the conversation, adds the model's call as it came, and then your result:

messages
[
  { "role": "user", "content": "What is the weather in Cairo?" },
  { "role": "assistant", "content": null, "tool_calls": [
    { "id": "call_1", "type": "function", "function": { "name": "get_weather", "arguments": "{\"city\":\"Cairo\"}" } }
  ] },
  { "role": "tool", "tool_call_id": "call_1", "content": "{\"temp_c\": 31, \"sky\": \"clear\"}" }
]

In Messages, the call and the result are blocks:

messages
[
  { "role": "user", "content": "What is the weather in Cairo?" },
  { "role": "assistant", "content": [
    { "type": "tool_use", "id": "toolu_1", "name": "get_weather", "input": { "city": "Cairo" } }
  ] },
  { "role": "user", "content": [
    { "type": "tool_result", "tool_use_id": "toolu_1", "content": "{\"temp_c\": 31, \"sky\": \"clear\"}" }
  ] }
]

What each family supports#

  • Every family accepts tools in Chat Completions and Messages, and Claude and GPT in Responses.
  • Forcing a tool with tool_choice works for Claude and GPT. Gemini models choose for themselves in Chat Completions and Messages; in generateContent use toolConfig.
  • parallel_tool_calls has an effect for GPT models only. Claude models may call several tools in one reply; handle every call before you answer.
  • For a JSON answer from Claude, define one tool whose schema is the shape you want and force it with tool_choice: the arguments are your JSON.

Tips#

  • Check the arguments before you run anything: the model can send a wrong value.
  • Keep tool results short and factual; long results cost input tokens on every later request.
  • Return errors as results, such as {"error": "city not found"}, so the model can recover.