Skip to main content

Weather Stations API CORE

Preview

This guide covers the Weather Stations API v2, which is currently in preview and not yet publicly listed. The specification is under active review and may change before general availability.

The Platform Guides for authentication, error handling, and rate limits apply to this API.

Help shape it before general availability

Tell us what you're trying to do and what's missing. It takes under a minute.

You can reopen this prompt anytime from this box.

Integration fact sheet
Auth typeAPI accessBase URLProtocol
API KeyManual requesthttps://api.observations.metservice.comREST

VariablesCoverageHorizonInterval
Air temp, wind (speed/direction/gust/lull), pressure, humidity, rainfall, solar, soil, cloud, visibility, road conditionsNZ physical station network (AWS + road sensors) (Coverage Map)Near real-time (1–2 min ingest delay) + up to 60 days history1min, 10min, hourly, 3hr

Full endpoint reference, with live try-it console: Technical Reference

The Weather Stations API v2 provides near real-time and recent observation data from MetService's physical hardware network across New Zealand (data is typically available within 1–2 minutes of observation due to the ingest process). It replaces the 1-Minute Observations API, consolidating single-station and multi-station access, fragmented temporal query modes (/latest, /range, /last/{n}/minutes), and region-specific path segments (/nz/) under one consistent, versioned resource family.

Because it is built on the MetService public API platform, it shares the same authentication model, error contract, and developer experience as the other Core APIs — including the interactive API explorer in the Technical Reference.

Key features​

  • Single-station and bulk access — dedicated endpoints for both the common one-station case and high-volume multi-station consumers
  • Flexible time windowing — absolute date ranges (from_date_time/to_date_time) or a rolling relative window (last_minutes)
  • Observation interval control — set the spacing between returned observations to 1min, 10min, hourly, or 3hr via the timestep parameter. Omit it and you get the finest interval your key is entitled to
  • Auth-driven bulk latest — a single call to the bulk latest endpoint returns the latest observation for every station your key is entitled to, with no station list to supply
  • Self-describing variable names — aggregation window baked into every field name (e.g. wind_speed_10min_mean, rainfall_1h_sum)

Authentication​

To use this API you must first Request Access to receive an API key.

Pass the key on every request using the Authorization header:

curl -H "Authorization: Bearer <your_key>" \
"https://api.observations.metservice.com/weather-stations/v2/stations/NZWNA"

Requests without a valid key return 401 Unauthorized. A valid key without entitlement for the requested station returns 403 Forbidden.

Quick start​

  1. Get access — submit a request via the Request Access form.
  2. Browse the station catalog — GET /weather-stations/v2/stations
  3. Fetch the latest observation for a station — GET /weather-stations/v2/stations/NZWNA/observations/latest
  4. Query a time window — GET /weather-stations/v2/stations/NZWNA/observations?last_minutes=60
  5. Fetch all your entitled stations at once — GET /weather-stations/v2/stations/observations/latest

Example calls​

# Browse the station catalog
curl -H "Authorization: Bearer <your_key>" \
"https://api.observations.metservice.com/weather-stations/v2/stations"

# Get the latest observation for Wellington Airport
curl -H "Authorization: Bearer <your_key>" \
"https://api.observations.metservice.com/weather-stations/v2/stations/NZWNA/observations/latest"

# Get the last 30 minutes of data for Auckland Airport, temperature and wind only
curl -H "Authorization: Bearer <your_key>" \
"https://api.observations.metservice.com/weather-stations/v2/stations/NZAAA/observations?last_minutes=30&variables=air_temperature_1min_mean,wind_speed_1min_mean,wind_from_direction_1min_mean"

# Get hourly data for a specific date range
curl -H "Authorization: Bearer <your_key>" \
"https://api.observations.metservice.com/weather-stations/v2/stations/93110/observations?from_date_time=2026-08-18T00:00:00Z&to_date_time=2026-08-18T12:00:00Z&timestep=hourly"

# Get the latest observation across all entitled stations (bulk)
curl -H "Authorization: Bearer <your_key>" \
"https://api.observations.metservice.com/weather-stations/v2/stations/observations/latest"

Building a request​

Every URL above has two parts that do different jobs. The path segment identifies which station; everything after the ? shapes what comes back:

/weather-stations/v2/stations/NZWNA/observations?last_minutes=60&timestep=10min
^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
path parameter query parameters

The table below is an orientation map, not the parameter contract — for exact types, defaults, and validation rules, follow each link to the Technical Reference.

ParameterControlsWhere
station_idWhich station (path segment, single-station endpoints)Path
from_date_time / to_date_timeAbsolute time windowQuery
last_minutesRolling relative time window, anchored to the server clockQuery
timestepRow cadence — how many observations come backQuery
variablesWhich fields appear in each observationQuery
qFree-text station search (catalogue endpoint only)Query

Choosing a time window​

last_minutes and from_date_time/to_date_time are two ways of expressing the same idea — combining them in one request returns 400 Bad Request. Pick based on what you're building:

  • last_minutes — for polling loops and live dashboards. The server anchors the window to its own clock, so you never compute or store a timestamp between requests.
  • from_date_time / to_date_time — for a fixed historical range, or for paging through more data than a single request's range cap allows.
  • Neither parameter is accepted on the /latest endpoints — they always return the single most recent observation.

Migrating an existing integration from the legacy 1-Minute Observations API? See the Legacy Migration guide for the full request and variable-name mapping.

timestep vs variables​

These sound similar but control different axes of the response: timestep controls how many rows come back (the time spacing between observations); variables controls which fields appear in each row. Use them together freely — for example timestep=hourly with variables=air_temperature_1min_mean to get one row per hour, temperature only.

Response format​

All observation endpoints return the same structure. The per-variable units map and a generated_at timestamp are shared by the whole response, so they sit once at the top level. Each response then identifies its station by station_id and carries a state block with that station's position; observation data follows as either an array (time-series endpoints) or a single object (/latest endpoints). The rest of the static station metadata (name, elevation, magnetic declination, and both identifiers, wmo_id and icao_id) is not repeated in observation responses — fetch it once from the catalogue (GET /stations or GET /stations/{station_id}) and cache it. Within a time-series, observations are returned most-recent-first (descending by observation_time).

Because units are a property of the variable (not the station) they are stated only once, which keeps high-frequency polling responses lean.

generated_at is the UTC time the API generated the response. Comparing it against observation_time (generated_at − observation_time) tells you how far behind real time the returned data is, with your own network round-trip excluded — the same freshness signal the legacy API provided via request-time.

For the full list of observation variables — with their units, data types, and examples — see the Variables reference.

{
"generated_at": "2026-08-18T12:00:00Z",
"units": {
"air_temperature_1min_mean": "degC",
"air_temperature_1h_max": "degC",
"air_temperature_1h_min": "degC",
"wind_speed_1min_mean": "kn",
"wind_speed_10min_mean": "kn",
"wind_from_direction_1min_mean": "degrees_true",
"wind_gust_speed_10min_max": "kn",
"wind_lull_speed_1min_min": "kn",
"sea_level_pressure_1min_mean": "hPa",
"relative_humidity_1min_mean": "%",
"rainfall_1min_sum": "mm",
"rainfall_1h_sum": "mm",
"visibility_1min_mean": "m"
},
"station_id": "NZWNA",
"state": {
"latitude": -41.3278,
"longitude": 174.8056
},
"observations": [
{
"observation_time": "2026-08-18T11:59:00Z",

"air_temperature_1min_mean": 12.4,
"air_temperature_1h_max": 13.1,
"air_temperature_1h_min": 11.8,

"wind_speed_1min_mean": 18.5,
"wind_speed_10min_mean": 17.2,
"wind_from_direction_1min_mean": 220,
"wind_gust_speed_10min_max": 24.0,
"wind_lull_speed_1min_min": 14.3,

"sea_level_pressure_1min_mean": 1008.6,
"relative_humidity_1min_mean": 82.0,

"rainfall_1min_sum": 0.2,
"rainfall_1h_sum": 1.4,

"visibility_1min_mean": 18500,
"snow_depth_1min_mean": null
}
]
}

Static station details for NZWNA (name, elevation, both identifiers, magnetic declination) come from the catalogue endpoint and are cached client-side, so they do not travel with every observation response.

Observation timestamps​

The observation_time field is the right-closed window label per WMO convention. A 10-minute mean ending at 10:10 UTC is labelled 10:10:00Z — it represents the period 10:00–10:10, not the moment of recording.

Missing data​

All observation fields are nullable. A null value means no data was received from the sensor at that timestamp — it is not zero. Plan your parsing accordingly.

Station capabilities​

The station catalogue doesn't currently list which variables a station provides, how often it reports, or whether it is operating. To find out which variables a station provides, request its latest observation and check which fields come back with a value. A field with no value (null) means no data was received for it at that time, which can mean the station doesn't measure it or that it didn't report. We'd like to add station capabilities to the catalogue in future.

Road variables​

Road weather variables (road surface temperature, water film height, condition codes, and similar) are not part of the selectable variables list. They are entitlement-gated: if your API key has road-sensor access, they are returned automatically for stations that have road sensors. You do not request them via the variables parameter, and they will not appear for keys without the entitlement.

Bulk response shape​

The bulk latest endpoint (GET /stations/observations/latest) keeps generated_at and the shared units map at the top level, then lists one lean block per station. Each block carries station_id and its observations — units are not repeated per station:

{
"generated_at": "2026-08-18T12:00:00Z",
"station_count": 2,
"units": {
"air_temperature_1min_mean": "degC",
"wind_speed_1min_mean": "kn"
},
"stations": [
{
"station_id": "NZWNA",
"state": { "latitude": -41.3278, "longitude": 174.8056 },
"observations": [
{ "observation_time": "2026-08-18T11:59:00Z", "air_temperature_1min_mean": 14.6, "wind_speed_1min_mean": 12.5 }
]
},
{
"station_id": "NZAAA",
"state": { "latitude": -37.0082, "longitude": 174.7850 },
"observations": [
{ "observation_time": "2026-08-18T11:59:00Z", "air_temperature_1min_mean": 17.2, "wind_speed_1min_mean": 8.0 }
]
}
]
}

Every station block carries a state object holding that station's latitude and longitude. It is always present, on both the single-station and bulk shapes, so you can parse it without checking whether it exists — for every station in the current network, these are static coordinates, which saves you a catalogue lookup just to place an observation on a map.

Range cap​

Every query returns at most 1440 observations, validated before any data is fetched, and the time window is capped at 24 hours (1440 minutes) per request. For a single station that means up to 1440 observations — a full 24 hours at 1min, or the same window at a coarser timestep (which simply returns fewer observations).

The bulk latest endpoint (GET /stations/observations/latest) returns one observation per station and accepts no time parameters, so the range cap does not apply to it. There is no bulk time-series endpoint. To retrieve time-series data for several stations, call the single-station observations endpoint once per station.

Observations are available for the most recent 60 days. Queries for earlier periods return no observations. Within that 60-day window, the range cap limits how much a single request can return, so retrieve longer stretches by paging through successive windowed requests (each within the cap) using from_date_time/to_date_time.

Station identifiers​

A station can be addressed by either of two identifiers, so you can use whichever form your systems already hold:

FormExampleNotes
WMO ID93439Numeric World Meteorological Organisation identifier
MetService Station IDNZWNA5-character alphanumeric code

Both resolve to the same station in the {station_id} path segment. If your systems hold a four-character airport code such as NZWN, use the station's MetService Station ID instead (NZWNA for Wellington Airport). The Coverage Map shows it for each station.

To find a station's identifiers without calling the API, open its marker on the Coverage Map. The map shows open-access stations only.

An identifier must be exactly 5 characters (5 digits or 5 letters); any other format returns 400 Bad Request. Catalogue responses include both identifiers, in wmo_id and icao_id, so you can map between the two forms.

Technical reference​

For the full endpoint reference — request parameters, response schemas, and a live try-it console — see the generated specification:

Weather Stations API v2 — Technical Reference

You can also download the OpenAPI specification.

For a plain-language dictionary of every observation variable — its unit, data type, and an example value — see the Variables reference.

If you're migrating from the legacy 1-Minute Observations API, see the Legacy Migration guide.

Support​

For technical support or access requests, visit our Support & Help Centre.