None of these requests need an account. The shell examples use jq to filter JSON.
Find a station
Raindrop identifies stations by UUID. GET /stations/map/details returns every station keyed by ID. The window=1d parameter limits it to stations that reported in the last day. This finds the NAV CANADA station at London, Ontario:
curl -s --compressed "https://raindrop.cssl.ca/api/v1/stations/map/details?window=1d" \
| jq 'to_entries[]
| select(.value.name == "London")
| {id: .key, network: .value.network}'{
"id": "12efaad4-2ddd-42c1-bba2-0c00031e4a98",
"network": "NAV CANADA"
}Get the latest readings
POST /stations/readings returns the most recent reading of each requested variable for the stations you name:
curl -s --compressed -X POST \
"https://raindrop.cssl.ca/api/v1/stations/readings?names=airTemperature,dewPointTemperature,windSpeed10m" \
-H "Content-Type: application/json" \
-d '{"stationIds": ["12efaad4-2ddd-42c1-bba2-0c00031e4a98"]}'{
"stations": {
"12efaad4-2ddd-42c1-bba2-0c00031e4a98": {
"readings": [
{
"timestamp": "2026-09-24T19:00:00Z",
"type": "airTemperature",
"typeId": 560,
"value": 19.7,
"quality": { "baseQuality": "Good", "reasonQuality": "None" }
},
{
"timestamp": "2026-09-24T19:00:00Z",
"type": "windSpeed10m",
"typeId": 38094,
"value": 19.8,
"quality": { "baseQuality": "Good", "reasonQuality": "None" }
}
]
}
}
}Temperatures are in °C and wind speeds in km/h. GET /observations/units lists the unit for every variable.
Pull a time series
For one variable over a time range, use POST /observations/series:
curl -s --compressed -X POST \
"https://raindrop.cssl.ca/api/v1/observations/series?start=2026-09-24T00:00:00Z&end=2026-09-24T23:59:59Z" \
-H "Content-Type: application/json" \
-d '{"stationId": "12efaad4-2ddd-42c1-bba2-0c00031e4a98", "name": "airTemperature"}' \
| jq -c '.readings[] | [.timestamp, .value]'import requests
res = requests.post(
"https://raindrop.cssl.ca/api/v1/observations/series",
params={"start": "2026-09-24T00:00:00Z", "end": "2026-09-24T23:59:59Z"},
json={"stationId": "12efaad4-2ddd-42c1-bba2-0c00031e4a98", "name": "airTemperature"},
)
res.raise_for_status()
for reading in res.json()["readings"]:
print(reading["timestamp"], reading["value"])const params = new URLSearchParams({
start: '2026-09-24T00:00:00Z',
end: '2026-09-24T23:59:59Z',
});
const res = await fetch(`https://raindrop.cssl.ca/api/v1/observations/series?${params}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
stationId: '12efaad4-2ddd-42c1-bba2-0c00031e4a98',
name: 'airTemperature',
}),
});
const series = await res.json();
for (const r of series.readings) console.log(r.timestamp, r.value);Without an account the window can be at most 7 days and must end within the last 7 days. See time windows.
Get a forecast from Cyclone
Cyclone serves model output as 256×256 data tiles of packed 16-bit integers. This script reads the RDPS 2 m temperature forecast for London six hours into the latest run:
import math
import requests
import numpy as np
BASE = "https://cyclone.cssl.ca/models/rdps"
run = requests.get(f"{BASE}/runs").json()["runs"][0]
products = {p["name"]: p for p in requests.get(f"{BASE}/products").json()["products"]}
enc = products["T2m"]["encoding"]
# Find the Web Mercator tile and pixel that contain London, Ontario.
lat, lon, z = 43.03, -81.15, 6
n = 2**z
x = (lon + 180) / 360 * n
y = (1 - math.asinh(math.tan(math.radians(lat))) / math.pi) / 2 * n
res = requests.get(f"{BASE}/products/T2m/data/{z}/{int(x)}/{int(y)}", params={"run": run, "hour": 6})
res.raise_for_status()
tile = np.frombuffer(res.content, dtype="<i2").reshape(enc["height"], enc["width"])
raw = tile[int(y % 1 * enc["height"]), int(x % 1 * enc["width"])]
if raw != enc["nodata"]:
kelvin = raw * enc["scale"] + enc["offset"]
print(f"RDPS {run}, +6 h: {kelvin - 273.15:.1f} °C")RDPS 20260924T120000Z, +6 h: 18.8 °CMost Cyclone products use SI units, so this temperature is in kelvin. /products lists the unit of every product.
Next steps
- Authentication covers what an account or API key adds.
- The Raindrop API overview covers conventions, limits and errors.
- The Cyclone API overview explains the models and how runs and forecast hours are addressed.