# Earthquake & Wildfire Events API — USGS + NASA FIRMS (`mouadapi/geospatial-event-intelligence`) Actor

Returns earthquakes (USGS) and satellite fire detections (NASA FIRMS) for any area as flat rows, with watch mode for new and changed events; failed, unavailable and unchanged rows are never charged. Not affiliated with or endorsed by the USGS or NASA.

- **URL**: https://apify.com/mouadapi/geospatial-event-intelligence.md
- **Developed by:** [COMPASS DEV](https://apify.com/mouadapi) (community)
- **Categories:** News, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 hazard events

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

Returns earthquakes from the USGS catalog and satellite fire detections from NASA FIRMS for any area you give, as flat rows with the sources' own magnitude, alert, confidence and fire-power fields; failed, unavailable and unchanged rows are never charged.

Give it one or more areas (a box, or a point with a radius); get one row per event:

- **earthquakes** (USGS earthquake catalog): time, magnitude, depth, place, the USGS PAGER alert level, the significance
  number, the tsunami flag and the review status;
- **fire detections** (NASA FIRMS, VIIRS on NOAA-20 and NOAA-21, optionally MODIS): time of the satellite scan, place,
  confidence class, fire radiative power (MW) and brightness.

Built for risk dashboards, insurance and logistics feeds, newsrooms, research and AI agents that need one feed for "what
happened near here". *Not affiliated with or endorsed by the USGS or NASA.*

### What it does

- **Two official sources in one call, one flat schema:** `eventType` is `earthquake` or `fire`; the other type's fields are
  null. Severity comes only from each source's own fields (magnitude, PAGER alert, significance; FIRMS confidence, fire
  radiative power): no score of our own.
- **Any area:** a box (`"west,south,east,north"`), a circle (`"latitude,longitude,radiusKm"`, up to 2,000 km) or `"world"`,
  with a name if you like (`"California: -125,32,-114,42"`). Circles give `distanceKm` from their centre. Up to 20 areas per
  run; an event in two overlapping areas is returned and charged once.
- **The last days or a past window:** the last `sinceDays` UTC days, today included (default 2), or `sinceDays` days from
  `dateFrom`.
- **Watch mode:** give a watch list name (`watchListName`) and run it hourly or daily:
  - the first run returns every event (`baseline`);
  - later runs return only new events, and earthquakes the USGS revised (magnitude, magnitude type, review status, tsunami
    flag or PAGER alert), with the previous values;
  - an earthquake the USGS deleted comes back once as a free `no_data` row;
  - a run with nothing new returns exactly one free `no_data` row that says so.
- **Your own NASA FIRMS key:** fires need your free MAP_KEY (`firmsApiKey`, sent to you by email from
  [FIRMS](https://firms.modaps.eosdis.nasa.gov/api/map_key/)). It is used only in requests to FIRMS and never logged,
  stored or returned. Without it you still get earthquakes, and each area's fire part is one free `failed` row.
- **You are never charged for failed results:** failed and no_data rows are free, and so are unchanged rows in watch mode.
  One charge per returned event.

### Quick start

```json
{ "areas": ["California: -125,32,-114,42.1"], "firmsApiKey": "YOUR_FIRMS_MAP_KEY" }
```

A watch list for two places, earthquakes from M4 and high-confidence fires, run daily:

```json
{
  "areas": ["Tokyo: 35.68,139.69,150", "Los Angeles: 34.05,-118.24,100"],
  "minMagnitude": 4,
  "minFireConfidence": "high",
  "firmsApiKey": "YOUR_FIRMS_MAP_KEY",
  "watchListName": "sites"
}
```

### Input

| Field | What it does |
|---|---|
| `areas` | Main input, up to 20. A box `"west,south,east,north"` (degrees), a circle `"latitude,longitude,radiusKm"` or `"world"`, with an optional name first (`"California: -125,32,-114,42"`). Objects work too: `{ "name", "west", "south", "east", "north" }` or `{ "name", "latitude", "longitude", "radiusKm" }`. A box that crosses the 180° meridian is given as two boxes. |
| `eventTypes` | Which events; default `earthquake,fire`. |
| `sinceDays` | The window in UTC days, today included; default `2` (1 to 10). |
| `dateFrom` | Optional first day of a past window (`YYYY-MM-DD`); empty = the last days. |
| `minMagnitude` | Smallest earthquake magnitude; default `2.5`. |
| `minFireConfidence` | Smallest FIRMS confidence class: `low`, `nominal` or `high`; default `nominal`. |
| `fireSources` | FIRMS products; default `VIIRS_NOAA20_NRT,VIIRS_NOAA21_NRT` (add `MODIS_NRT` for MODIS on Terra and Aqua). Each product's detections are separate rows. |
| `firmsApiKey` | Your own free NASA FIRMS MAP_KEY; needed for fires. Never logged, stored or returned. |
| `mode` | Empty: watch when a watch list name is given, otherwise export. An explicit `watch` or `export` wins. |
| `watchListName` | Your watch list (kept in your own storage between runs). A name turns on watch mode; watch mode without a name uses the list "default". Changing the areas or filters starts the list again. |
| `includeUnchanged` | Watch mode: also return unchanged events (free); default `false`. |
| `maxItems` | Most charged events per run; default `1000`. Export: areas past the cap are not read. Watch: the rest come in the next run. |

Field names from other tools: `stateName` (→ `watchListName`); `apiKey`, `mapKey` (→ `firmsApiKey`).

### Output

One row per event. An earthquake:

```json
{
  "status": "ok",
  "input": "Costa Rica: -87,8,-82,12",
  "areaName": "Costa Rica",
  "eventType": "earthquake",
  "eventId": "us6000tymj",
  "time": "2026-09-30T21:55:26.169Z",
  "latitude": 9.7526,
  "longitude": -86.5063,
  "magnitude": 5.6,
  "magnitudeType": "mww",
  "depthKm": 8,
  "place": "94 km SW of Tamarindo, Costa Rica",
  "eventStatus": "reviewed",
  "tsunami": false,
  "alert": "green",
  "significance": 483,
  "summary": "M 5.6 earthquake, 94 km SW of Tamarindo, Costa Rica, 8 km deep (USGS PAGER alert: green)",
  "url": "https://earthquake.usgs.gov/earthquakes/eventpage/us6000tymj"
}
```

A fire detection:

```json
{
  "status": "ok",
  "input": "LA: 34.2,-118.2,30",
  "eventType": "fire",
  "eventId": "VIIRS_NOAA20_NRT:2026-10-02T0942:34.21036,-118.17114",
  "time": "2026-10-02T09:42:00.000Z",
  "latitude": 34.21036,
  "longitude": -118.17114,
  "distanceKm": 3.2,
  "confidence": "high",
  "frpMw": 21.4,
  "satellite": "NOAA-20",
  "instrument": "VIIRS",
  "daynight": "night",
  "summary": "Fire detection (VIIRS NOAA-20), high confidence, 21.4 MW, night",
  "url": "https://firms.modaps.eosdis.nasa.gov/map/#d:2026-10-02;@-118.17114,34.21036,12z"
}
```

No fire in an area (free):

```json
{ "status": "no_data", "input": "Costa Rica: -87,8,-82,12", "eventType": "fire", "error": "No fire detection in this area and window (confidence nominal or higher)" }
```

### Output fields

| Field | Type | Description |
|---|---|---|
| `status` | string (or null) | ok = an event returned (charged in export mode, and in watch mode when it is a baseline, new or changed event; free when unchanged and includeUnchanged is on); no_data = nothing to return for this area and event type (no earthquake or fire detection in the window, an event found again in an overlapping area, an earthquake the USGS deleted since the last run, or nothing new since the last run) (free); failed = an invalid area, no FIRMS key for fires, or a source that could not be read (free) |
| `error` | string (or null) | Why a row is no_data or failed; null on ok rows |
| `attempts` | integer (or null) | Requests made for the answer this row came from (retries included) |
| `input` | string (or null) | The area entry that produced this row, as given (a box "west,south,east,north", a circle "latitude,longitude,radiusKm", "world", or an object), or the watch list for the nothing-new row |
| `areaName` | string (or null) | The name given before the area ("California: ..."), or null |
| `mode` | string (or null) | watch or export |
| `watchList` | string (or null) | Watch list name (watch mode); null in export mode |
| `eventType` | string (or null) | earthquake (USGS) or fire (a NASA FIRMS fire detection) |
| `eventId` | string (or null) | Earthquakes: the USGS event ID. Fires: "<product>:<date>T<HHMM>:<latitude>,<longitude>", the same for the same detection in every run |
| `time` | string (or null) | When it happened (ISO 8601, UTC): the earthquake's origin time, or the satellite scan's start for a fire detection |
| `updated` | string (or null) | Earthquakes: when the USGS last updated the event (ISO 8601); null for fires |
| `latitude` | number (or null) | Latitude in degrees (WGS 84) |
| `longitude` | number (or null) | Longitude in degrees (WGS 84) |
| `distanceKm` | number (or null) | For a circle area: the great-circle distance from its centre (km, 0.1); null for a box |
| `magnitude` | number (or null) | Earthquakes: the USGS magnitude; null for fires |
| `magnitudeType` | string (or null) | Earthquakes: the magnitude type (mww, mb, ml, md ...) |
| `depthKm` | number (or null) | Earthquakes: depth below the surface (km) |
| `place` | string (or null) | Earthquakes: the USGS place text ("94 km SW of Tamarindo, Costa Rica"); null when the people filter left it out |
| `placeOmitted` | boolean (or null) | Earthquakes: true when the place text was left out by the people filter (it looked like a person's name); latitude and longitude stay |
| `eventStatus` | string (or null) | Earthquakes: automatic, reviewed or deleted (the USGS review status) |
| `tsunami` | boolean (or null) | Earthquakes: the USGS tsunami flag (set for large events in oceanic regions; not a tsunami warning) |
| `alert` | string (or null) | Earthquakes: the USGS PAGER alert level (green, yellow, orange, red) for estimated impact; null when PAGER gave none |
| `significance` | integer (or null) | Earthquakes: the USGS significance number (0 and up; larger is more significant: magnitude, felt reports and estimated impact) |
| `network` | string (or null) | Earthquakes: the network that gave the preferred solution (us, ci, nc, ak ...) |
| `confidence` | string (or null) | Fires: the FIRMS confidence class (low, nominal, high); VIIRS gives it directly, MODIS as 0-100 % (under 30 low, 30-79 nominal, 80+ high) |
| `confidenceRaw` | string (or null) | Fires: the confidence as FIRMS gives it (VIIRS l / n / h; MODIS 0-100) |
| `frpMw` | number (or null) | Fires: fire radiative power, megawatts |
| `brightnessK` | number (or null) | Fires: brightness temperature, kelvin (VIIRS I-4 channel; MODIS channel 21/22) |
| `brightness2K` | number (or null) | Fires: brightness temperature of the second channel, kelvin (VIIRS I-5; MODIS channel 31) |
| `scanKm` | number (or null) | Fires: the pixel's approximate size along the scan (km) |
| `trackKm` | number (or null) | Fires: the pixel's approximate size along the track (km) |
| `satellite` | string (or null) | Fires: NOAA-20, NOAA-21, Terra or Aqua |
| `instrument` | string (or null) | Fires: VIIRS or MODIS |
| `daynight` | string (or null) | Fires: day or night (the scan's time of day) |
| `firmsVersion` | string (or null) | Fires: the FIRMS product version (e.g. 2.0NRT) |
| `fireSource` | string (or null) | Fires: the FIRMS product read (VIIRS_NOAA20_NRT, VIIRS_NOAA21_NRT or MODIS_NRT) |
| `summary` | string (or null) | The event in plain words, from the source's own fields |
| `changeType` | string (or null) | Watch mode: baseline (first run of the list), new, changed, unchanged (only with includeUnchanged) or deleted (the USGS deleted an earthquake on the list); null in export mode |
| `changedFields` | string (or null) | Watch mode, changed rows: the tracked fields that changed, comma-separated (earthquakes: magnitude, magnitudeType, eventStatus, tsunami, alert; fires: confidence) |
| `previousValues` | string (or null) | Watch mode, changed rows: the changed fields' previous values, as JSON |
| `url` | string (or null) | Earthquakes: the event's USGS page. Fires: the NASA FIRMS Fire Map at the detection's date and place |
| `source` | string (or null) | The source and the citation it asks for (fires: "NASA FIRMS" and the LANCE acknowledgement, with NASA's advice on local-scale use) |
| `license` | string (or null) | The data's licence or terms (USGS: U.S. Public Domain; FIRMS: NASA open data, provided "as is") |
| `licenseUrl` | string (or null) | Where the licence or terms are published |
| `scrapedAt` | string (or null) | When the row was made (ISO 8601) |

### Pricing

Pay per event, one event per returned earthquake or fire detection (`hazard-event`):

| Plan | Price per event | Per 1,000 events |
|---|---|---|
| Free (no discount) | $0.0015 | $1.50 |
| Bronze | $0.0013 | $1.30 |
| Silver | $0.00115 | $1.15 |
| Gold (and Platinum, Diamond) | $0.0010 | $1.00 |

- Charged: ok rows in export mode; baseline, new and changed rows in watch mode.
- Never charged: failed rows (an invalid area, no FIRMS key, a source that could not be read), no_data rows (no event in an
  area, an event found again in an overlapping area, a deleted earthquake, nothing new) and unchanged rows. You are never
  charged for failed results.
- A big area over several days can hold thousands of fire detections: `maxItems` (default 1,000) caps what a run returns and
  charges.
- Pay per event only, with no usage fees, so the actor is eligible for x402 agent payments.

### Use it from AI agents

One clear main input, `areas`; every row has `status`, `error`, `eventType`, `summary` and `scrapedAt`. Call it through the
Apify API, the Apify MCP server (`mouadapi/geospatial-event-intelligence`) or x402 agentic payments. Copy-paste call (your
Apify token in place of `YOUR_APIFY_TOKEN`):

```bash
curl -X POST "https://api.apify.com/v2/acts/mouadapi~geospatial-event-intelligence/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" -H "Content-Type: application/json" -d '{"areas": ["35.68,139.69,150"], "eventTypes": ["earthquake"], "minMagnitude": 4, "sinceDays": 7}'
```

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('mouadapi/geospatial-event-intelligence').call({ areas: ['California: -125,32,-114,42.1'], firmsApiKey: 'YOUR_FIRMS_MAP_KEY', watchListName: 'california' });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

### Limits

- **Fire detections are satellite pixels, not fires.** Each row is one 375 m (VIIRS) or 1 km (MODIS) pixel that looked hot in
  one satellite pass; one fire gives many rows, and a gas flare, a volcano or a hot factory roof can be detected too.
  NASA advises that, due to their spatial resolution, these data are not suited to tactical decision-making or to
  informing about conditions at a local scale: confirm with local authorities.
- **FIRMS near-real-time products only** (`_NRT`): each satellite passes about twice a day, and clouds hide fires. For
  archives older than a few months, use FIRMS's own archive download.
- **Up to 10 days per run;** FIRMS answers up to 5 days per request, so 6 to 10 days take two requests per area and product.
- **The USGS catalog** is complete worldwide for larger earthquakes (about M4.5 and up) and in more detail in the United
  States; small earthquakes elsewhere may be missing. At most 2,000 earthquakes per area.
- **Coordinates only:** no place-name or address lookup.
- **Suomi NPP** (VIIRS_SNPP) is not offered: NASA ends its data products on 1 November 2026.

### Known issues

- The FIRMS key: a key FIRMS refuses, or one whose limit is used up (5,000 requests per 10 minutes), stops FIRMS for the
  rest of the run; every fire part after it is a free `failed` row that says why.
- A source that cannot be read (a rate limit that three pauses don't clear, an outage) stops for the rest of the run; the
  other source goes on. Another IP or proxy is never tried.
- The place text of an earthquake is left out (`placeOmitted`) when it has the shape of a person's name; the coordinates
  stay.
- The daily self-test of this actor checks the earthquake path; the fire path is checked with a key in every release test.

### Sources and licences

- USGS earthquake catalog (FDSN event web service): U.S. Public Domain
  ([USGS copyrights and credits](https://www.usgs.gov/information-policies-and-instructions/copyrights-and-credits)).
- NASA FIRMS: "NASA promotes full and open sharing of data"; please cite it as "NASA FIRMS"
  ([FIRMS FAQ](https://www.earthdata.nasa.gov/data/tools/firms/faq)). We acknowledge the use of data and/or imagery from
  NASA's Land, Atmosphere Near real-time Capability for Earth observations (LANCE) (https://earthdata.nasa.gov/lance), part
  of NASA's Earth Science Data and Information System (ESDIS). The data are provided "as is"
  ([LANCE disclaimer](https://www.earthdata.nasa.gov/data/projects/lance#ed-lance-disclaimer)).

Each row's `source`, `license` and `licenseUrl` name the source it came from.

# Actor input Schema

## `areas` (type: `array`):

Where to look, up to 20 areas. A box: "west,south,east,north" in degrees (for example "-125,32,-114,42" for California). A circle: "latitude,longitude,radiusKm" (for example "34.05,-118.24,100", up to 2,000 km). "world" for the whole globe. A name may come first ("California: -125,32,-114,42"). Objects work too: { "name", "west", "south", "east", "north" } or { "name", "latitude", "longitude", "radiusKm" }. A box that crosses the 180° meridian is given as two boxes.

## `eventTypes` (type: `array`):

earthquake (USGS earthquake catalog) and fire (NASA FIRMS satellite fire detections). Fires need your NASA FIRMS key below.

## `sinceDays` (type: `integer`):

The window in UTC days, today included (2 = today and yesterday). With a start date: that many days from it. FIRMS gives up to 5 days per request, so 6 to 10 days take two requests per area.

## `dateFrom` (type: `string`):

The first day of a past window (YYYY-MM-DD, UTC), for example 2026-09-29. Empty: the last days, today included.

## `minMagnitude` (type: `number`):

Smallest earthquake magnitude returned (USGS catalog magnitudes run from about -1 to 9.5).

## `minFireConfidence` (type: `string`):

Smallest NASA FIRMS confidence class returned: low (every detection, more false alarms), nominal (FIRMS's usual choice) or high. MODIS's 0-100 % is read as low under 30, nominal 30-79 and high 80+.

## `fireSources` (type: `array`):

The NASA FIRMS near-real-time products to read: VIIRS on NOAA-20 and NOAA-21 (375 m pixels) and MODIS on Terra and Aqua (1 km pixels). Each product's detections are separate rows.

## `firmsApiKey` (type: `string`):

Your own free NASA FIRMS MAP_KEY, sent to you by email when you ask for it at https://firms.modaps.eosdis.nasa.gov/api/map_key/ (5,000 requests per 10 minutes). Needed for fire detections; without it each area's fire part is one free failed row. Used only in requests to NASA FIRMS; never logged, stored or returned.

## `mode` (type: `string`):

Empty: watch when a watch list name is given, otherwise export. "watch" returns only events that are new or changed since the last run of the watch list; "export" returns every event. An explicit mode wins.

## `watchListName` (type: `string`):

Name of your watch list (kept in your own storage between runs). Giving a name turns on watch mode. Watch mode without a name uses the list "default". Changing the areas or filters starts the list again (every event a baseline row).

## `includeUnchanged` (type: `boolean`):

Watch mode: also return events that did not change since the last run (free).

## `maxItems` (type: `integer`):

Most events returned and charged per run. Export: areas past the cap are not read. Watch: the rest come in the next run.

## Actor input object example

```json
{
  "areas": [
    "California: -125,32,-114,42.1",
    "Tokyo: 35.68,139.69,150"
  ],
  "eventTypes": [
    "earthquake",
    "fire"
  ],
  "sinceDays": 2,
  "minMagnitude": 2.5,
  "minFireConfidence": "nominal",
  "fireSources": [
    "VIIRS_NOAA20_NRT",
    "VIIRS_NOAA21_NRT"
  ],
  "includeUnchanged": false,
  "maxItems": 1000
}
```

# Actor output Schema

## `dataset` (type: `string`):

Dataset with one row per event, or per area and event type when nothing is returned

## `runReport` (type: `string`):

Summary of the run (counts, charged and free rows, stop reason)

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "areas": [
        "California: -125,32,-114,42.1"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("mouadapi/geospatial-event-intelligence").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "areas": ["California: -125,32,-114,42.1"] }

# Run the Actor and wait for it to finish
run = client.actor("mouadapi/geospatial-event-intelligence").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "areas": [
    "California: -125,32,-114,42.1"
  ]
}' |
apify call mouadapi/geospatial-event-intelligence --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mouadapi/geospatial-event-intelligence"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/12bBeEJ9W6UhenyKk/builds/qEIWEEcloR1PlVGWI/openapi.json
