← Blog

Claude API Function Calling Schema Example

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

What a Claude function calling schema actually looks like

If you're searching for a working example, here's the short answer: Claude's "function calling" is called tool use, and it works by sending a tools array in your API request, where each tool has a name, a description, and an input_schema written in standard JSON Schema. Claude doesn't execute the function itself — it returns a tool_use content block with the arguments it wants to call, and your code runs the actual function and sends the result back.

This is different from older OpenAI-style "functions" parameters in naming but nearly identical in structure. If you've written a JSON Schema before, you already know 90% of what you need.

The minimal tool schema

Here's a bare-bones example: a weather lookup tool.

{
  "name": "get_weather",
  "description": "Get the current weather for a given city",
  "input_schema": {
    "type": "object",
    "properties": {
      "city": {
        "type": "string",
        "description": "City name, e.g. 'Berlin'"
      },
      "unit": {
        "type": "string",
        "enum": ["celsius", "fahrenheit"]
      }
    },
    "required": ["city"]
  }
}

Three things matter most here:

Full request example

curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-4-5",
    "max_tokens": 1024,
    "tools": [
      {
        "name": "get_weather",
        "description": "Get the current weather for a given city",
        "input_schema": {
          "type": "object",
          "properties": {
            "city": { "type": "string" },
            "unit": { "type": "string", "enum": ["celsius", "fahrenheit"] }
          },
          "required": ["city"]
        }
      }
    ],
    "messages": [
      { "role": "user", "content": "What is the weather in Lisbon right now?" }
    ]
  }'

Claude's response won't contain a final answer — it contains a tool call:

{
  "content": [
    {
      "type": "tool_use",
      "id": "toolu_01A2bC",
      "name": "get_weather",
      "input": { "city": "Lisbon" }
    }
  ],
  "stop_reason": "tool_use"
}

Your application code calls the real weather API, then sends the result back as a tool_result block, using the same id:

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

Claude then generates the final natural-language reply using that result.

Multiple tools and tool_choice

You can define several tools in the same array, and let Claude pick the right one:

"tools": [
  { "name": "get_weather", "description": "...", "input_schema": { ... } },
  { "name": "search_flights", "description": "...", "input_schema": { ... } },
  { "name": "convert_currency", "description": "...", "input_schema": { ... } }
]

Use tool_choice to control behavior:

Forcing a specific tool is useful when you're using tool use purely as a structured-output mechanism rather than for real function execution — a common pattern for extracting structured JSON from unstructured text.

Nested and array schemas

Schemas can go as deep as real JSON Schema allows. A booking tool with nested objects:

{
  "name": "create_booking",
  "description": "Create a hotel booking for one or more guests",
  "input_schema": {
    "type": "object",
    "properties": {
      "hotel_id": { "type": "string" },
      "check_in": { "type": "string", "format": "date" },
      "check_out": { "type": "string", "format": "date" },
      "guests": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "name": { "type": "string" },
            "age": { "type": "integer" }
          },
          "required": ["name"]
        }
      }
    },
    "required": ["hotel_id", "check_in", "check_out", "guests"]
  }
}

Keep schemas as flat as practical. Deep nesting works, but every extra layer increases the chance Claude misinterprets which field belongs where, especially with ambiguous field names reused across levels.

Common mistakes in tool schemas

Running this through SubToAPI

If your team already pays for Claude through a subscription rather than per-token API billing, you can still use this exact tool-use schema format. SubToAPI turns your Claude access into a standard HTTPS API with sub_live_... application keys, so the same /v1/messages request shape — including tools, tool_choice, and streaming — works without changing your integration code.

curl https://api.subtoapi.app/v1/messages \
  -H "Authorization: Bearer $SUBTOAPI_KEY" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-sonnet-4-5",
    "max_tokens": 1024,
    "tools": [ /* same schema as above */ ],
    "messages": [{ "role": "user", "content": "Book a room for 2 guests in Lisbon" }]
  }'

This is useful when multiple developers on a team need API-style access without each person managing separate billing — see /docs/tools for the full tool-use reference, /docs/messages for request/response formats, and /pricing for Solo, Team, and Scale plans. A free trial is available at /signup.

FAQ

Does Claude support OpenAI-style "functions" syntax? No. Claude uses a tools array with name, description, and input_schema (JSON Schema), returned as a tool_use content block — conceptually similar to OpenAI functions but with different field names and response structure.

Can I force Claude to always call a specific tool? Yes, set tool_choice to {"type": "tool", "name": "your_tool_name"}. This is commonly used to get strictly structured JSON output rather than free-text responses.

Why does Claude call the wrong tool when I have several defined? Usually because tool descriptions overlap or are too generic. Write descriptions that clearly state when a tool should and shouldn't be used, and keep input schemas as flat and explicit as possible.

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 →