← Blog

How to Use Claude Tool Calling: A Developer Guide

2026-09-15 · 5 min read · SubToAPI Team

"Using a Claude tool" almost always means one of two things: giving Claude access to functions it can call (tool use / function calling), or connecting a third-party tool that talks to Claude through an API. This guide covers the first and most common case — how to actually wire up tool calling in your own application, from your first request to handling the response Claude sends back.

The short version: you describe your tools (name, description, input schema) in your API request, Claude decides whether to call one, you execute the actual function on your side, and you send the result back so Claude can finish its answer. Nothing runs on Anthropic's servers — Claude only tells you what to run and with what arguments.

What you need before starting

Step 1: Define your tool

Every tool needs a name, a description, and a JSON schema for its inputs. The description matters more than people expect — it's how the model decides when to call the tool, not just how.

{
  "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. Paris" },
      "unit": { "type": "string", "enum": ["celsius", "fahrenheit"] }
    },
    "required": ["city"]
  }
}

Keep schemas minimal. Extra optional fields the model doesn't need just add ambiguity and increase the chance of malformed calls.

Step 2: Send the request with the tool attached

You pass the tool definition alongside your normal messages request. The model reads the conversation and decides on its own whether a tool call is needed.

curl https://api.subtoapi.app/v1/messages \
  -H "Authorization: Bearer $SUBTOAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-3-5-sonnet",
    "max_tokens": 1024,
    "tools": [{
      "name": "get_weather",
      "description": "Get the current weather for a given city",
      "input_schema": {
        "type": "object",
        "properties": {
          "city": { "type": "string" }
        },
        "required": ["city"]
      }
    }],
    "messages": [
      { "role": "user", "content": "What is the weather like in Lisbon?" }
    ]
  }'

Step 3: Read the tool_use block

If Claude decides a tool is needed, the response contains a content block with type: "tool_use", the tool name, and structured input arguments — not free text.

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

Your code checks stop_reason. If it's tool_use, you extract the name and input, run the matching function yourself, and capture the output.

Step 4: Send the result back

You append the tool call to the conversation as an assistant message, then add a tool_result block as a user message with the same id. Claude uses that result to write its final answer.

const toolResult = await getWeather(input.city); // your actual function

const followUp = await fetch("https://api.subtoapi.app/v1/messages", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SUBTOAPI_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    model: "claude-3-5-sonnet",
    max_tokens: 1024,
    tools: [ /* same tool definitions */ ],
    messages: [
      { role: "user", content: "What is the weather like in Lisbon?" },
      { role: "assistant", content: previousToolUseBlocks },
      {
        role: "user",
        content: [{
          type: "tool_result",
          tool_use_id: "toolu_01Xyz",
          content: JSON.stringify(toolResult)
        }]
      }
    ]
  })
});

Claude then returns a normal text response, now informed by real data instead of a guess.

Common mistakes when using Claude tool calling

Where SubToAPI fits in

If you're paying for a Claude subscription and don't want to separately manage Anthropic API billing, SubToAPI turns that access into a standard HTTPS endpoint with application API keys (sub_live_...), streaming, and full tool-use support — so the same request format shown above works without changes. It also gives you per-key usage metadata, which is useful once you have several tools and want to see which ones actually get called in production.

Start with the quickstart guide, then check the tool use docs for the full request/response schema and the messages reference for everything else the endpoint supports. Plans start with a free trial at signup — pricing is on the pricing page.

questions

Do I need a special API plan to use Claude's tools? No — tool use is part of the standard Messages API, available on any plan that supports the model you're calling. You just include a tools array in your request.

Can Claude call the tool for me automatically? No. Claude only returns the tool name and arguments; your application has to execute the actual function and send the result back in a follow-up request.

Why isn't Claude calling my tool even though I defined it? Usually the description is too vague, the user's message doesn't clearly need that action, or the tool schema has a required field the model can't reasonably infer — tighten the description and required parameters first.

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 →