Open Data · Developer Portal

Build on live seismic data.

Event and station data from the GeoShake community earthquake early-warning network — free to use for research, education and applications.

CC BY 4.0JSON · CSV · SSE · MQTTNo cost
recent-events.sh
curl https://api.geoshake.org/api/events

[
  {
    "event_id": 7,
    "originMs": 1783678236932,
    "lat": 36.57, "lon": 31.06,
    "nStations": 3,
    "intensityClass": "orta",
    "maxPga": 0.106
  }, …
]
License & citation

Free to use — just credit GeoShake.

All GeoShake event and station data is published under Creative Commons Attribution 4.0 (CC BY 4.0). You may use, share and adapt it — including in academic publications and commercial products — as long as you credit GeoShake. The full terms, including the station-privacy and no-warranty notes, are in data/LICENSE.

GeoShake is a community monitoring network, not an official earthquake early warning service. Don't use it as the sole basis for life-safety, evacuation or emergency-response decisions — follow your national seismological and civil protection authorities.

GeoShake Seismic Network, https://map.geoshake.org (accessed YYYY-MM-DD), CC BY 4.0
Access

Three access tiers.

Start anonymous, add a free API key for the historical catalog, or request a personal real-time feed.

Anonymous
no auth
  • Recent confirmed events
  • Station list & details
  • Live SSE stream
Free API key
header · X-API-Key
  • Historical event catalog
  • Date-range queries · JSON / CSV
  • Up to 10,000 rows / request
Real-time MQTT
GeoShake account
  • Personal read-only TLS feed
  • Confirmed events, as they happen
  • Station trigger messages
Your API key

Register, log in, get your key.

One free GeoShake account works everywhere: this API, the Home Assistant integration and Google Home linking. Log in to mint your personal key — copy it, or regenerate at any time.

or

New here? Create a GeoShake account in the mobile app, then log in to get your API key.

Download on theApp StoreGET IT ONGoogle Play
Anonymous endpoints

No key required.

Public read endpoints under api.geoshake.org — great for prototyping and live dashboards.

Endpoint
Returns — click a row for examples
Historical catalog · free API key

Query the full event catalog.

Sign up is free — a key is issued against your GeoShake account so we can apply fair-use quotas and keep researchers informed of changes.

1

Get a key

Use the panel above — or the API directly. Logging in returns your existing key; pass "regenerate": true to force a new one (the old key becomes invalid).

cURL
curl -X POST https://api.geoshake.org/api/data/key \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","password":"..."}'
2

Query the catalog

Pull events by date range in JSON or CSV.

curl "https://api.geoshake.org/api/data/events?from=2026-01-01T00:00:00Z&to=2026-07-01T00:00:00Z&format=csv" \
  -H "X-API-Key: YOUR_KEY" -o geoshake-events.csv
from / to — ISO 8601 · default last 30 dayslimit — 1–10000 · default 1000format — json | csv
JSON responses carry license and citation fields, plus truncated: true when the row limit was hit — narrow the date range and continue.
Quota · 120 requests / 5 minutes per key
Looking for what people felt during one specific earthquake? Community felt reports is a separate, keyless GeoJSON endpoint.
Community felt reports · GeoJSON · no key

What people felt, one event at a time.

After an earthquake, GeoShake app users can report how strongly they felt it. Those reports are aggregated into ~300 m cells and published per event as a plain GeoJSON FeatureCollection on the Modified Mercalli (MMI) scale — QGIS, Leaflet, GDAL/ogr2ogr and geopandas read it as-is. Two endpoints, in this order: /api/intensity lists the events that have data, then /api/intensity/{eventKey} returns the cells for one of them.

This is a human-reported layer: what people say they felt, not what an instrument measured. Keep it apart from the PGA and intensityClass fields of the endpoints above, and from the phone-accelerometer layer on the map — those are machine measurements. No API key is needed here, so the access tiers and the key panel above don't apply to this endpoint.

1

Start here: which earthquakes have data

One keyless GET lists every earthquake that has published felt-report data, newest first. Each entry hands you the eventKey for step 2 together with a catalog summary and the counts — you don't build keys, and you don't probe events to find out which ones are worth asking about.

curl "https://api.geoshake.org/api/intensity"

# Optional paging — newest first, 1-200 per page
curl "https://api.geoshake.org/api/intensity?limit=100&offset=0"
limit — 1–200 · default 50offset — 0–100000 · default 0total / hasMore — events with data · paging flagcellCount / reportCount — published cells · reporters in themwindowEnd — past it, that event's tally is frozen
Only events that cleared the publication threshold are listed, which is why the list is empty today — an honest answer, not an outage. A broken limit/offset is 400; if the service itself is down you get 503, never a fake empty list. Cached ~60 s.
One physical earthquake is listed once. USGS, EMSC and AFAD each publish their own record of the same quake; we group records within 10 s and 100 km of each other across different agencies, list the group under one eventKey, and put the other agencies' keys in mergedKeys so you can match this entry against your own catalogue without de-duplicating the list yourself. Aftershocks are not merged — a separate quake minutes later stays a separate entry.
2

Fetch the cells for one event

Take an eventKey from step 1 and GET it — again no headers. Each feature is one published cell; the collection also carries the event, the counting window and the licence in metadata.

curl "https://api.geoshake.org/api/intensity/eq_USGS_us6000tjl2"

# Plain GeoJSON — save it and open it in QGIS, ogr2ogr, Leaflet, geopandas…
curl -s "https://api.geoshake.org/api/intensity/eq_USGS_us6000tjl2" -o felt-reports.geojson
n — reporters in the cell · always ≥ 3mmi — median reported MMI · 1–12, one decimalmmiHistogram — reported levels · sums to nlastReportAt — ISO 8601 · may be nullmetadata — scale · kind · cellCount · reportCount · windowStart / windowEndcanonicalKey / mergedKeys — the group's chosen key · the same quake in other catalogues
Malformed key → 400. Well-formed but unknown event → 200 with an empty features array. Cached ~30 s while the report window is open, ~5 min once it has closed. Both intensity endpoints are anonymous and rate-limited per IP: over the limit you get 429, never a fake empty collection.
Any key of the same quake returns the same map. Ask for the EMSC record of an event that USGS also published and you get one merged collection — so metadata.event.source can name an agency you did not ask for. That is the merge working, not a mismatch: eventKey always echoes what you asked for, canonicalKey names the group's chosen record, and mergedKeys lists the rest. Reports are counted once per person, so a merged event never double-counts.
Building a key yourself (optional). Keys are eq_<source>_<sourceEventId> — USGS event us6000tjl2 becomes eq_USGS_us6000tjl2, sources being the agencies GeoShake mirrors (USGS, EMSC, AFAD). A single catalog record at /api/quakes/{id} carries both source and source_event_id; the list endpoint /api/quakes does not, which is exactly why step 1 exists. Records without an agency id use the fallback form eqid_<id>, built from that record's numeric catalog id.
One earthquake exists as separate records at USGS, EMSC and AFAD. Reports are stored under the key of the record the GeoShake app notified people about, so another agency's key for the same quake can legitimately come back empty — we don't silently merge the copies for you, and the same physical earthquake can appear twice in step 1 under two agency keys.
3

Know what you are plotting

Reports are counted inside the window the response states — windowStart → windowEnd, closing 60 minutes after origin time. Once that window is closed the result stops changing.

Read this before you publish a map from it. Values are Modified Mercalli (MMI) intensities reported by people, not measured by an instrument — not comparable with PGA, with intensityClass, or with the phone-accelerometer layer. A cell is published only after at least 3 independent reports; a single report is never released. That is also why a feature is a ~300 m polygon and not a point: lat/lon is the cell centre, deliberately not a reporter's position, and reportCount sums published cells only. An empty features array is the normal outcome for most events — a 200 with nothing to draw, not a failure. And none of this is an official damage assessment: for that, follow your national seismological and civil-protection authority.
CC BY 4.0 · credit GeoShake community felt reports — geoshake.org; the response repeats license and attribution inside metadata so a pipeline can pick them up automatically.
Real-time feed · MQTT

Stream confirmed events live.

For live pipelines, request personal read-only MQTT credentials with your account and subscribe to the events topic over TLS (port 8883).

geoshake/events · TLS :8883

Returns { broker, port, username, password } — works with any MQTT client: paho, aiomqtt, mosquitto_sub.

Request credentials
curl -X POST https://api.geoshake.org/api/ha/credentials \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","password":"..."}'

# → { broker, port, username, password }
# → subscribe with paho / aiomqtt / mosquitto_sub
Academic · FDSN web services · no key

ObsPy works out of the box.

GeoShake speaks the seismology community's own standards — anonymous FDSN web services returning QuakeML and StationXML. Point ObsPy at api.geoshake.org and pull events and station metadata the same way you would from IRIS or a national network.

1

Pull events & stations

fdsnws-event serves the confirmed catalog as QuakeML 1.2; fdsnws-station serves network/station metadata as StationXML 1.1. Both are anonymous and rate-limited per IP.

from obspy import UTCDateTime
from obspy.clients.fdsn import Client

# GeoShake speaks the standard FDSN web services (no authentication).
client = Client(base_url="https://api.geoshake.org")

# Event catalog -> QuakeML (magnitude = PGA-derived MMI, NOT a seismic magnitude)
cat = client.get_events(starttime=UTCDateTime("2026-01-01"),
                        minmagnitude=2.0)          # MMI threshold
print(cat)                                          # ObsPy Catalog object

# Station metadata -> StationXML (network "GW", FDSN-registered, uncalibrated)
inv = client.get_stations(network="GW", level="channel")
print(inv)

# What the samples REALLY are - read this before processing. LNZ is the 1 Hz
# ENVELOPE of gravity-referenced vertical acceleration (per-second peak |value|, no
# polarity - since 2026-09-10; earlier archive = vector magnitude, see the
# channel HISTORY comment). ENZ/EN1/EN2 are genuine signed components: ENZ is
# gravity-referenced vertical (Azimuth 0, Dip -90); EN1/EN2 are the horizontals and their
# azimuth is NOT published, because the devices carry no magnetometer.
print(inv[0][0][0].description)
event — starttime · endtime · minmagnitude · maxmagnitude · bbox · format xml | textstation — network=GW · station · channel · level=station|channel · bbox · format xml | text
The QuakeML magnitude is a PGA-derived Modified Mercalli Intensity (MMI), explicitly labelled not a seismic magnitude — GeoShake computes neither ML/Mw nor depth. Network GW is a permanent, FDSN-registered code, but the sensors are uncalibrated MEMS: StationXML serves level=channel, where each channel states in its <Description> what the samples actually are, but level=response serves a nominal instrument sensitivity (counts = m/s² × 10⁶, derived from the sensor datasheet). It is not a per-unit calibration and carries no poles/zeros model. There are four channels per station — LNZ, ENZ, EN1, EN2 — and StationXML publishes Azimuth/Dip only where they are known: ENZ carries Azimuth 0, Dip -90 because gravity gives us the vertical axis; the two horizontals carry Dip 0 with no Azimuth, because without a magnetometer we know they are orthogonal but not which way they point; LNZ also carries Azimuth 0, Dip -90 — the measured axis is the vertical, even though the samples are absolute values. An absent field there means unknown, not forgotten — each channel carries a comment saying which case it is.
Quota · 100 requests / 5 minutes per IP · empty result → HTTP 204
2

Cite a frozen snapshot

For reproducible research, catalog snapshots are archived on Zenodo under CC-BY-4.0 with a citable DOI. Cite the concept DOI below — it is version-stable and always resolves to the latest snapshot.

Citation
GeoShake Community Seismic Network (2026). GeoShake Community
Seismic Event Catalog. Zenodo. https://doi.org/10.5281/zenodo.21313786
DOI — 10.5281/zenodo.21313786 · concept · latest versionLicense — CC-BY-4.0
Need a snapshot at a specific date for your paper? Ask us and we'll mint a pinned version.
3

Cite the network itself

The Zenodo DOI above identifies a snapshot of the event catalog. The network — the stations, their metadata and the waveforms — is a separate object with its own permanent identifier: GW is registered with the FDSN as GeoShake Global Seismic Network (the registry entry is public), with DOI 10.7914/ft1b-4x43. Since 6 September 2026 GeoShake is also listed in the FDSN data centre registry as GEOSHAKE, with three services declared there: fdsnws-station, fdsnws-event and SeedLink. If your work uses GeoShake waveforms or station metadata, cite the network:

Citation
GeoShake (2026): GeoShake Global Seismic Network. International Federation of Digital Seismograph Networks. Dataset/Seismic Network. https://doi.org/10.7914/ft1b-4x43
Network DOI — 10.7914/ft1b-4x43 · FDSN · the networkCatalog DOI — 10.5281/zenodo.21313786 · Zenodo · a snapshot
Same DOI is published inside the metadata itself, as <Identifier type="DOI"> on the StationXML <Network> element.
Good to know

What the data is — and isn't.

Network-confirmed events

3+ GeoShake stations must agree before an event is published — a conservative catalog with a low false-alarm rate.

Trigger-window snippets only

Waveform snippets are stored around trigger windows only. GeoShake does not archive continuous waveforms. A null inside samples is a missing sample (gap) — it is not a zero reading; do not plot it as 0.

Intensity ≠ magnitude

Classes hafif · orta · şiddetli are network-derived shaking categories. max_pga is the highest measured peak ground acceleration across triggering stations, taken from the 1 Hz feature stream at the moment the event was solved. It is a three-component vector magnitude (not the max-horizontal convention used by most GMPEs; measured ratio 1.03–1.16×). If a station's measurement had not arrived yet, its trigger-onset amplitude is used instead, so the value is a lower bound. Before 2026-09-20 this field carried the trigger-onset amplitude, which under-reads the true peak by a median factor of 2.94 (measured, n=14); historical rows have been recomputed. This set is not closed — we may add a class later, so treat an unfamiliar intensityClass as a display value rather than an error.

A complement, not a replacement

A community network — data quality varies with station density. It complements national networks (AFAD/Kandilli, USGS…), it doesn't replace them.

Uncalibrated sensors

Stations are consumer-grade MEMS accelerometers. They are not calibrated: the response served at level=response is a nominal datasheet sensitivity, not a per-unit calibration — no shake-table calibration, no coupling or mounting correction, no poles/zeros model. Amplitudes are indicative, not metrologically traceable.

Elevation is a model, not a survey

Station elevation is sampled from a digital elevation model (DEM) at the reported coordinates. It is not a survey, and it describes the terrain rather than the sensor — a unit on an upper floor of a building sits above the published figure. Where elevation is unknown the StationXML schema still requires the field, so 0 is published and the station comment says it means "unknown", not sea level. Depth stays 0: the sensor's height above the local ground surface is not recorded.

Network code is registered

The code GW in StationXML, SAC and SeedLink is permanent and registered with the FDSN — since 27 August 2026, as GeoShake Global Seismic Network, DOI 10.7914/ft1b-4x43; the FDSN registry entry is public. It will not change, so you can safely rely on it.

Holding GeoShake files from before 27 Jul 2026? They carry GS, which was a mistake on our part — the FDSN has GS assigned to a USGS network. Don't merge those files into a shared archive under GS; re-fetch and they will carry GW.

Roadmap

Just shipped — and what's next.

Live

FDSN web services + QuakeML

Anonymous fdsnws-event & fdsnws-station serving QuakeML and StationXML — ObsPy works out of the box today.

Live

DOI-versioned snapshots

The catalog is published on Zenodo under CC-BY-4.0 with a citable DOI — 10.5281/zenodo.21313786. See how to cite.

Live

Live waveform streaming (SeedLink)

Real-time activity envelopes + event bursts over SeedLink — open in ObsPy, jAmaSeis or SWARM at seedlink.geoshake.org:18000.

Planned

Waveform snippets (miniSEED)

Downloadable trigger-window snippets in miniSEED alongside the event catalog for signal-level analysis (live SAC per-trigger already available on station pages).

Researchers — tell us what you need first. Get in touch →