Claude API Function Calling: Real-World Examples
What Claude API Function Calling Actually Does
Claude API function calling — Anthropic calls it tool use — lets the model decide when to call a function you've defined, extract the right arguments from a conversation, and hand control back to your code to execute it. Claude never runs code itself. It returns a structured tool_use block with a name and JSON input; your application executes the real logic (hitting a database, calling an API, running a calculation) and sends the result back as a tool_result so Claude can finish its answer.
The real-world examples below cover the patterns developers actually build: live data lookups, internal database queries, multi-step booking agents, calculators, and structured extraction pipelines. Each one includes the tool schema and the request/response flow so you can adapt it directly.
Example 1: Live Data Lookup (Weather API)
This is the canonical example because it shows the full loop clearly: Claude decides it needs external data, you fetch it, Claude finishes the answer.
{
"name": "get_weather",
"description": "Get current weather for a city",
"input_schema": {
"type": "object",
"properties": {
"city": { "type": "string" },
"unit": { "type": "string", "enum": ["celsius", "fahrenheit"] }
},
"required": ["city"]
}
}
A user asks "Is it going to rain in Lisbon today?" Claude replies with a tool_use block requesting get_weather with {"city": "Lisbon"}. Your server calls the real weather API, then sends:
{
"type": "tool_result",
"tool_use_id": "toolu_01abc",
"content": "18°C, light rain expected after 4pm"
}
Claude then writes the natural-language answer using that data. No hallucinated weather, no stale training data.
Example 2: Internal Database / CRM Queries
This is the pattern most SaaS teams actually ship: letting Claude answer "what's the status of order #4521?" by querying your own systems instead of the public web.
{
"name": "lookup_order",
"description": "Fetch order details by order ID from the internal orders table",
"input_schema": {
"type": "object",
"properties": {
"order_id": { "type": "string" }
},
"required": ["order_id"]
}
}
The key design decision here is scope: expose read-only, narrowly-defined functions (lookup_order, get_customer_tier) rather than one generic run_sql tool. It's safer, and Claude picks the right tool more reliably when each one has a single clear purpose.
Example 3: Multi-Step Booking Agent
Real agent workflows chain several tool calls in sequence. A travel-booking assistant might need search_flights, check_seat_availability, and create_booking — each depending on the output of the last.
const tools = [
{ name: "search_flights", description: "Search flights by route and date", input_schema: {/* ... */} },
{ name: "check_seat_availability", description: "Check seats on a flight", input_schema: {/* ... */} },
{ name: "create_booking", description: "Create a confirmed booking", input_schema: {/* ... */} }
];
let messages = [{ role: "user", content: "Book me a one-way flight from Porto to Berlin next Friday, window seat." }];
while (true) {
const response = await callClaude(messages, tools);
if (response.stop_reason !== "tool_use") break;
for (const block of response.content.filter(b => b.type === "tool_use")) {
const result = await executeTool(block.name, block.input);
messages.push({ role: "assistant", content: [block] });
messages.push({
role: "user",
content: [{ type: "tool_result", tool_use_id: block.id, content: JSON.stringify(result) }]
});
}
}
This loop is the backbone of most production agents: call Claude, check if it wants a tool, execute, feed the result back, repeat until it returns a final text answer. Guard it with a max iteration count so a malfunctioning tool can't loop forever.
Example 4: Calculator / Code Execution Tool
Claude is good at reasoning but shouldn't be trusted with exact arithmetic on large numbers or financial calculations. A simple calculate tool fixes that:
{
"name": "calculate",
"description": "Evaluate a basic arithmetic expression",
"input_schema": {
"type": "object",
"properties": { "expression": { "type": "string" } },
"required": ["expression"]
}
}
For a question like "If I invest €500 a month at 6% annual return for 10 years, what's the total?", Claude builds the expression, your backend evaluates it with a safe math parser (never eval), and returns the exact number.
Example 5: Structured Data Extraction
Function calling isn't only for taking actions — it's also the most reliable way to force Claude into a strict output shape, like pulling fields out of an email or support ticket.
{
"name": "extract_ticket_info",
"description": "Extract structured fields from a support ticket",
"input_schema": {
"type": "object",
"properties": {
"priority": { "type": "string", "enum": ["low", "medium", "high", "urgent"] },
"category": { "type": "string" },
"summary": { "type": "string" }
},
"required": ["priority", "category", "summary"]
}
}
Instead of parsing free-text JSON out of a response (which breaks the moment Claude adds a stray sentence), you force a tool call and read tool_use.input directly — guaranteed valid JSON matching your schema.
Running These Through SubToAPI
If you're already building on a Claude subscription rather than a pay-per-token API key, SubToAPI exposes the same tool-use interface over a standard HTTPS endpoint, so these examples work unchanged:
curl https://api.subtoapi.app/v1/messages \
-H "Authorization: Bearer $SUBTOAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4",
"messages": [{"role": "user", "content": "Whats the weather in Lisbon?"}],
"tools": [{"name": "get_weather", "description": "Get current weather", "input_schema": {"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}}]
}'
Each application gets its own sub_live_ key, usage is visible per key in the dashboard, and streaming works alongside tool use if you need partial responses while the agent loop runs. See the tool use docs and messages reference for request details, or check the quickstart to get a key from the pricing page.
Practical Tips Across All Examples
- Keep tool descriptions specific — vague descriptions cause Claude to pick the wrong tool or skip calling one it should use.
- Return errors as tool results, not thrown exceptions, so Claude can explain the failure to the user instead of the request crashing.
- Validate
tool_use.inputagainst your schema server-side before executing — Claude is reliable but not infallible, and this is your real security boundary. - Cap agent loops with a max step count to avoid runaway tool-calling chains.
FAQ
Is function calling the same as tool use in the Claude API? Yes, "function calling" is the general industry term; Anthropic's documentation and API fields call it "tool use." The mechanics — defining a schema, receiving a tool_use block, returning a tool_result — are identical regardless of which term you use.
Can Claude call multiple tools in one response? Yes. Claude can return several tool_use blocks in a single response when a task needs parallel lookups (e.g., checking weather in three cities at once). Execute each one and return all results before continuing the conversation.
Does streaming work with tool use? Yes, tool-use responses can be streamed, but the tool_use input arrives as accumulated JSON deltas you need to parse once complete, not usable mid-stream. See the streaming docs for the event format.