Open-Meteo 🌤️

Free weather API with no API key required.

🌍

What you can do: Current weather, hourly/daily forecasts, historical data, air quality, marine forecasts, and climate projections - all free and open source.

Setup

Open-Meteo is free and requires no API key. Just configure it in your ProtectMyAPI setup.


Current Weather

Basic Weather

let weather = ProtectMyAPI.openMeteoService()
 
let current = try await weather.getCurrentWeather(
    latitude: 37.7749,
    longitude: -122.4194
)
 
print("Temperature: \(current.temperature)°C")
print("Feels like: \(current.apparentTemperature)°C")
print("Humidity: \(current.relativeHumidity)%")
print("Wind: \(current.windSpeed) km/h")
print("Conditions: \(current.weatherDescription)")

With Units

let current = try await weather.getCurrentWeather(
    latitude: 37.7749,
    longitude: -122.4194,
    options: OpenMeteoOptions(
        temperatureUnit: .fahrenheit,
        windSpeedUnit: .mph,
        precipitationUnit: .inch
    )
)
 
print("Temperature: \(current.temperature)°F")

Hourly Forecast

let forecast = try await weather.getHourlyForecast(
    latitude: 37.7749,
    longitude: -122.4194,
    hours: 24 // Next 24 hours
)
 
for hour in forecast.hourly {
    print("\(hour.time):")
    print("  Temperature: \(hour.temperature)°C")
    print("  Precipitation: \(hour.precipitation)mm")
    print("  Conditions: \(hour.weatherDescription)")
}

Daily Forecast

let forecast = try await weather.getDailyForecast(
    latitude: 37.7749,
    longitude: -122.4194,
    days: 7 // Next 7 days
)
 
for day in forecast.daily {
    print("\(day.date):")
    print("  High: \(day.temperatureMax)°C")
    print("  Low: \(day.temperatureMin)°C")
    print("  Sunrise: \(day.sunrise)")
    print("  Sunset: \(day.sunset)")
    print("  UV Index: \(day.uvIndexMax)")
    print("  Rain chance: \(day.precipitationProbability)%")
}

Air Quality

let airQuality = try await weather.getAirQuality(
    latitude: 37.7749,
    longitude: -122.4194
)
 
print("AQI (US): \(airQuality.usAqi)")
print("AQI (European): \(airQuality.europeanAqi)")
print("PM2.5: \(airQuality.pm2_5) µg/m³")
print("PM10: \(airQuality.pm10) µg/m³")
print("Ozone: \(airQuality.ozone) µg/m³")
print("NO2: \(airQuality.nitrogenDioxide) µg/m³")
print("SO2: \(airQuality.sulfurDioxide) µg/m³")
print("CO: \(airQuality.carbonMonoxide) µg/m³")
 
// Pollen data
print("Grass pollen: \(airQuality.grassPollen)")
print("Tree pollen: \(airQuality.alderPollen)")
print("Ragweed pollen: \(airQuality.ragweedPollen)")

Marine Forecast

For ocean and coastal conditions:

let marine = try await weather.getMarineForecast(
    latitude: 37.7749,
    longitude: -122.4194,
    days: 7
)
 
for day in marine.daily {
    print("\(day.date):")
    print("  Wave height: \(day.waveHeight)m")
    print("  Wave direction: \(day.waveDirection)°")
    print("  Wave period: \(day.wavePeriod)s")
    print("  Ocean temperature: \(day.seaSurfaceTemperature)°C")
}
 
for hour in marine.hourly {
    print("\(hour.time):")
    print("  Swell height: \(hour.swellHeight)m")
    print("  Swell direction: \(hour.swellDirection)°")
}

Historical Weather

Get weather data for past dates:

let historical = try await weather.getHistoricalWeather(
    latitude: 37.7749,
    longitude: -122.4194,
    startDate: "2024-01-01",
    endDate: "2024-01-07"
)
 
for day in historical.daily {
    print("\(day.date):")
    print("  High: \(day.temperatureMax)°C")
    print("  Low: \(day.temperatureMin)°C")
    print("  Rain: \(day.precipitation)mm")
}

Geocoding

Convert location names to coordinates:

let locations = try await weather.searchLocation(name: "San Francisco")
 
for location in locations {
    print("\(location.name), \(location.country)")
    print("  Coordinates: \(location.latitude), \(location.longitude)")
    print("  Population: \(location.population ?? 0)")
    print("  Timezone: \(location.timezone)")
}

Complete Weather

Get all weather data in one call:

let complete = try await weather.getCompleteWeather(
    latitude: 37.7749,
    longitude: -122.4194,
    options: OpenMeteoCompleteOptions(
        current: true,
        hourlyHours: 24,
        dailyDays: 7,
        airQuality: true
    )
)
 
print("Current: \(complete.current.temperature)°C")
print("Hourly forecast: \(complete.hourly.count) hours")
print("Daily forecast: \(complete.daily.count) days")
print("Air quality: AQI \(complete.airQuality?.usAqi ?? 0)")

Weather Codes

CodeDescription
0Clear sky
1, 2, 3Mainly clear, partly cloudy, overcast
45, 48Fog and depositing rime fog
51, 53, 55Drizzle: Light, moderate, dense
61, 63, 65Rain: Slight, moderate, heavy
66, 67Freezing Rain: Light, heavy
71, 73, 75Snowfall: Slight, moderate, heavy
77Snow grains
80, 81, 82Rain showers: Slight, moderate, violent
85, 86Snow showers: Slight, heavy
95Thunderstorm
96, 99Thunderstorm with hail

Unit Options

Temperature

UnitDescription
.celsiusCelsius (°C)
.fahrenheitFahrenheit (°F)

Wind Speed

UnitDescription
.kmhKilometers per hour
.mphMiles per hour
.msMeters per second
.knotsKnots

Precipitation

UnitDescription
.mmMillimeters
.inchInches

Pricing

Open-Meteo is FREE for non-commercial use:

  • No API key required
  • Unlimited requests (fair use)
  • All features included

For commercial use, check their API documentation.