Raindrop API

Stations

List stations, look up their metadata, and read their observations.

The station endpoints are split by what they return:

  • /stations/map/markers: where each station is
  • /stations/map/details: what each station is
  • /stations/readings: what each station measured

All three are keyed by station ID. Fetch locations and metadata once, then join readings onto them.

Station locations

GET/api/v1/stations/map/markers

Returns a GeoJSON FeatureCollection with one Point feature for every station on record. Each feature’s id is the station ID, and properties is always empty. The response takes no parameters and only changes when a station is added or moves, so fetch it once and cache it.

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "id": "12efaad4-2ddd-42c1-bba2-0c00031e4a98",
      "geometry": { "type": "Point", "coordinates": [-81.1511, 43.0331] },
      "properties": {}
    }
  ]
}

Station details

GET/api/v1/stations/map/details

Returns metadata for every station, as an object keyed by station ID. Without window it covers the same stations as /stations/map/markers.

windowstringquery

Only include stations that reported within this span of now. Use a whole number of days or hours: 7d, 36h.

{
  "12efaad4-2ddd-42c1-bba2-0c00031e4a98": {
    "network": "NAV CANADA",
    "name": "London",
    "stationType": "OpenCountry",
    "presentWeather": ["No present weather available"],
    "coordinates": [-81.1511, 43.0331],
    "elevation": 10,
    "updateTime": "2026-09-24T19:00:00Z",
    "types": [
      {
        "id": 560,
        "name": "airTemperature",
        "prettyName": "Air Temperature",
        "groupBucketName": "",
        "reportedUnit": "°C",
        "calculated": false,
        "intervalType": "Instantaneous",
        "intervalMinutes": 0,
        "firstAppearance": "2024-11-22T20:00:00Z"
      }
    ],
    "qualities": ["Good"]
  }
}
networkstring

The data provider, as named by the source feed. Examples: MSC, NAV CANADA, ON-MTO, BC-FOR, HYDROQUEBEC, UPEI, HailSTORM and NWS. See Data sources.

namestring

The station name as the provider reports it. Names are only unique within a network.

stationTypestring

Exposure class: OpenCountry, Suburban or OpenWater.

coordinates[number, number]

[longitude, latitude] in decimal degrees.

elevationnumber

Sensor height above ground in metres, not altitude. It’s a fixed value per network, such as 10 m for ECCC stations or 3 m for HailSTORM. It’s 0 when the network doesn’t supply one.

updateTimestring

Time of the station’s most recent report.

typesObservationType[]

The series this station reports. A station can report the same variable more than once, with different averaging intervals. See Series.

qualitiesstring[]

The distinct quality codes of the station’s latest readings over the last 12 hours, worst first. An empty array means the station hasn’t reported any map variables in that time. Use this to hide faulty stations without fetching readings.

One station

GET/api/v1/stations/{stationId}

Returns the details object for a single station, in the same shape as one entry above. Returns 404 if no station has that ID.

Readings in an area

GET/api/v1/stations/readings

Returns readings for every station that reported during the window, optionally limited to a bounding box.

startdatetimequerydefault end − 12 h

Start of the window. Stations are included if they’ve reported since start.

enddatetimequerydefault now

End of the window.

namesstring[]query

Which variables to return. Repeat the parameter (names=a&names=b) or separate names with commas. Defaults to all of: airTemperature, dewPointTemperature, windSpeed10m, windGust10m, windDirection, mslp, seaSurfaceTemperature and seaSurfaceTemperature1m. Any other name returns 400.

minLat, minLon, maxLat, maxLonnumberquery

Bounding box. Pass all four or none. minLon can be greater than maxLon for a box that crosses the antimeridian.

stepintegerquery

Grid spacing in minutes. Leave it out for a snapshot. See Snapshots and grids.

curl -s --compressed \
  "https://raindrop.cssl.ca/api/v1/stations/readings?names=airTemperature&minLat=42&minLon=-83.5&maxLat=46&maxLon=-74.5"
{
  "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" }
        }
      ]
    }
  }
}

Stations with nothing in the window are left out.

stepinteger

The grid spacing actually used, in minutes. Present only when you requested a grid.

readings[].typestring

The variable name.

readings[].typeIdinteger

The series this reading came from. Matches types[].id in the station details, which gives the averaging interval and unit.

readings[].qualityobject

baseQuality and reasonQuality codes. See Quality flags.

readings[].ageinteger

Grid mode only. How many seconds before the grid time the reading was taken.

Snapshots and grids

Without step, you get a snapshot: the latest reading of each series in the window.

With step, you get a grid: one reading per variable at start, start + step, and so on up to end. The grid also includes end itself when the step doesn’t divide the window evenly. Each cell holds the latest reading at or before that time, and age says how old it is.

step is a request, not a guarantee. Responses are capped at 500,000 cells and 2,000 time positions. If your request would exceed that, the server coarsens the grid to a whole multiple of your step rather than failing. Read step from the response rather than assuming it. Asking for fewer names or a smaller area leaves room for a finer grid.

When a station reports a variable at several intervals, each grid cell uses the most instantaneous one that’s current at that time. So a series’ typeId can change from one cell to the next. Look up each cell by its own typeId.

Readings for specific stations

POST/api/v1/stations/readings

The same as the GET form, but you name the stations instead of giving a bounding box. It takes the same start, end, names and step query parameters.

stationIdsstring[]bodyrequired

Station IDs, up to 5,000. An empty list returns an empty stations object.

curl -s --compressed -X POST \
  "https://raindrop.cssl.ca/api/v1/stations/readings?step=60&start=2026-09-24T00:00:00Z&end=2026-09-24T12:00:00Z" \
  -H "Content-Type: application/json" \
  -d '{"stationIds": ["12efaad4-2ddd-42c1-bba2-0c00031e4a98"]}'

Naming fewer stations means fewer series to fit under the cell cap, so this form can return a finer grid than a bounding box would.