Claude can reason about weather, but without access to live data, it can’t verify current conditions. Connecting it to Weatherstack’s API gives your AI agent access to actual weather data instead of relying on guesses.
This tutorial shows how to integrate Weatherstack with Claude tool use in Python, from defining a function schema and fetching current weather to building an agent loop that returns real API data.
It is the weather sibling to our Marketstack stock-data agent. Same pattern, different API.
Table of Contents
Why can’t Claude get live weather on its own?
Because live data is not in the model’s training data. Ask Claude for today’s weather with no tools, and it will invent something plausible and be wrong.
Tool use closes that gap. You describe a function, Claude decides when to call it, your code runs it against a live API, and Claude answers from the real response.
Weather is the ideal first tool. The input is one string, the output is one JSON object, and the payoff is obvious the second you run it.
Agents are moving into production quickly, and the fastest way to make one trustworthy is to back its answers with a real source instead of the model’s best guess.
What does the Weatherstack current weather endpoint return?
It returns the current conditions for a location as JSON. The request is a single GET call:
https://api.weatherstack.com/current
? access_key = YOUR_ACCESS_KEY
& query = New York
Two parameters are required: access_key from your dashboard, and query for the location. The query accepts a city name, a ZIP code, latitude and longitude, or an IP address.
Here’s an example response published by Weatherstack for New York, dated September 7, 2019. It shows the structure and fields returned by the current weather endpoint.
{
"request": {
"type": "City",
"query": "New York, United States of America",
"language": "en",
"unit": "m"
},
"location": {
"name": "New York",
"country": "United States of America",
"region": "New York",
"lat": "40.714",
"lon": "-74.006",
"timezone_id": "America/New_York",
"localtime": "2019-09-07 08:14",
"localtime_epoch": 1567844040,
"utc_offset": "-4.0"
},
"current": {
"observation_time": "12:14 PM",
"temperature": 13,
"weather_code": 113,
"weather_icons": [
"https://assets.weatherstack.com/images/wsymbols01_png_64/wsymbol_0001_sunny.png"
],
"weather_descriptions": ["Sunny"],
"wind_speed": 0,
"wind_degree": 349,
"wind_dir": "N",
"pressure": 1010,
"precip": 0,
"humidity": 90,
"cloudcover": 0,
"feelslike": 13,
"uv_index": 4,
"visibility": 16
}
}
The fields you will reach for most are temperature, weather_descriptions, humidity, and wind_speed. The weather_code maps to a fixed set of conditions if you want to render your own icons.
Temperatures are Celsius by default. Add &units=f for Fahrenheit. Paid plans add astro and air_quality blocks to the same response. If you hit your monthly cap, Weatherstack returns an error object with the type usage_limit_reached instead of weather data, so check for that in production.
How do you define the weather tool for Claude?
You hand Claude a JSON schema that names the function and its inputs. This is the schema for get_current_weather:
tools = [
{
"name": "get_current_weather",
"description": "Get the current weather conditions for a city or location.",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name, e.g. 'Tokyo' or 'New York'",
}
},
"required": ["location"],
},
}
]
The description is the part worth getting right. Claude reads it to decide when to call the tool, so name exactly what it returns. The input_schema is plain JSON Schema, and Claude fills in location from the user’s question without inventing fields you did not define.
What does the full agent loop look like?
It is a short loop: send the message, check if Claude wants the tool, run it, send the result back, print the answer. Here is the whole thing.
import os
import json
import requests
import anthropic
client = anthropic.Anthropic() # reads ANTHROPIC_API_KEY
WS_KEY = os.environ["WEATHERSTACK_KEY"]
def get_current_weather(location):
res = requests.get(
"https://api.weatherstack.com/current",
params={"access_key": WS_KEY, "query": location},
)
return json.dumps(res.json())
tools = [
{
"name": "get_current_weather",
"description": "Get the current weather conditions for a city or location.",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name, e.g. 'Tokyo' or 'New York'",
}
},
"required": ["location"],
},
}
]
messages = [{"role": "user", "content": "What's the weather in Tokyo right now?"}]
while True:
reply = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
tools=tools,
messages=messages,
)
if reply.stop_reason != "tool_use":
break
messages.append({"role": "assistant", "content": reply.content})
tool_results = []
for block in reply.content:
if block.type == "tool_use":
weather = get_current_weather(block.input["location"])
tool_results.append(
{
"type": "tool_result",
"tool_use_id": block.id,
"content": weather,
}
)
messages.append({"role": "user", "content": tool_results})
print(reply.content[0].text)
Set two environment variables (ANTHROPIC_API_KEY and WEATHERSTACK_KEY), keep them out of your code, then run it. Here is what happens.
Claude reads the question, sees get_current_weather, and stops with a stop_reason of tool_use. The loop catches that, calls Weatherstack, and feeds the raw JSON back as a tool_result. We return it as a string so Claude can read every field. Now Claude has real data, so it stops calling tools and writes a plain answer like “It’s 13C and sunny in Tokyo.” If a request fails, return the error text in the tool_result too, so Claude can tell the user what went wrong instead of guessing.
The loop matters. Ask something that needs no live data, like “what is humidity,” and Claude answers straight away without spending a request. For simpler or higher-volume tools you can swap in a Claude Haiku model for lower cost and latency.
What are the limits of the free tier?
The free plan is built for prototyping, and it has real limits. Be honest about them before you ship.
You get 100 requests a month. That is enough to build and test an agent, not to run one in production.
It covers current weather only. Forecast data needs the Professional plan, and historical data needs the Standard plan. Bulk lookups, asking for several cities in one call, are also a paid feature.
A weather value rarely changes minute to minute, so caching each location for a few minutes stretches the free quota a long way. For anything user-facing, cache responses and upgrade once you outgrow the cap.
Get started
Sign up for Weatherstack’s free tier and get your API key in 30 seconds. 100 requests/month, no credit card required. Get your free API key here.
For the full field list, see the Weatherstack documentation. For the exact request and response shapes, see Anthropic’s tool use documentation. Building something bigger? Here is how APILayer combines Weatherstack and Marketstack in a real-time RAG system.
Explore APILayer Products
Discover APIs for geolocation, finance, aviation, weather, web scraping, AI, and more. Browse APILayer's product catalog to find the right APIs for your application and integrate the data and functionality your project needs.
Explore APILayer ProductsFind the right tools to start building.
Frequently Asked Questions
Does Weatherstack’s free tier work with Claude tool use?
Yes. Claude tool use does not care which API sits behind your function, so the free current endpoint works exactly like a paid one. You are limited only by the free plan’s 100 monthly requests.
Can I use HTTPS with the Weatherstack free plan?
Yes. Weatherstack supports 256-bit HTTPS encryption on every plan, including the free tier, so use https:// in your requests. This was once a paid-only feature, so older tutorials may tell you otherwise.
How many weather requests can I make per month on the free tier?
The free plan includes 100 API requests per month. Failed requests do not count toward the quota, and you can upgrade for higher volumes whenever you need them.
Can I get forecast data through this tool setup?
Not on the free tier. Forecast data requires the Professional plan or higher. Once you upgrade, you can add a second tool for the forecast endpoint and let Claude pick between current and forecast.
Does this approach work with OpenAI function calling too?
Yes. The pattern is identical: define a function schema, let the model return a call, run it, and return the result. Only the schema format and field names differ between the two APIs.
STAY CONNECTED
No deposit bonuses hand new players a small amount of credit or a handful of spins without requiring any payment. They are genuinely free to claim, though the conditions attached are usually stricter than those on standard deposit matches.
The Real Terms Behind No Deposit Offers
The withdrawal ceiling is the detail that decides whether the offer means anything. Players who want the conditions in front of them can spin-fincasino.uk and compare the current promotions properly. Verification requirements still apply in full, so the account setup is identical to one funded with your own money.
| Offer | Typical Value | Max Withdrawal |
|---|---|---|
| Free credit | $10 | $50 |
| Free spins | 20 spins | $100 |
- Treat the offer as a free trial, not a funding source
- Check which games the credit can be used on
Used as a test drive, no deposit credit is genuinely useful, since it shows how a site plays before any money is committed. Used as a strategy it disappoints almost every time. Explore the lobby, form a view on the operator, and move on either way.