Skip to main content
The gateway supports tool (function) calling on Chat Completions, the Responses API, and Messages. Declare your tools in the request; if the model decides to use one, the gateway streams the tool call back to you.

Relay mode

Your function tools run in relay mode: the gateway does not execute your functions. It declares your tool definitions to the model, returns the call the model wants to make, and stops. You run the tool and send the result back on the next turn. A typical loop:
  1. Send a request with tools (and optionally tool_choice).
  2. The model responds with one or more tool calls and a tool-call finish reason instead of final text.
  3. Run each tool yourself and append the result to the conversation.
  4. Send the updated conversation back; the model continues (more tool calls, or a final text answer).
Use a model that supports tools. Validate the returned function name and arguments before execution, and keep a limit on tool-loop iterations. Each follow-up model request is billed separately.

Chat Completions

Request — tools[] are function definitions; tool_choice is auto (default), none, required, or { "type": "function", "function": { "name": "..." } }.
Response — the assistant message carries tool_calls and finish_reason is tool_calls. Each call’s function.arguments is a JSON-encoded string.
Returning the result — append the assistant message and a tool message whose tool_call_id matches, then send the conversation again:
Streaming — tool calls arrive as delta.tool_calls[] fragments. The first fragment for a call carries id, type, and function.name; later fragments stream function.arguments text. The index field correlates fragments of the same call.

Responses API

Request — Responses flattens the function fields onto each tool. tool_choice is auto / none / required / { "type": "function", "name": "..." }.
Response — the model emits a function_call output item with a call_id and a JSON-string arguments:
Returning the result — resend the prior input and output items, then add a function_call_output referencing the same call_id. Responses is stateless; sending only the result loses the conversation:
Streaming — a response.output_item.added event opens the function_call item, response.function_call_arguments.delta events stream the argument text, and response.function_call_arguments.done closes it.

Messages (Anthropic)

Request — tools[] use input_schema; tool_choice is { "type": "auto" }, { "type": "any" }, { "type": "tool", "name": "..." }, or { "type": "none" }. (A bare claude-... model id routes to Anthropic; any provider/model id also works here — see SDKs & integrations.)
Response — a tool_use content block (with a parsed input object) and stop_reason: "tool_use":
Returning the result — send a user turn containing a tool_result block referencing the tool_use_id:
Streaming — the tool_use block opens with a content_block_start, its input streams as content_block_delta events of type input_json_delta (partial_json), and closes with content_block_stop.
Across all three surfaces, arguments arrive as JSON text (a string for OpenAI-style calls, streamed partial_json for Anthropic). Parse them yourself before running the tool, and tolerate empty/partial fragments while streaming.

Images in tool results

A tool that returns an image can hand it straight to the model — the image reaches the model instead of being flattened to text. Each surface uses its own content part inside the tool result:
Tool-result images must be data: base64 URIs. Unlike a user message, an http(s) URL in a tool result returns 400 — the gateway does not fetch remote images on your behalf. Fetch it yourself and inline the bytes. User-message images still accept both sources (see Vision).
Anthropic, Gemini, and the OpenAI Responses API receive the image natively inside the tool result. Chat-Completions backends receive it as a single user message placed immediately after the whole tool-result group, so parallel tool calls stay intact. Sending an image to a model whose input_modalities explicitly exclude image returns 400 invalid_request_error rather than silently dropping it. A model that declares no modalities at all is unverified, not text-only, and still accepts images.

Gemini thought signatures

Gemini 3 models attach an opaque signature to the first function call of each step and reject the tool-result turn unless it comes back verbatim. The gateway round-trips it for you: on Chat Completions the tool call carries extra_content.google.thought_signature (Google’s OpenAI-compat mapping — in streaming it rides a tool_calls fragment), and on the Responses API the function_call item carries the same extra_content field. Send the tool call back exactly as you received it — clients that echo the assistant message unchanged preserve this context. Check that your framework does not strip unknown fields. The Gemini-native endpoint uses Google’s own Part.thoughtSignature unchanged. Tool calls from another model. Gemini 3 also rejects any tool call in the history that carries no signature at all — the case when you switch an ongoing session to Gemini, synthesise a call yourself, or use a client that strips unknown fields. The gateway marks those calls with Google’s documented skip-validation sentinel so the turn is accepted; a real signature you send is always preserved byte-for-byte and never replaced.

Mistral on Azure Foundry

Mistral’s serving stack on Foundry requires tool-call ids to be exactly nine alphanumeric characters, and requires every tool to carry a description. An OpenAI-style call_abc123 or an Anthropic-style toolu_01ABC from an earlier model would be refused. The gateway rewrites ids consistently across the request (each id and the tool_call_id referring to it get the same value) and supplies an empty description when you omit one, so a tool history built against any other provider replays unchanged. Ids in the response are the ones the provider minted; your own ids are never rewritten on the way back.
On Responses, supported xAI models can run web_search and x_search on the provider’s server. Unlike your function tools, these searches do not need an application round trip.
Send this body to POST /v1/responses. Search invocations add a $0.005 charge each on top of token usage for gateway-paid requests. usage.server_side_tool_calls reports invocations when present; one request can use more than one search.These native searches execute only on xAI routes. On other providers they are filtered out; tool_choice: "required" returns 400 if no executable tools remain. Do not assume that an answer used search just because your request included a search tool. Code execution is not supported.