← Blog

Claude API Tool Calling: A JSON Schema Example

2026-10-10 · 4 min read · SubToAPI Team

If you're trying to get Claude to call a tool with the correct arguments, the fastest way to understand it is to see a complete, working JSON schema example alongside the actual request and response payloads. Below is exactly that: a real tool definition, a real request, and the tool_use block Claude returns, with explanations of why each field matters.

Tool calling in the Claude API works by describing a function as a JSON Schema object inside your request. Claude decides whether to call it, and if so, returns a structured tool_use content block with arguments that match your schema. You never execute code on Anthropic's servers — you send the schema, Claude returns arguments, your code runs the function and (optionally) sends the result back.

The Minimal Tool Schema

Here's a complete tool definition for a weather lookup function:

{
  "name": "get_weather",
  "description": "Get the current weather for a specific city and country.",
  "input_schema": {
    "type": "object",
    "properties": {
      "city": {
        "type": "string",
        "description": "The city name, e.g. 'Berlin'"
      },
      "country": {
        "type": "string",
        "description": "ISO 3166 two-letter country code, e.g. 'DE'"
      },
      "unit": {
        "type": "string",
        "enum": ["celsius", "fahrenheit"],
        "description": "Temperature unit to return"
      }
    },
    "required": ["city", "country"]
  }
}

Three things matter here more than anything else:

Full Request Example

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

What Claude Returns

When Claude decides to use the tool, the response contains a tool_use block instead of (or alongside) plain text:

{
  "id": "msg_01XYZ",
  "role": "assistant",
  "content": [
    {
      "type": "tool_use",
      "id": "toolu_01ABC",
      "name": "get_weather",
      "input": {
        "city": "Lisbon",
        "country": "PT",
        "unit": "celsius"
      }
    }
  ],
  "stop_reason": "tool_use"
}

Your application code reads input, calls the real weather API, and sends the result back as a tool_result message so Claude can produce a final natural-language answer:

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

That round trip — schema in, tool_use out, tool_result back in — is the entire pattern. Multi-tool setups and parallel tool calls follow the same structure, just with multiple tool_use blocks in one response.

Common JSON Schema Mistakes

A few issues show up repeatedly when people build their first tool:

Validating Before You Ship

Treat your tool schema like an API contract. Run it through a JSON Schema validator before deploying, and test it with adversarial prompts — ambiguous requests, missing information, multiple tools that could plausibly apply. This catches most of the "Claude picked the wrong tool" issues before they reach production.

Where SubToAPI Fits In

If you're building tool-calling features into a product, SubToAPI gives you an HTTPS endpoint on top of your existing Claude access, with sub_live_... application keys, streaming, and usage metadata per key — useful when different teams or environments need isolated tool definitions and separate rate limits. The same tools array and request shape shown above works against SubToAPI's endpoint; see the tool use docs and messages API reference for details, or check pricing if you're evaluating it for a team.

FAQ

Does Claude support standard JSON Schema, or a custom format? Claude's input_schema is a subset of standard JSON Schema (draft 2020-12 style). Most common keywords — type, properties, required, enum, items, nested object — work as expected, but exotic keywords like $ref across files aren't reliably supported.

Can Claude call multiple tools in one response? Yes. If the model determines multiple tool calls are needed, the response content array can contain multiple tool_use blocks, each with its own id you match back when sending tool_result messages.

What happens if the arguments don't match my schema? Claude generally produces arguments that conform to your schema, but you should still validate on your end — type mismatches or missing required fields can occasionally slip through, especially with vague descriptions or ambiguous enums.

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 →