DEV Community

Alex Spinov
Alex Spinov

Posted on

Open-Meteo API: Free Weather Data for Any Location (No Key, No Limits, No BS)

Why I Stopped Paying for Weather APIs

I was paying $40/month for a weather API. Then I found Open-Meteo — completely free, no API key, no rate limits, and the data is actually better.

  • Global coverage — any latitude/longitude on Earth
  • 16-day forecast + historical data back to 1940
  • 80+ weather variables (temperature, rain, wind, UV, air quality)
  • No API key — just make HTTP requests
  • No rate limits for non-commercial use

Get Current Weather (3 Lines)

import requests

resp = requests.get("https://api.open-meteo.com/v1/forecast", params={
    "latitude": 40.71, "longitude": -74.01,  # New York
    "current_weather": True
})

weather = resp.json()["current_weather"]
print(f"Temperature: {weather['temperature']}°C")
print(f"Wind: {weather['windspeed']} km/h")
print(f"Condition: {'Sunny' if weather['weathercode'] == 0 else 'See code ' + str(weather['weathercode'])}")
Enter fullscreen mode Exit fullscreen mode

5-Day Forecast with Hourly Data

resp = requests.get("https://api.open-meteo.com/v1/forecast", params={
    "latitude": 51.51, "longitude": -0.13,  # London
    "hourly": "temperature_2m,precipitation_probability,windspeed_10m",
    "forecast_days": 5
})

data = resp.json()["hourly"]
for i in range(0, len(data["time"]), 6):  # Every 6 hours
    time = data["time"][i]
    temp = data["temperature_2m"][i]
    rain = data["precipitation_probability"][i]
    wind = data["windspeed_10m"][i]
    print(f"{time}: {temp}°C, {rain}% rain, {wind} km/h wind")
Enter fullscreen mode Exit fullscreen mode

Historical Weather (Back to 1940!)

resp = requests.get("https://archive-api.open-meteo.com/v1/archive", params={
    "latitude": 48.85, "longitude": 2.35,  # Paris
    "start_date": "2025-01-01",
    "end_date": "2025-01-31",
    "daily": "temperature_2m_max,temperature_2m_min,precipitation_sum"
})

daily = resp.json()["daily"]
for i in range(len(daily["time"])):
    date = daily["time"][i]
    high = daily["temperature_2m_max"][i]
    low = daily["temperature_2m_min"][i]
    rain = daily["precipitation_sum"][i]
    print(f"{date}: {low}{high}°C, {rain}mm rain")
Enter fullscreen mode Exit fullscreen mode

Air Quality Index

resp = requests.get("https://air-quality-api.open-meteo.com/v1/air-quality", params={
    "latitude": 39.90, "longitude": 116.40,  # Beijing
    "hourly": "pm2_5,pm10,us_aqi",
    "forecast_days": 1
})

data = resp.json()["hourly"]
for i in range(0, 24, 3):
    print(f"{data['time'][i]}: AQI={data['us_aqi'][i]}, PM2.5={data['pm2_5'][i]}")
Enter fullscreen mode Exit fullscreen mode

Geocoding (City Name → Coordinates)

def get_coordinates(city):
    resp = requests.get("https://geocoding-api.open-meteo.com/v1/search", params={
        "name": city, "count": 1
    })
    result = resp.json()["results"][0]
    return result["latitude"], result["longitude"], result["name"], result["country"]

lat, lon, name, country = get_coordinates("Tokyo")
print(f"{name}, {country}: {lat}, {lon}")

# Now get weather
resp = requests.get("https://api.open-meteo.com/v1/forecast", params={
    "latitude": lat, "longitude": lon, "current_weather": True
})
print(f"Temperature: {resp.json()['current_weather']['temperature']}°C")
Enter fullscreen mode Exit fullscreen mode

Build a Weather CLI Tool

#!/usr/bin/env python3
import requests, sys

def weather(city):
    # Geocode
    geo = requests.get("https://geocoding-api.open-meteo.com/v1/search",
                       params={"name": city, "count": 1}).json()
    if not geo.get("results"):
        print(f"City not found: {city}")
        return
    loc = geo["results"][0]

    # Weather
    w = requests.get("https://api.open-meteo.com/v1/forecast", params={
        "latitude": loc["latitude"], "longitude": loc["longitude"],
        "current_weather": True,
        "daily": "temperature_2m_max,temperature_2m_min,precipitation_sum",
        "timezone": "auto", "forecast_days": 3
    }).json()

    cw = w["current_weather"]
    print(f"\n{loc['name']}, {loc.get('country', '')} — Now:")
    print(f"  {cw['temperature']}°C, wind {cw['windspeed']} km/h")
    print(f"\n3-day forecast:")
    for i in range(3):
        d = w["daily"]
        print(f"  {d['time'][i]}: {d['temperature_2m_min'][i]}{d['temperature_2m_max'][i]}°C, rain: {d['precipitation_sum'][i]}mm")

city = sys.argv[1] if len(sys.argv) > 1 else input("City: ")
weather(city)
Enter fullscreen mode Exit fullscreen mode

Usage: python3 weather.py "San Francisco"

All Available Variables

Category Variables
Temperature temperature_2m, apparent_temperature, dewpoint_2m
Precipitation rain, snowfall, precipitation_probability
Wind windspeed_10m, windgusts_10m, winddirection_10m
Solar uv_index, sunshine_duration, shortwave_radiation
Pressure surface_pressure, pressure_msl
Cloud cloudcover, cloudcover_low/mid/high
Soil soil_temperature_0cm, soil_moisture_0_to_1cm

Comparison with Paid APIs

Feature Open-Meteo OpenWeather WeatherAPI
Price Free Free tier + paid Free tier + paid
API Key Not needed Required Required
Rate Limit None* 60/min (free) 1M/month
Forecast Days 16 5 (free) 3 (free)
Historical Data 1940–now Paid only Paid only
Air Quality Free Paid only Paid only
Variables 80+ 20+ 30+

*Fair use policy applies for non-commercial use.


What do you build with weather data? I'm always looking for creative API use cases.

I write about free APIs and developer tools every week. Follow for more practical tutorials.


More from me: 10 Dev Tools I Use Daily | 77 Scrapers on a Schedule | 150+ Free APIs


Building something with free APIs? I write about developer tools and free APIs every week. Follow for more.

Need automated data collection or a custom scraper? Email me at spinov001@gmail.com

Top comments (0)