Skip to content
Console

Earthquake reports

Earthquake report data comes from reports published by the Central Weather Administration (CWA). Each report includes the epicenter, magnitude, and depth, plus the observed seismic intensity for each county or city and each station. The server checks the CWA for new reports every few seconds. Use it for an earthquake list, historical queries, and intensity maps.

  • For a new report as soon as it is published, use the SSE stream eq.report.v1.
  • The list (/api/v2/eq/report) does not include intensity by area. When you need the intensity distribution, take id from the list and then request the single report.
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 right now.

Query earthquake reports by condition. The response is an array. By default it is sorted by origin time, newest first, one report per page, and includes only reports whose maximum intensity across Taiwan is 1 or higher (see Notes).

GEThttps://api.core.exptech.dev/api/v2/eq/report
Query parameters
  • limitintOptionalDefault 1

    Page size, 1–150. A value outside the range is clamped to the nearest bound.

  • pageintOptionalDefault 1

    Page number, 1–10000.

  • sortstringOptionalDefault time

    Sort field: time (origin time), intensity (maximum intensity across Taiwan), magnitude, or depth. Ties are broken by report id, newest first.

  • orderstringOptionalDefault desc

    Sort direction: asc or desc.

  • minIntensityintOptionalDefault 1

    Lower bound on the maximum intensity across Taiwan, 0–9 (see Intensity scale). Pass minIntensity=0 to include intensity 0.

  • maxIntensityintOptionalDefault 9

    Upper bound on the maximum intensity across Taiwan, 0–9.

  • minMagnitudefloatOptionalDefault 0

    Lower bound on magnitude, 0–10.

  • maxMagnitudefloatOptionalDefault 10

    Upper bound on magnitude, 0–10.

  • minDepthfloatOptionalDefault 0

    Lower bound on depth (kilometers), 0–700.

  • maxDepthfloatOptionalDefault 700

    Upper bound on depth (kilometers), 0–700.

  • startTimestringOptional

    Start date YYYY-MM-DD (Taiwan time), inclusive of 00:00:00 that day. An invalid format is ignored.

  • endTimestringOptional

    End date YYYY-MM-DD (Taiwan time), inclusive of 23:59:59 that day. An invalid format is ignored.

  • citystringOptional

    County or city name, exact match, for example 花蓮縣 or 臺北市 (use 臺, not 台). Returns only reports that recorded an intensity in that county or city.

  • cityMinIntintOptional

    Lower bound on county or city intensity. With city, it applies to that county or city. Alone, a report is included if any county or city matches.

  • cityMaxIntintOptional

    Upper bound on county or city intensity. Same rules as cityMinInt.

Request
curl -L "https://api.core.exptech.dev/api/v2/eq/report"
Response

Success (an empty array [] when nothing matches)

[
{
"id": "115079-2026-1109-122157",
"lat": 23.62,
"lon": 120.66,
"depth": 10.5,
"loc": "雲林縣政府東南東方 23.2 公里 (位於雲林縣古坑鄉)",
"mag": 4.2,
"time": 1794198117000,
"int": 3,
"trem": 0,
"md5": "3F2A9C1E7B5D4A608E1F2C3D4B5A6978"
}
]

The parameters are not in canonical form. Redirects to the canonical URL

HTTP/1.1 302 Found
Location: /api/v2/eq/report?limit=20&minIntensity=4

If-None-Match matches the ETag. Empty bodyNo response body

Server error

{
"error": "<錯誤訊息>"
}
Try it
Query parameters

The token is sent from your browser directly to the API.

The response is an array. Each element is one report:

FieldTypeDescription
[].idstringReport ID, format XXXXXX-YYYY-MMDD-HHMMSS. The first 3 digits are the ROC year, the next 3 are the CWA report number (000 for a small-area earthquake with no number), and the rest is the origin date and time (Taiwan time). Example: 115079-2026-1109-122157.
[].latnumberEpicenter latitude (degrees).
[].lonnumberEpicenter longitude (degrees).
[].depthnumberFocal depth (kilometers).
[].locstringEpicenter description, kept as the CWA original text (it may contain consecutive spaces).
[].magnumberRichter magnitude.
[].timeintOrigin time, Unix milliseconds.
[].intintMaximum seismic intensity across Taiwan, 0–9 (see Intensity scale).
[].tremintReserved field. Currently always 0.
[].md5stringHash of the report contents, including intensity by area. 32 uppercase hex digits. It changes when the contents are updated, so you can use it to decide whether to fetch the single report again.

Fetch one report by id, including intensity for each county or city and each station.

GEThttps://api.core.exptech.dev/api/v2/eq/report/{id}
Path parameters
  • idstringRequired

    Report ID (path parameter), format XXXXXX-YYYY-MMDD-HHMMSS, for example 114000-2025-0829-100546. Query parameters are ignored.

Request
curl "https://api.core.exptech.dev/api/v2/eq/report/<id>"
Response

Success

{
"id": "114000-2025-0829-100546",
"lat": 22.86,
"lon": 121.28,
"depth": 16.9,
"loc": "臺東縣政府東北方 17.5 公里 (位於臺東縣近海)",
"mag": 4,
"time": 1756433146000,
"list": {
"臺東縣": {
"int": 2,
"town": {
"東河": {
"lat": 22.97,
"lon": 121.3,
"int": 2
},
"鹿野": {
"lat": 22.91,
"lon": 121.13,
"int": 2
},
"成功": {
"lat": 23.1,
"lon": 121.37,
"int": 1
}
}
},
"花蓮縣": {
"int": 1,
"town": {
"富里": {
"lat": 23.2,
"lon": 121.29,
"int": 1
}
}
}
},
"trem": 0
}

If-None-Match matches the ETag. Empty bodyNo response body

The ID format is wrong, or there is no such report (no response body)No response body

Try it
Path parameters

The token is sent from your browser directly to the API.

FieldTypeDescription
idstringReport ID. Same format as the list.
latnumberEpicenter latitude (degrees).
lonnumberEpicenter longitude (degrees).
depthnumberFocal depth (kilometers).
locstringEpicenter description.
magnumberRichter magnitude.
timeintOrigin time, Unix milliseconds.
listobjectSeismic intensity by county or city. The key is the county or city name (for example 臺東縣). An empty object {} when there are no observations.
<縣市>.intintMaximum seismic intensity in that county or city, 0–9.
<縣市>.townobjectSeismic intensity at each station in that county or city. The key is the station name.
<測站>.latnumberStation latitude (degrees).
<測站>.lonnumberStation longitude (degrees).
<測站>.intintStation seismic intensity, 0–9.
tremintReserved field. Currently always 0.

A single report does not include int (maximum intensity across Taiwan) or md5. For the maximum across Taiwan, take the maximum int among the counties and cities in list.

int, minIntensity, cityMinInt, and the other intensity fields use the integers 0–9 for the Central Weather Administration (CWA) intensity scale:

Value 0 1 2 3 4 5 6 7 8 9
Intensity 0 1 2 3 4 5 lower 5 upper 6 lower 6 upper 7

Query the list by condition, then fetch intensity by area for each id (the list does not include it). Build the query in canonical form (parameters in alphabetical order, defaults omitted) and you skip the extra 302:

終端機視窗
# 20 most recent reports with maximum intensity 4 or higher
curl -L "https://api.core.exptech.dev/api/v2/eq/report?limit=20&minIntensity=4"
# Every report on 2024-04-03 (Taiwan time), including intensity 0
curl -L "https://api.core.exptech.dev/api/v2/eq/report?endTime=2024-04-03&limit=150&minIntensity=0&startTime=2024-04-03"
const BASE = "https://api.core.exptech.dev";
// 1. List: the 20 most recent reports with maximum intensity 4 or higher
const params = new URLSearchParams({ limit: "20", minIntensity: "4" });
const listRes = await fetch(`${BASE}/api/v2/eq/report?${params}`);
if (!listRes.ok) throw new Error(`HTTP ${listRes.status}`);
const reports = await listRes.json();
// 2. Single report: intensity for each county or city and each station
for (const r of reports) {
console.log(r.id, new Date(r.time).toISOString(), `M${r.mag}`, `max intensity ${r.int}`);
const res = await fetch(`${BASE}/api/v2/eq/report/${r.id}`);
if (res.status === 404) continue; // no such report
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const report = await res.json();
for (const [city, area] of Object.entries(report.list)) {
for (const [station, s] of Object.entries(area.town)) {
console.log(" ", city, area.int, station, s.int);
}
}
}
  • Intensity 0 is filtered out by default. The list’s minIntensity defaults to 1. If you omit it, reports whose maximum intensity across Taiwan is 0 do not appear. Pass minIntensity=0 to list every report.

  • A query that is not in canonical form returns 302 first. The list (v2 and v1) canonicalizes the query. If it differs from the canonical form, the response is 302 to the canonical URL, and the data comes after that. Canonical form:

    • Parameters are sorted by name;
    • Parameters equal to the default are removed (for example page=1, sort=time, limit=1);
    • Unknown parameters are removed;
    • Numbers are clamped to the bounds and trailing zeros are dropped (for example limit=500 becomes limit=150, and minMagnitude=4.50 becomes minMagnitude=4.5). A date in the wrong format is removed.

    The browser fetch follows a 302 automatically. curl needs -L. Building the URL by the rules above saves a round trip. A single report (/api/v2/eq/report/{id}) is not canonicalized and does not return 302.

  • A bad parameter value does not return 400. An integer or decimal that cannot be parsed is treated as 0 and then clamped (for example minIntensity=abc is the same as minIntensity=0). An unknown sort or order falls back to the default.

  • Cache and ETag. The response includes ETag. The same If-None-Match returns 304 (no body). The server caches for 1 second. HEAD is supported.

  • Error responses. A server error returns 500 with a body {"error": "..."}. The message is for debugging. Do not branch on its text. A single report that is missing, or an ID in the wrong format, returns 404 with no body.

  • Time and coordinates. time is Unix milliseconds. The date parameters startTime and endTime are read as Taiwan time (UTC+8). Epicenter coordinates are rounded to 2 decimal places.

  • The list and the single report have different fields. The list has int and md5, and no list. The single report has list, and no int or md5.

Returns the latest N reports (by origin time, newest first). Every report includes intensity for each county or city and each station. There is no filter on intensity, magnitude, or the other fields, and intensity 0 reports are not filtered out.

GEThttps://api.core.exptech.dev/api/v1/eq/report
Query parameters
  • limitintOptionalDefault 1

    Number of reports to return, 1–50. An invalid value is treated as 1. A value over 50 is treated as 50.

Request
curl -L "https://api.core.exptech.dev/api/v1/eq/report"
Response

Success (an empty array [] when there is no data)

[
{
"id": "CWA-EQ114000-2025-0829-100546",
"no": "2025082910054600000",
"lat": 22.86,
"lon": 121.28,
"depth": 16.9,
"loc": "臺東縣政府東北方 17.5 公里 (位於臺東縣近海)",
"mag": 4,
"time": 1756433146000,
"list": {
"臺東縣": {
"int": 2,
"town": {
"東河": {
"lat": 22.97,
"lon": 121.3,
"int": 2
}
}
}
}
}
]

The parameters are not in canonical form. Redirects to the canonical URL

HTTP/1.1 302 Found
Location: /api/v1/eq/report

If-None-Match matches the ETag. Empty bodyNo response body

Server error

{
"error": "<錯誤訊息>"
}
Try it
Query parameters

The token is sent from your browser directly to the API.

Differences from v2:

FieldTypeDescription
[].idstringReport ID. Compared with v2, it has a CWA-EQ prefix, for example CWA-EQ114000-2025-0829-100546. Remove the prefix to get the v2 ID.
[].nostringThe CWA earthquake number. The first 14 digits are the origin time YYYYMMDDHHMMSS (Taiwan time). v2 does not have this field.
[].listobjectSeismic intensity by county or city and by station. Same shape as list on a v2 single report.

The other fields (lat, lon, depth, loc, mag, time) match v2. v1 has no int, trem, or md5. ?limit=1 equals the default, so it 302s to the URL with no query.