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
| Code | Description |
|---|---|
| 0 | Clear sky |
| 1, 2, 3 | Mainly clear, partly cloudy, overcast |
| 45, 48 | Fog and depositing rime fog |
| 51, 53, 55 | Drizzle: Light, moderate, dense |
| 61, 63, 65 | Rain: Slight, moderate, heavy |
| 66, 67 | Freezing Rain: Light, heavy |
| 71, 73, 75 | Snowfall: Slight, moderate, heavy |
| 77 | Snow grains |
| 80, 81, 82 | Rain showers: Slight, moderate, violent |
| 85, 86 | Snow showers: Slight, heavy |
| 95 | Thunderstorm |
| 96, 99 | Thunderstorm with hail |
Unit Options
Temperature
| Unit | Description |
|---|---|
.celsius | Celsius (°C) |
.fahrenheit | Fahrenheit (°F) |
Wind Speed
| Unit | Description |
|---|---|
.kmh | Kilometers per hour |
.mph | Miles per hour |
.ms | Meters per second |
.knots | Knots |
Precipitation
| Unit | Description |
|---|---|
.mm | Millimeters |
.inch | Inches |
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.