Skip to content
Console

Weather API

The weather API (v5) serves station weather observations, rainfall, lightning, and typhoons for Taiwan, plus current weather from the nearest station and hourly township forecasts. The data comes from the Central Weather Administration (CWA), Ministry of Transportation and Communications. The server fetches it on a schedule and stores it as compact JSON. Every endpoint is GET, under the prefix /api/v5/meteor.

Upstream terms
  • Central Weather Administration (CWA): CWA's own data terms (such as the Open Government Data License) also apply; CWA's official releases take precedence.

Where to show it, examples and commercial-use requests: Data licensing and attribution.

No API Token is required, and there is no extra access limit.

Dataset Page Contents Update History kept
Station weather weather Station weather Temperature, humidity, pressure, wind, gusts, and the day’s high and low at automatic weather stations About once an hour 3 days; trends up to 7 days
Current weather weather/realtime Station weather Current weather at the station nearest a coordinate Checked every minute Latest value only
Township forecast weather/forecast Station weather Hourly forecast for about the next 24 hours for a township Every 15 minutes Latest value only
Rainfall rain Rainfall Rainfall at rain gauges for each accumulation period About every 10 minutes 3 days; trends up to 7 days
Lightning lightning Lightning Location and time of cloud-to-cloud and cloud-to-ground flashes Checked every 30 seconds 3 days
Typhoons typhoon Typhoons Track, potential track, wind-radius strike probability, and typhoon warnings Checked every minute 7 days, and at least the latest entry of each kind

“Checked every minute” means the server queries the source at that interval. A new entry is added only when the source has new data.

The weather API is deployed only on the TNN-1 node, and the path decides which of two servers you call:

Path Server Cache
A snapshot whose path ends in a 10-digit Unix timestamp in seconds, for example /api/v5/meteor/weather/1794636000 or /api/v5/meteor/typhoon/track/1794636000 https://static.core-tnn1.exptech.dev 300 seconds (5 seconds for a 404)
Every other path: latest value, /list, /station, /trend/..., /realtime/..., /forecast/..., /typhoon/geojson https://api.core-tnn1.exptech.dev 1 second
  • The wrong server returns 404. api.core returns 404 for every timestamp-snapshot path. static.core serves only timestamp-snapshot paths.
  • Do not use api.core.exptech.dev or static.core.exptech.dev, which DNS assigns to a node. On a node other than TNN-1, every weather path returns 404. Use the TNN-1 URLs in the table. The examples on each weather page use those two URLs.
  • Legacy v3 (deprecated) is on https://tnn.exptech.dev. See Legacy v3.

weather, rain, lightning, and the four typhoon products all use the same shapes:

Shape Path Response
Latest /api/v5/meteor/<dataset> The latest snapshot
Time list /api/v5/meteor/<dataset>/list Snapshot times you can query, delta-encoded (see below)
One time /api/v5/meteor/<dataset>/<10-digit Unix seconds> The snapshot at that time, with the same structure as Latest. Only on static.core
Trend /api/v5/meteor/<dataset>/trend/<station id> A 24-hour or 7-day series for one station (weather, rainfall)
Station catalog /api/v5/meteor/<dataset>/station Station id to name, county or city, township, elevation, and coordinates (weather, rainfall)

A snapshot at a chosen time must use a time that appeared in /list. Any other time returns 404.

Weather, rainfall, and lightning snapshots are arrays per field, aligned by index, rather than one object per station. For weather and rainfall, ids[i] looks up the station catalog for the name and coordinates. The catalog rarely changes. Fetch it once, then revalidate with the ETag.

const API = "https://api.core-tnn1.exptech.dev";
const [station, latest] = await Promise.all([
fetch(`${API}/api/v5/meteor/weather/station`).then((r) => r.json()),
fetch(`${API}/api/v5/meteor/weather`).then((r) => r.json()),
]);
const rows = latest.ids.map((id, i) => ({
id,
name: station[id]?.n,
county: station[id]?.c,
temp: latest.temp[i] === -99 ? null : latest.temp[i],
}));

/list, and ts on a trend, are delta-encoded Unix seconds. The first element is the start time. Each later element is the gap, in seconds, from the previous time. Times run oldest first.

[1794632400, 3600, 3600]

That is the three times 1794632400, 1794636000, and 1794639600. Decode it like this:

function decodeDelta(a) {
const out = [];
let t = 0;
for (let i = 0; i < a.length; i++) {
t = i === 0 ? a[0] : t + a[i];
out.push(t);
}
return out;
}

When there is no data, the response is [].

  • Times in v5 are Unix seconds (10 digits). <time> in the path is also seconds.
  • Exception: updateTime on a township forecast is Unix milliseconds (13 digits). forecast[].time is a Taiwan-time "HH:00" string.
  • time in legacy v3 is Unix milliseconds.
Quantity Unit
Air temperature, apparent temperature °C
Relative humidity, probability of precipitation %
Pressure hPa
Wind speed, gust m/s; typhoon movement speed is km/h
Wind direction Degrees (station snapshots); a string (current weather, forecasts, typhoons)
Rainfall mm
Distance, typhoon wind radius km
Elevation m
Coordinates Decimal degrees, rounded to 4 decimal places

Weather, rainfall, and lightning use two fields, lat and lon. Typhoon geometry uses GeoJSON order [longitude, latitude].

Data How a missing value is written
Numeric fields on station weather, rainfall, and current weather -99. Rainfall is never negative. Treat any negative value as no valid observation
gt, hit, and lot (times) on a station snapshot 0
Weather codes wx and weatherCode 0
Township forecast Temperature, apparent temperature, and humidity are -99. Probability of precipitation, wind speed, and Beaufort number are 0. Wind direction is ""
Typhoons null

wx on a station snapshot, and weatherCode on current weather and forecasts, use this three-digit code. The hundreds digit is cloud cover. The last two digits are an extra phenomenon.

Hundreds Cloud cover
1 Clear
2 Cloudy
3 Overcast
Last two digits Phenomenon Last two digits Phenomenon
00 No extra phenomenon, or no match 10 Ice pellets
01 Haze 11 Showers
02 Mist 12 Rain and snow showers
03 Lightning 13 Hail
04 Thunder 14 Thunderstorm
05 Fog 15 Thunder and snow
06 Rain 16 Thunder and hail
07 Rain and snow 17 Heavy thunderstorm
08 Heavy snow 18 Heavy thunder and hail
09 Snow grains 19 Thunder

For example, 206 is cloudy with rain. The code is 0 when the weather text does not start with clear, cloudy, or overcast, or when there is no data.

  • Every v5 JSON response has an ETag (an MD5 in quotes). Send the previous value in If-None-Match. When the data is unchanged, the response is 304 with no body.
  • Responses support gzip. Send Accept-Encoding: gzip (add --compressed to curl).
  • Any origin may call cross-origin (Access-Control-Allow-Origin: *). A browser can fetch directly.
  • Server-side cache: 1 second on api.core, 300 seconds on static.core.
Dataset Source
Station weather, rainfall, lightning, typhoons Open data from the Central Weather Administration, Ministry of Transportation and Communications
Current weather, township forecasts Station observations and township forecasts on the CWA website

When you republish or display the data, credit the source with the suggested attribution in Data license.