# KNMI earthquakes

KNMI's earthquake catalogue as an open service: time, place, depth, magnitude and type of every event, plus stations, waveforms and ShakeMaps (ground motion per earthquake). On 16 October 2026 the box around the Netherlands held 4,551 events since 1911, of which 3,493 induced (by gas extraction or mining). In the Netherlands itself that is 2,003 induced earthquakes since 1986; the strongest was Huizinge on 16 August 2012 (magnitude 3.6).

- Publisher: Koninklijk Nederlands Meteorologisch Instituut
- Area: Netherlands · Finest detail: event
- Period: 1911 – 2026 · Refreshed: daily
- Access: Open · Licence: CC BY 4.0 (ShakeMaps volgens KNMI niet onbewerkt commercieel herbruikbaar)
- Join keys: event-id (knmi2012qcdh), coördinaten, plaatsnaam, stationscode
- Status: ok (2026-10-14) · Geraardsbergen (België), quarry blast
- URL: https://api.dataplatform.knmi.nl/fdsnws/event/1/

## What can you do with it?
- **Earthquakes per year in Groningen.** Count the induced earthquakes per year. At magnitude 1.5 or more, 2013 was the peak year (34); in 2025 there were 7. The chart on this page shows the whole series.
- **Which villages shake most often?.** KNMI names every earthquake after the nearest village. Garrelsweer (89), Appingedam (88) and Loppersum (76) top the list.
- **How hard did the ground shake?.** 66 earthquakes have a ShakeMap: ground acceleration per station (rrsm.json) and for 56 also a grid (grid.nc). Overlay it on the homes from the BAG.
- **Gas production and earthquakes side by side.** Put earthquakes per year next to production from the Groningen field and the decisions to cut it. Start with Huizinge (August 2012).

## How to process it
1. **The whole catalogue as text.** format=text gives one line per event, separated by | (~580 kB for the box around the Netherlands). Without a box you also get earthquakes further away (6,514 in total).
   `https://api.dataplatform.knmi.nl/fdsnws/event/1/query?starttime=1900-01-01&minlatitude=50.7&maxlatitude=53.7&minlongitude=3.2&maxlongitude=7.3&format=text`
2. **Only induced earthquakes above a magnitude.** Filter on eventtype and minmagnitude. Note: the box also holds mining earthquakes in Germany; drop place names ending in (Duitsland) or (België).
   `https://api.dataplatform.knmi.nl/fdsnws/event/1/query?starttime=2020-01-01&eventtype=induced%20or%20triggered%20event&minmagnitude=2.5&format=text`
3. **One earthquake in detail (QuakeML).** Without format you get QuakeML (XML) with all magnitudes and the origin. Huizinge 2012 has id knmi2012qcdh.
   `https://api.dataplatform.knmi.nl/fdsnws/event/1/query?eventid=knmi2012qcdh`
4. **ShakeMaps and ground acceleration.** list gives the files per earthquake; download/<id>/rrsm.json the acceleration per station.
   `https://api.dataplatform.knmi.nl/shakemaps/7/download/knmi2025whfa/rrsm.json`
5. **The stations.** Network NL (since 1993) has 903 stations, network NA (Caribbean Netherlands) 12.
   `https://api.dataplatform.knmi.nl/fdsnws/station/1/query?level=station&network=NL&format=text`

## Interesting combinations
- How many homes are within 5 km of an earthquake? → [pdok-bag](https://www.opendataindex.nl/en/bron/pdok-bag.md) via coördinaten. Count the BAG addresses within a radius of the epicentre for each earthquake. That shows which earthquakes affected many homes.
- Earthquakes per neighbourhood and house values → [cbs-kwb](https://www.opendataindex.nl/en/bron/cbs-kwb.md) via buurtcode (punt in buurtvlak). Overlay the epicentres on the CBS neighbourhoods and compare the number of earthquakes with the property value and number of homes.

## Similar sources
- [EMSC (European-Mediterranean Seismological Centre)](https://www.seismicportal.eu/fdsn-wsevent.html): Same FDSN standard and parameters, but for Europe and the world. Useful to compare earthquakes across the border.
- [knmi-dataplatform](https://www.opendataindex.nl/en/bron/knmi-dataplatform.md): The KNMI Data Platform itself, with over 400 weather and climate datasets; the earthquake services run on the same server but without a key.

## What to watch out for
- **The box is bigger than the Netherlands.** A rectangle around the Netherlands also brings in ~1,900 mining earthquakes from the Ruhr area and earthquakes in Belgium. The place name then ends in (Duitsland) or (België).
- **Small earthquakes depend on the network.** The more stations, the more small earthquakes are detected. Compare years from a fixed magnitude, for example 1.5.
- **Not everything is an earthquake.** The catalogue also holds explosions, quarry blasts and sonic booms. Filter on the EventType column.
- **Depth often fixed at 3 km.** For 1,939 of the 2,003 induced earthquakes in the Netherlands the depth is 3.0 km, roughly the depth of the Groningen field. Do not treat it as a measured depth per earthquake.
- **ShakeMaps with an extra condition.** The ShakeMap service states CC BY 4.0, but also says the data cannot be reused unaltered for commercial use. The two conflict; ask KNMI when in doubt.

## API (FDSN Web Services (event, station, dataselect))

- Base: https://api.dataplatform.knmi.nl/fdsnws
- Access: No key. Runs on the same server as the KNMI Data Platform, but the seismological services need no Authorization header (tested). (tested)
- Formats: text, json, xml, csv
- Size: 6514 events in the whole catalogue since 1911 (4,408 induced, 2,053 tectonic, 53 explosions etc.; 16 Oct 2026) (tested)
- Filtering: No query language: each condition is its own query parameter (FDSN). Combinations act as AND.; min…, max…, =

### Endpoints
- `GET /event/1/query`: Search events by time, box or radius, depth, magnitude and type. QuakeML by default; format=text or json for a table or GeoJSON.
- `GET /event/1/query?eventid={id}`: One event in detail (all magnitudes, origin, picks); id such as knmi2012qcdh (Huizinge).
- `GET /event/1/version`: Service version (1.2.9 on 16 Oct 2026).
- `GET /event/1/application.wadl`: Machine-readable list of parameters.
- `GET /event/1/catalogs/`: Catalogues (KNMI only); mind the trailing slash, without it you get a 301.
- `GET /event/1/contributors/`: Contributors (KNMI only).
- `GET /station/1/query`: Networks and stations (level=network|station|channel|response): NL 903 stations since 1993, NA (Caribbean Netherlands) 12.
- `GET /dataselect/1/query`: Waveforms (miniSEED) per network, station, channel and time window.
- `GET /shakemaps/7/list`: All ShakeMaps with their files (66 earthquakes, 56 with grid.nc).
- `GET /shakemaps/7/download/{eventid}/{bestand}`: One ShakeMap file: rrsm.json/rrsm.csv (acceleration per station), grid.nc (grid), event.xml.

### Parameters
- `starttime / endtime`: Time window in UTC, ISO 8601 (2025-01-01 or 2025-01-01T12:00:00). (from the description)
- `minlatitude / maxlatitude / minlongitude / maxlongitude`: Rectangle in degrees (WGS84). Around the Netherlands: 50.7–53.7 N, 3.2–7.3 E. (tested)
- `latitude / longitude / minradius / maxradius`: Circle around a point; radius in degrees (not km). (platform)
- `mindepth / maxdepth`: Depth in km. (from the description)
- `minmagnitude / maxmagnitude / magnitudetype`: Magnitude (usually ML) and magnitude type. (from the description)
- `eventtype`: Type: 'induced or triggered event', earthquake, 'quarry blast', 'controlled explosion', 'sonic boom', explosion, 'other event'. (tested)
- `eventid`: One or more events by id. (from the description)
- `updateafter`: Only events updated after this moment: handy for incremental updates. (from the description)
- `limit / offset`: Paging; offset starts at 1 (FDSN), not 0. (from the description)
- `orderby`: time (newest first, default), time-asc, magnitude, magnitude-asc. (tested)
- `format`: xml (QuakeML, default), text (|-separated), json (GeoJSON), csv, qml-rt, sc3ml. geojson as value gives 400. (tested)
- `nodata`: What happens when nothing is found: 204 with no body by default, with nodata=404 a 404 with explanation. (tested)
- `includeallmagnitudes / includeallorigins / includearrivals / includepicks / includefocalmechanism`: Extra parts in QuakeML. (from the description)

### Columns with format=text (json has the same data as GeoJSON properties) (9)
`EventID` tekst, `Time` datetime, `Latitude / Longitude` getal, `Depth/km` getal, `MagType` tekst, `Magnitude` getal, `EventLocationName` tekst, `EventType` tekst, `status / mode (json)` tekst

### Limits and pitfalls
- No documented limit; the whole catalogue (6,514 lines) comes in one text response of ~0.6 MB. (tested)
- /event/1/count (optional in FDSN) does not exist here: 404. Count the lines of format=text yourself. (tested)
- Nothing found returns HTTP 204 with no body, not an empty list. A JSON parser chokes on that; handle 204 or use nodata=404. (tested)
- The catalogue is not just the Netherlands: without a box you also get Caribbean Netherlands and beyond (orderby=magnitude returned a quake near the Leeward Islands); with a box also the Ruhr and Belgium. (tested)
- The catalog parameter does not work (according to the KNMI help page, not available in SeisComP). (from the description)
- format=text has numbers with many decimals (Magnitude 1.5031251973028663, coordinates 53.46530151367188): round them yourself. (tested)
- An error (400, 404) is plain text with the line 'Usage details are available from …', not JSON. (tested)

### Example
```
https://api.dataplatform.knmi.nl/fdsnws/event/1/query?starttime=2026-01-01&minlatitude=50.7&maxlatitude=53.7&minlongitude=3.2&maxlongitude=7.3&eventtype=induced%20or%20triggered%20event&limit=5&format=json
```

## How to fetch it

### curl
```bash
curl "https://api.dataplatform.knmi.nl/fdsnws/event/1/query?starttime=2024-01-01&minlatitude=50.7&maxlatitude=53.7&minlongitude=3.2&maxlongitude=7.3&eventtype=induced%20or%20triggered%20event&format=text"
```

### python
```python
import requests
from collections import Counter

url = "https://api.dataplatform.knmi.nl/fdsnws/event/1/query"
params = {"starttime": "1990-01-01", "minlatitude": 50.7, "maxlatitude": 53.7,
          "minlongitude": 3.2, "maxlongitude": 7.3, "format": "text"}
regels = requests.get(url, params=params).text.splitlines()[1:]
jaren = Counter()
for r in regels:
    k = r.split("|")
    plaats, soort, kracht = k[12], k[13], float(k[10] or 0)
    if soort == "induced or triggered event" and kracht >= 1.5 and not plaats.endswith(("(Duitsland)", "(België)")):
        jaren[k[1][:4]] += 1
print(sorted(jaren.items()))
```

## What you can build with it
- [Earthquake tracker: every quake on the map, with municipality and homes](https://www.opendataindex.nl/en/bouwen/aardbevingentracker.md): A map and timeline of every earthquake in the Netherlands since 1986, with magnitude, type, municipality and neighbourhood, and the number of addresses within two kilometres of the epicentre.


## Examples with real figures (2)

For each example the finding, the reference date and the call that fetches exactly these figures.

- **Induced earthquakes in the Netherlands (magnitude 1.5 or more): 7 in 2025, against 34 in the peak year 2013** (2025). Table fdsnws/event. [Example](https://www.opendataindex.nl/en/voorbeeld/knmi-aardbevingen-geinduceerd-per-jaar)
  - `https://api.dataplatform.knmi.nl/fdsnws/event/1/query?starttime=1900-01-01&minlatitude=50.7&maxlatitude=53.7&minlongitude=3.2&maxlongitude=7.3&format=text`
- **Induced earthquakes by place: most Garrelsweer (89 earthquakes), then Appingedam and Loppersum** (1986–2026). Table fdsnws/event. [Example](https://www.opendataindex.nl/en/voorbeeld/knmi-aardbevingen-per-plaats)
  - `https://api.dataplatform.knmi.nl/fdsnws/event/1/query?starttime=1900-01-01&minlatitude=50.7&maxlatitude=53.7&minlongitude=3.2&maxlongitude=7.3&format=text`
