API reference
Weather
Forecasts, air quality and place search, and your saved places and units.
See Weather. Weather is personal: these routes take no organization, and a key needs weather:read in its own. Show "Weather data by Open-Meteo.com" (the answer's source.attribution, linking to source.url) wherever you show the data.
GET /v1/weather/forecast
The forecast at a point: current conditions, today, hours hourly (1–48, default 24, from the current hour) and days daily (1–16, default 10, from today in the place's time zone), air quality where there is some, and the attribution to show with it. Cached for 10 minutes per 1 km cell. units (metric or imperial) defaults to the person's saved choice. place names the caller's saved place within 1.5 km. 429 (with Retry-After) past the per-person limits.
Auth: user access token or platform agent key · Scope: weather:read
| Query parameter | Type | Required | Notes |
|---|---|---|---|
lat | number | Yes | -90–90; coerced from a string |
lon | number | Yes | -180–180; coerced from a string |
units | "metric" | "imperial" | No | |
days | integer | No | 1–16; coerced from a string |
hours | integer | No | 1–48; coerced from a string |
Response 200
{
at: number
timeZone: string
units: {
temperature: "C" | "F"
wind: "km/h" | "mph"
precipitation: "in" | "mm"
}
place?: {
name: string
region?: string
country?: string
}
current: {
temp: number
feelsLike: number
humidity: number
windSpeed: number
windGust?: number
windDir: number
windCompass: string
pressure?: number
uv?: number
precip: number
cloud: number
visibility?: number
isDay: boolean
code: number
condition: string
symbol: string
icon: "cloud" | "sunny" | "bedtime" | "partly-cloudy-day" | "partly-cloudy-night" | "foggy" | "rainy-light" | "rainy" | "rainy-heavy" | "weather-mix" | "weather-snowy" | "snowing-heavy" | "grain" | "thunderstorm"
}
today: {
high: number
low: number
precipChance: number
precipSum: number
sunrise: number
sunset: number
uvMax?: number
windMax?: number
}
hourly: {
at: number
temp: number
precipChance: number
precip: number
code: number
symbol: string
icon: "cloud" | "sunny" | "bedtime" | "partly-cloudy-day" | "partly-cloudy-night" | "foggy" | "rainy-light" | "rainy" | "rainy-heavy" | "weather-mix" | "weather-snowy" | "snowing-heavy" | "grain" | "thunderstorm"
windSpeed: number
isDay: boolean
}[]
daily: {
date: string
high: number
low: number
precipChance: number
precipSum: number
code: number
condition: string
symbol: string
icon: "cloud" | "sunny" | "bedtime" | "partly-cloudy-day" | "partly-cloudy-night" | "foggy" | "rainy-light" | "rainy" | "rainy-heavy" | "weather-mix" | "weather-snowy" | "snowing-heavy" | "grain" | "thunderstorm"
sunrise: number
sunset: number
windMax: number
uvMax?: number
}[]
airQuality?: {
aqi: number
pm25?: number
category: "Good" | "Fair" | "Moderate" | "Poor" | "Very poor" | "Extremely poor"
}
source: {
id: string
name: string
attribution: string
url: string
}
}Errors
| Status | Message |
|---|---|
400 | Give lat and lon. |
GET /v1/weather/places/search
Places by name or postcode, best first (count 1–10, default 5); "Name, region or country" narrows. Each has a placeId (gn: and its GeoNames id) to save it with. Fewer than 2 characters find nothing.
Auth: user access token or platform agent key · Scope: weather:read
| Query parameter | Type | Required | Notes |
|---|---|---|---|
q | string | Yes | up to 100 characters |
count | integer | No | 1–10; coerced from a string |
Response 200
{
results: {
placeId: string
name: string
region?: string
country?: string
lat: number
lon: number
timeZone?: string
}[]
}GET /v1/me/weather/places
Your saved places in your order, and your units (metric until you choose). The same on every device.
Auth: user access token or platform agent key · Scope: weather:read
Response 200
{
places: {
placeId: string
name: string
region?: string
country?: string
lat: number
lon: number
timeZone: string
}[]
units: "metric" | "imperial"
updatedAt?: number
}Errors
| Status | Message |
|---|---|
403 | Saved places belong to people, not keys. |
PUT /v1/me/weather/places
Replaces your saved places with places, in order (up to the weather.places limit, 20 by default), and sets units when given. A place without a placeId gets one (wpl_…). Coordinates are kept to 3 decimals. Not from an assistant.
Auth: user access token or platform agent key · Scope: weather:write
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
places | object[] | Yes | up to 100 items |
places[].placeId | string | No | matches ^[A-Za-z0-9:_.-]{1,64}$ |
places[].name | string | Yes | 1–100 characters; trimmed |
places[].region | string | No | up to 100 characters; trimmed |
places[].country | string | No | up to 100 characters; trimmed |
places[].lat | number | Yes | -90–90 |
places[].lon | number | Yes | -180–180 |
places[].timeZone | string | Yes | 1–64 characters |
units | "metric" | "imperial" | No |
Response 200
{
places: {
placeId: string
name: string
region?: string
country?: string
lat: number
lon: number
timeZone: string
}[]
units: "metric" | "imperial"
updatedAt?: number
}Errors
| Status | Message |
|---|---|
403 | Saved places belong to people, not keys. |
403 | Change your places in the Weather app. |