API reference

Incidents

Live and historical emergency incidents from every state and territory, in one GeoJSON schema. Base URL https://dataquoll.io/api/v1.

GET/incidents

List all current incidents

Returns a GeoJSON FeatureCollection of all current emergency incidents, with support for filtering, pagination, and bounding box queries.

Parameters

NameInRequiredTypeDescription
statequeryNostringComma-separated state codes (e.g. nsw,vic,qld)
eventTypequeryNostringComma-separated event types (bushfire, burn_off, fire_ban, structure_fire, vehicle_fire, grass_fire, other_fire, hazmat, rescue, flood, storm, tree_down, cyclone, earthquake, extreme_heat, vehicle_accident, medical, alarm, other). For every kind of fire, use category=fire.
categoryqueryNostringComma-separated event categories. Groups related event types (e.g. fire includes bushfire, structure_fire, grass_fire, vehicle_fire, other_fire (a fire of another or unstated kind) and fire_ban). burn_off is its own category (planned). See /api/v1/schema for the full mapping.
featureTypequeryNostringComma-separated feature types. Defaults to 'incident' (point incidents only), so boundary polygons never appear unless requested. Request them explicitly: incident_area, warning_area, fire_ban_area, road_disruption, forecast (a forecast the source publishes for a day, such as CFA's fire danger forecast: no incident, and it states no warning level, severity, urgency or certainty). See /api/v1/schema.
severityqueryNostringCAP-AU severity levels (Extreme, Severe, Moderate, Minor, Unknown). Matches the published value: a record whose agency does not state severity, or whose stored value could be DataQuoll's, matches Unknown only.
urgencyqueryNostringCAP-AU urgency levels (Immediate, Expected, Future, Past, Unknown). Matches the published value: a record whose agency does not state urgency, or whose stored value could be DataQuoll's, matches Unknown only.
certaintyqueryNostringCAP-AU certainty levels (Observed, Likely, Possible, Unlikely, Unknown). Matches the published value: a record whose agency does not state certainty, or whose stored value could be DataQuoll's, matches Unknown only.
warningLevelqueryNostringAustralian Warning System levels (advice, watch_and_act, emergency_warning, none). Matches the published level: none matches a record whose agency states no level; a level DataQuoll cannot confirm (absent on the record) matches nothing.
statusqueryNostringIncident status filter
agencyqueryNostringComma-separated source agency codes, as each record's source.agency gives them (for example RFS, CFS). Matching is exact and case-sensitive, so rfs matches nothing; an unknown code matches nothing. At most 100 values, each at most 64 characters and 2,000 characters for the whole list, counted URL-encoded: a letter, digit, space, hyphen, full stop, underscore or asterisk counts one, any other character three or more. A longer list returns 400; to get every agency, omit agency.
officialqueryNobooleanFilter by source provenance. `true` excludes sources the feed registry marks unofficial (today the South Australian community-decoded pager feeds, and NT PFES, an agency feed whose licence is not published); `false` returns only those sources. Omit it to return everything, which is the default and unchanged behaviour. Read the semantics before relying on it: `official` defaults to true in our feed configuration and is declared explicitly on only the unofficial sources, so `official=true` means "not marked unofficial", not "verified government source". An official feed can still carry individual ambulance dispatches. Use `/api/v1/attribution` to see the flag per source.
bboxqueryNostringBounding box: minLon,minLat,maxLon,maxLat. Records at precision 'state' (not placed) are never inside a box, so a bbox query leaves them out.
limitqueryNointegerResults per page (default 100, max 500)
cursorqueryNostringOpaque pagination cursor, taken from meta.next_cursor of the previous response. Absent next_cursor means there are no further pages.
afterqueryNostringAlias for cursor. This is the parameter name emitted in links.next, and is accepted for backward compatibility. If both are supplied, after wins.
formatqueryNostringResponse format. CSV includes columns: id, state, agency, feed_id, title, event_type, status, warning_level, severity, urgency, certainty, lng, lat, address, suburb, lga, location_state, reported_at, updated_at, fetched_at, is_retracted, retracted_at, retraction_reason, feature_type, event_category. In CSV, a text cell begins with a single quote (') when its first visible character is =, +, - or @ (also after spaces or line breaks, and in fullwidth form) or it starts with a tab, carriage return or single quote, so a spreadsheet opens it as text, never as a formula; numbers, such as a negative latitude, are never changed. To get the original text, remove one single quote from the start of a cell that begins with one. cap-atom returns a standards-validated CAP Atom feed (each entry inlines a CAP-AU alert in <content>; incidents retracted in the last 7 days appear as Cancel messages). cap-au is the deprecated legacy <alerts> wrapper, kept for backward compatibility; new consumers should use cap-atom. A forecast is not an alert, so cap-au and cap-atom with featureType=forecast return 400. CSV, cap-atom and cap-au require the Developer plan or above; requesting one on a lower plan returns 403.
include_retractedqueryNobooleanInclude retracted incidents (default false). Retracted incidents are marked when upstream feeds stop publishing them.
include_boundaryqueryNobooleanSet true to add properties.boundary: the area (Polygon or MultiPolygon) the agency published for each incident, or null when it published none. Off by default because polygons make list responses much larger. /api/v1/incidents/{id} always includes it.

Responses

StatusDescription
200A GeoJSON FeatureCollection of incidents
400A malformed parameter (a filter, limit or cursor), or a CAP format asked for forecasts. A request whose database query would be longer than 24,926 characters also returns 400, naming the filters that made it large (for example, severity, urgency, certainty and warningLevel each set to every value).
402Pay per request: no key was sent, so the answer is a price. The WWW-Authenticate header carries an MPP Payment challenge; pay it and send the request again with Authorization: Payment. Also sent, with a fresh price, when a payment fails its checks or its price has expired. Only while pay per request is on; otherwise a request without a key gets 401.
403A paid format (csv, cap-au, cap-atom) below the Developer plan, or a key restricted to other origins or endpoints
429Rate limit exceeded
Request
curl "https://dataquoll.io/api/v1/incidents?state=nsw%2Cvic&eventType=bushfire%2Cflood" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response
{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "id": "nsw-rfs-1234567",
      "geometry": {
        "type": "Point",
        "coordinates": [
          150.604,
          -33.883
        ]
      },
      "properties": {
        "source": {
          "state": "nsw",
          "agency": "RFS",
          "feedId": "1234567"
        },
        "title": "Bush Fire - Warragamba",
        "eventType": "bushfire",
        "status": "active",
        "warningLevel": "watch_and_act",
        "severity": "Unknown",
        "urgency": "Unknown",
        "certainty": "Unknown",
        "location": {
          "address": "Warragamba Dam Rd, Warragamba NSW",
          "suburb": "Warragamba",
          "state": "NSW",
          "latitude": -33.883,
          "longitude": 150.604
        },
        "details": {
          "description": "Bush fire burning in a south-easterly direction"
        },
        "timestamps": {
          "reported": "2026-04-07T14:30:00+10:00",
          "updated": "2026-04-07T16:45:00+10:00",
          "fetched": "2026-04-07T16:46:12+10:00"
        },
        "retraction": {
          "retracted": true,
          "retractedAt": "2026-04-07T18:00:00+10:00",
          "reason": "upstream_removed"
        }
      }
    }
  ],
  "meta": {
    "total_count": 245,
    "has_more": true,
    "next_cursor": "cursor_xyz789",
    "generatedAt": "2026-04-07T16:46:12+10:00"
  },
  "links": {
    "self": "/api/v1/incidents?limit=100",
    "next": "/api/v1/incidents?limit=100&after=cursor_xyz789"
  },
  "attribution": "https://dataquoll.io/api/v1/attribution"
}
GET/incidents/{id}

Get a single incident

Returns a single incident as a GeoJSON Feature.

Parameters

NameInRequiredTypeDescription
idpathYesstringIncident ID (e.g. nsw-rfs-1234567)
formatqueryNostringResponse format. Default geojson returns a GeoJSON Feature. cap-au returns the incident as a single standards-valid CAP-AU <alert> document (Content-Type application/cap+xml), validated against the OASIS CAP 1.2 schema and the CAP-AU Profile v3.0. A forecast record (featureType forecast) is not an alert and returns 400 for cap-au. CSV, cap-atom and cap-au require the Developer plan or above; requesting one on a lower plan returns 403.

Responses

StatusDescription
200A GeoJSON Feature, or a CAP-AU alert document when format=cap-au
400format=cap-au for a record that is not an alert (a forecast)
402Pay per request: no key was sent, so the answer is a price. The WWW-Authenticate header carries an MPP Payment challenge; pay it and send the request again with Authorization: Payment. Also sent, with a fresh price, when a payment fails its checks or its price has expired. Only while pay per request is on; otherwise a request without a key gets 401.
404Incident not found
Request
curl "https://dataquoll.io/api/v1/incidents/{id}" \
  -H "Authorization: Bearer YOUR_API_KEY"
GET/incidents/nearby

Find incidents near a location

Returns incidents within a radius (km) of a given lat/lng coordinate, sorted by distance. Records at precision 'state' are left out: their point only stands for somewhere in the state.

Parameters

NameInRequiredTypeDescription
latqueryYesnumberLatitude
lngqueryYesnumberLongitude
radiusqueryYesnumberRadius in kilometres (max 500)
limitqueryNointeger
statequeryNostring
eventTypequeryNostring
severityqueryNostring
categoryqueryNostringComma-separated event categories, as on /api/v1/incidents (fire, weather and so on; see /api/v1/schema). Named eventCategory here until v1.96.1, a name this endpoint never read: a filter sent under it was ignored.
urgencyqueryNostring
certaintyqueryNostring
warningLevelqueryNostring
agencyqueryNostringComma-separated source agency codes, as each record's source.agency gives them (for example RFS, CFS). Matching is exact and case-sensitive, so rfs matches nothing; an unknown code matches nothing. At most 100 values, each at most 64 characters and 2,000 characters for the whole list, counted URL-encoded: a letter, digit, space, hyphen, full stop, underscore or asterisk counts one, any other character three or more. A longer list returns 400; to get every agency, omit agency.
officialqueryNobooleanFilter by source provenance. `true` excludes sources the feed registry marks unofficial (today the South Australian community-decoded pager feeds, and NT PFES, an agency feed whose licence is not published); `false` returns only those sources. Omit it to return everything, which is the default and unchanged behaviour. Read the semantics before relying on it: `official` defaults to true in our feed configuration and is declared explicitly on only the unofficial sources, so `official=true` means "not marked unofficial", not "verified government source". An official feed can still carry individual ambulance dispatches. Use `/api/v1/attribution` to see the flag per source.
statusqueryNostringComma-separated incident statuses (active, contained, controlled, safe, completed). Defaults to all.
include_retractedqueryNobooleanSet true to include retracted incidents. Default false; retracted incidents are hidden, matching /api/v1/incidents.
include_boundaryqueryNobooleanSet true to add properties.boundary: the area (Polygon or MultiPolygon) the agency published for each incident, or null when it published none. Off by default because polygons make list responses much larger. /api/v1/incidents/{id} always includes it.

Responses

StatusDescription
200Nearby incidents as GeoJSON FeatureCollection
400Missing or invalid parameters. A request whose database query would be longer than 24,926 characters also returns 400, naming the filters that made it large (for example, severity, urgency, certainty and warningLevel each set to every value).
402Pay per request: no key was sent, so the answer is a price. The WWW-Authenticate header carries an MPP Payment challenge; pay it and send the request again with Authorization: Payment. Also sent, with a fresh price, when a payment fails its checks or its price has expired. Only while pay per request is on; otherwise a request without a key gets 401.
Request
curl "https://dataquoll.io/api/v1/incidents/nearby?lat=-33.87&lng=151.21" \
  -H "Authorization: Bearer YOUR_API_KEY"
GET/incidents/snapshot

Audit trail snapshot

Returns the incidents that were active at a specific point in time, each once. Recent datetimes are reconstructed from live and lifecycle data: an incident counts from when we first saw it until its source withdrew it, so one withdrawn by then is left out. Each carries the latest state we recorded for it, which, for an incident its source updated in place, can be later than the datetime asked (timestamps.updated says when). Datetimes before 2026-04-08 are reconstructed from the historical archive (4.5M records) and are gated by the same tier lookback as /api/v1/incidents/history (free has no archive access; Starter 1 year, Developer and Business 5 years, Pro, Organisation and Enterprise unlimited). Archive (pre-2026-04-08) snapshots require a state filter, and meta.source indicates whether the result came from "live" or "archive". meta.truncated is true when more incidents were active than came back: the answer stopped at limit, or at about 4 MB (archive flood extents come back whole; meta.size_limited is then true too). Narrow by state or event_type. An archive record its source dated only to a period (properties.archive.datePrecision, datePeriodEnd) counts as active from the period's first day until the end its source states, or, without one, until the period's last day, because the source does not say on which of those days it burned or flooded. One with a stated day and no stated end counts on that day only.

Parameters

NameInRequiredTypeDescription
datetimequeryYesstringISO 8601 datetime to query (cannot be in the future)
statequeryNostringFilter by state code. Required for archive (pre-2026-04-08) snapshots.
event_typequeryNostringFilter by event type
feature_typequeryNostringComma-separated feature types: only these kinds are returned. Without it every kind is returned except forecast, because a forecast (such as a day of CFA's fire danger forecast) is no incident; ask for forecasts with feature_type=forecast. Archive records are incidents. An unknown value is a 400.
limitqueryNointegerMax results (default 500). An integer from 1 to 500; anything else is a 400.
include_boundaryqueryNobooleanSet true to add properties.boundary: the area (Polygon or MultiPolygon) the agency published for each incident, or null when it published none. Off by default because polygons make list responses much larger. /api/v1/incidents/{id} always includes it.

Responses

StatusDescription
200Incidents active at the requested datetime
400Missing or invalid datetime, a limit that is not an integer from 1 to 500, an archive (pre-2026-04-08) snapshot requested without the required state filter, or a query that timed out (narrow it, or try again in a moment)
402Pay per request: no key was sent, so the answer is a price. The WWW-Authenticate header carries an MPP Payment challenge; pay it and send the request again with Authorization: Payment. Also sent, with a fresh price, when a payment fails its checks or its price has expired. Only while pay per request is on; otherwise a request without a key gets 401.
403Archive access requires a paid plan, or the datetime predates your tier's lookback window
429Rate limit exceeded
Request
curl "https://dataquoll.io/api/v1/incidents/snapshot?datetime=2026-04-20T14%3A30%3A00%2B09%3A30&state=sa" \
  -H "Authorization: Bearer YOUR_API_KEY"
GET/incidents/history

Historical incident data (paid tier)

Returns historical emergency incidents from two sources, merged and ordered newest first: the imported archive (1840 to 1 May 2026, 4.5M records) and the records our own pollers have written since April 2026, which carry `boundary` where an agency published an area. `meta.sources` names which answered. Free tier is blocked. Starter is limited to 1 year of lookback, Developer and Business to 5 years, Pro, Organisation and Enterprise unlimited. A window too large to answer within the database budget returns 400 asking you to narrow it. Engine-era records also carry `featureType` (incidents by default; pass `featureType` to ask for warning_area or incident_area markers, or forecast records) and a `retraction` object only when an agency withdrew the record rather than letting it end: leaving the agency's live feed is the normal end of an incident and is not reported as a retraction here. Records are ordered by `reported_at` newest first; a record with no `reported_at` is not returned here (hazard history counts it as undated). An archive record whose source stated only a period carries `date_precision` (`month`, `season`, `financial_year`, `year` or `period`) and `date_period_end`: its `event_start_date` is then the period's first day, not a stated day, and the same keys sit in its `details`, with `details.date_as_published` holding the source's own value wherever we replaced a placeholder start, and `details.end_as_published` a replaced end. A period-dated archive record's `reported_at` is its period's first day at the start of the day, UTC, so `after` and `before` select it by that day, not by overlap. PAGE WITH `cursor`: pass `meta.next_cursor` from one response as `cursor` on the next, or follow `links.next`. `before` and `after` bound the WINDOW and are not a paging mechanism: thousands of blocks of records share an identical `reported_at` (the largest holds more than 600,000 records), and advancing `before` past a page would skip the rest of that block. Records sharing an instant have no natural order; the order given is stable across pages, which is what the cursor relies on. A PAGE ALSO ENDS AT ABOUT 4 MB: archive polygons are returned whole (a single mapped flood extent can run to megabytes), so a page stops adding records once its size passes the cap, always serving at least one record. `meta.size_limited` is then true and `meta.has_more` true; keep following the cursor.

Parameters

NameInRequiredTypeDescription
statequeryNostringComma-separated state codes
eventTypequeryNostringComma-separated event types
officialqueryNobooleanFilter by source provenance. `true` excludes sources the feed registry marks unofficial (today the South Australian community-decoded pager feeds, and NT PFES, an agency feed whose licence is not published); `false` returns only those sources. Omit it to return everything, which is the default and unchanged behaviour. Read the semantics before relying on it: `official` defaults to true in our feed configuration and is declared explicitly on only the unofficial sources, so `official=true` means "not marked unofficial", not "verified government source". An official feed can still carry individual ambulance dispatches. Use `/api/v1/attribution` to see the flag per source.
afterqueryNostringStart of date range (ISO 8601, inclusive). Tier-limited.
beforequeryNostringEnd of date range (ISO 8601, exclusive). Defaults to now.
cursorqueryNostringOpaque pagination cursor. Pass `meta.next_cursor` from the previous response, or follow `links.next`. Use this rather than advancing `before`, which cannot page through records sharing one `reported_at`.
limitqueryNointegerMax results per page (1-500, default 100)

Responses

StatusDescription
200Historical incidents matching filters
400Invalid before or after, filters, limit or cursor, or a window too large to answer within the database budget (narrow it). A request whose database query would be longer than 24,926 characters also returns 400, naming the filters that made it large (for example, severity, urgency, certainty and warningLevel each set to every value).
402Pay per request: no key was sent, so the answer is a price. The WWW-Authenticate header carries an MPP Payment challenge; pay it and send the request again with Authorization: Payment. Also sent, with a fresh price, when a payment fails its checks or its price has expired. Only while pay per request is on; otherwise a request without a key gets 401.
403Free tier blocked or depth limit exceeded
429Rate limit exceeded
Request
curl "https://dataquoll.io/api/v1/incidents/history?state=wa%2Csa&eventType=bushfire%2Cflood" \
  -H "Authorization: Bearer YOUR_API_KEY"