← Blog

Claude Tool Use vs OpenAI Function Calling

2026-10-30 · 5 min read · SubToAPI Team

Both Claude and OpenAI let a model call external functions instead of just generating text, but the mechanics differ enough that a straight port of one integration to the other will break. Claude calls this feature "tool use" and expects you to define tools with JSON Schema input, then handles the request/response loop with explicit tool_use and tool_result content blocks. OpenAI's "function calling" (now part of its broader "tools" API) works similarly in spirit but structures the request and response payloads differently, and the two models also diverge in how aggressively they call tools versus answering directly.

If you're choosing between the two or building an integration that needs to support both, the short answer is: the core idea is the same (model decides to call a function, you execute it, you feed the result back), but the message format, streaming behavior, and parallel-call handling are different enough that you need separate code paths — or a layer that normalizes them for you.

How Claude tool use works

With Claude, you pass a tools array in your API request, each tool defined with a name, description, and input_schema (standard JSON Schema). When Claude decides to use a tool, it returns a response with stop_reason: "tool_use" and a content block of type tool_use containing the tool name, a unique id, and the input object.

{
  "role": "assistant",
  "content": [
    {
      "type": "tool_use",
      "id": "toolu_01A09q90qw90lq917835lq9",
      "name": "get_weather",
      "input": { "location": "Berlin", "unit": "celsius" }
    }
  ]
}

You then run the function yourself and send the result back as a tool_result block in the next user message, referencing the same id:

{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A09q90qw90lq917835lq9",
      "content": "18°C, partly cloudy"
    }
  ]
}

Claude can also return plain text alongside or instead of a tool call, and it supports calling multiple tools in a single turn. Anthropic's "forced tool choice" option lets you require a specific tool or any tool at all, which is useful for structured extraction tasks where you don't want a conversational answer.

How OpenAI function calling works

OpenAI's equivalent uses a tools array too, but each entry is wrapped in a {"type": "function", "function": {...}} object, and the schema is called parameters instead of input_schema. When the model wants to call a function, the response comes back with a tool_calls array on the assistant message, each entry containing an id, a function.name, and function.arguments — the arguments are a JSON string, not a parsed object, so you need to JSON.parse() them yourself.

{
  "role": "assistant",
  "tool_calls": [
    {
      "id": "call_abc123",
      "type": "function",
      "function": {
        "name": "get_weather",
        "arguments": "{\"location\":\"Berlin\",\"unit\":\"celsius\"}"
      }
    }
  ]
}

You respond with a role: "tool" message carrying tool_call_id and the raw string result. OpenAI also supports parallel tool calls by default on most models, returning multiple entries in tool_calls in one response.

Key practical differences

If you're standardizing on one API shape

Maintaining two separate tool-calling code paths is annoying if your product only needs Claude but your team is used to OpenAI's conventions, or if you're migrating. SubToAPI exposes Claude through a standard HTTPS API with application keys (sub_live_...), so you get Claude's tool use, streaming, and usage metadata without juggling account-level credentials — useful if you want one clean integration point while your app logic still speaks "tool calls" in whatever shape you've already built around.

A minimal tool-use request through SubToAPI looks like this:

curl https://api.subtoapi.app/v1/messages \
  -H "Authorization: Bearer $SUBTOAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4",
    "max_tokens": 512,
    "tools": [{
      "name": "get_weather",
      "description": "Get current weather for a location",
      "input_schema": {
        "type": "object",
        "properties": {
          "location": {"type": "string"},
          "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
        },
        "required": ["location"]
      }
    }],
    "messages": [{"role": "user", "content": "What is the weather in Berlin?"}]
  }'

This follows Claude's native tool-use format exactly — see the tools docs and messages docs for the full request/response reference, and streaming docs if you need incremental tool-call deltas. Plans start at €9/month on the Solo tier, with Team (€19/seat) and Scale (€49/seat) adding multi-key management for larger projects — check pricing or start with a free trial.

Which one should you pick

If you're choosing a model rather than migrating existing code, pick based on the model's reasoning quality and task fit first — tool-calling mechanics are a solvable integration detail either way. Claude's structured tool_use/tool_result blocks tend to be easier to reason about in multi-tool agent loops because inputs arrive pre-parsed and the stop reason explicitly tells you why generation stopped. OpenAI's function calling is fine too, just remember to parse the arguments string and track tool_call_id carefully across turns.

questions

Is Claude tool use the same as OpenAI function calling? No. Both let a model request a function call instead of a text answer, but the message structure differs: Claude returns a parsed input object in a tool_use content block, while OpenAI returns a JSON string in function.arguments inside tool_calls.

Can I use the same JSON Schema for both APIs? Mostly yes — standard JSON Schema works for both input_schema (Claude) and parameters (OpenAI), since both wrap the same underlying spec. You just need to place it under the correct field name in each request.

Which one calls tools more reliably without being asked? Behavior varies by model version and prompt, so don't assume one is categorically more conservative. Test your specific prompts with tool_choice set explicitly if you need deterministic forced calls rather than relying on default model judgment.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →