{"openapi":"3.1.0","info":{"title":"DataQuoll","description":"DataQuoll turns fragmented Australian public data into answers about locations, events and assets.\n\nToday's datasets: real-time emergency incidents and warnings (bushfires, floods, storms, earthquakes, rescues, and more) in one GeoJSON schema with CAP-aligned severity, urgency, and certainty fields that carry only what each agency states; disaster declarations reported by LGA as declared-area status; live river gauges with BoM flood classes; and a historical archive. DataQuoll was formerly EmergencyAPI. Standards-validated CAP output is available as an Atom feed via ?format=cap-atom and as per-incident documents via /api/v1/incidents/{id}?format=cap-au, both validated against the OASIS CAP 1.2 schema and the CAP-AU Profile v3.0. Includes real-time incidents, proximity search, and historical audit trail snapshots.\n\n**Disclaimer:** DataQuoll provides aggregated emergency incident data for informational\npurposes only. This data is sourced from\nofficial government feeds, community-decoded SA pager feeds and an agency feed whose licence is not published (NT PFES).\nIt may be delayed, incomplete, or inaccurate. Do not use this API as a substitute for\nofficial emergency warnings.\n","version":"1.110.1","contact":{"name":"DataQuoll Support","url":"https://dataquoll.io"},"license":{"name":"Proprietary"}},"x-service-info":{"docs":{"homepage":"https://dataquoll.io","apiReference":"https://docs.dataquoll.io","llms":"https://dataquoll.io/llms.txt"}},"servers":[{"url":"https://dataquoll.io","description":"Primary host"},{"url":"https://emergencyapi.com","description":"Legacy host, identical responses until the announced sunset"}],"paths":{"/api/v1/incidents":{"get":{"operationId":"listIncidents","summary":"List all current incidents","description":"Returns a GeoJSON FeatureCollection of all current emergency incidents, with support for filtering, pagination, and bounding box queries.","tags":["Incidents"],"parameters":[{"name":"state","in":"query","description":"Comma-separated state codes (e.g. nsw,vic,qld)","schema":{"type":"string"},"example":"nsw,vic"},{"name":"eventType","in":"query","description":"Comma-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.","schema":{"type":"string"},"example":"bushfire,flood"},{"name":"category","in":"query","description":"Comma-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.","schema":{"type":"string"},"example":"fire,weather"},{"name":"featureType","in":"query","description":"Comma-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.","schema":{"type":"string"},"example":"warning_area"},{"name":"severity","in":"query","description":"CAP-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.","schema":{"type":"string"},"example":"Extreme,Severe"},{"name":"urgency","in":"query","description":"CAP-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.","schema":{"type":"string"},"example":"Immediate,Expected"},{"name":"certainty","in":"query","description":"CAP-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.","schema":{"type":"string"},"example":"Observed,Likely"},{"name":"warningLevel","in":"query","description":"Australian 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.","schema":{"type":"string"},"example":"watch_and_act,emergency_warning"},{"name":"status","in":"query","description":"Incident status filter","schema":{"type":"string"},"example":"active,contained"},{"name":"agency","in":"query","description":"Source agency filter","schema":{"type":"string"},"example":"rfs,cfs"},{"name":"official","in":"query","description":"Filter 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.\n\nRead 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.","schema":{"type":"boolean"}},{"name":"bbox","in":"query","description":"Bounding box: minLon,minLat,maxLon,maxLat. Records at precision 'state' (not placed) are never inside a box, so a bbox query leaves them out.","schema":{"type":"string"},"example":"150.0,-34.0,152.0,-33.0"},{"name":"limit","in":"query","description":"Results per page (default 100, max 500)","schema":{"type":"integer","default":100,"maximum":500}},{"name":"cursor","in":"query","description":"Opaque pagination cursor, taken from meta.next_cursor of the previous response. Absent next_cursor means there are no further pages.","schema":{"type":"string"}},{"name":"after","in":"query","description":"Alias for cursor. This is the parameter name emitted in links.next, and is accepted for backward compatibility. If both are supplied, after wins.","schema":{"type":"string"}},{"name":"format","in":"query","description":"Response 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.","schema":{"type":"string","enum":["geojson","json","csv","cap-au","cap-atom"],"default":"geojson"}},{"name":"include_retracted","in":"query","description":"Include retracted incidents (default false). Retracted incidents are marked when upstream feeds stop publishing them.","schema":{"type":"boolean","default":false}},{"name":"include_boundary","in":"query","description":"Set 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.","schema":{"type":"boolean","default":false}}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"80000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.08"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"80000"}}]},"responses":{"200":{"description":"A GeoJSON FeatureCollection of incidents","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"},"RateLimit-Limit":{"schema":{"type":"integer"}},"RateLimit-Remaining":{"schema":{"type":"integer"}},"RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/geo+json":{"schema":{"$ref":"#/components/schemas/IncidentCollection"},"example":{"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"}}}},"400":{"description":"A malformed parameter (a filter, limit or cursor), or a CAP format asked for forecasts","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"403":{"description":"A paid format (csv, cap-au, cap-atom) below the Developer plan, or a key restricted to other origins or endpoints","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"Rate limit exceeded","headers":{"RateLimit-Limit":{"schema":{"type":"integer"}},"RateLimit-Remaining":{"schema":{"type":"integer"}},"RateLimit-Reset":{"schema":{"type":"integer"}},"Retry-After":{"description":"Seconds until the monthly quota resets.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/incidents/{id}":{"get":{"operationId":"getIncident","summary":"Get a single incident","description":"Returns a single incident as a GeoJSON Feature.","tags":["Incidents"],"parameters":[{"name":"id","in":"path","required":true,"description":"Incident ID (e.g. nsw-rfs-1234567)","schema":{"type":"string"}},{"name":"format","in":"query","description":"Response 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.","schema":{"type":"string","enum":["geojson","cap-au"],"default":"geojson"}}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"80000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.08"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"80000"}}]},"responses":{"200":{"description":"A GeoJSON Feature, or a CAP-AU alert document when format=cap-au","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/geo+json":{"schema":{"$ref":"#/components/schemas/IncidentFeature"}},"application/cap+xml":{"schema":{"type":"string","description":"A single CAP-AU <alert> document (XML)."}}}},"400":{"description":"format=cap-au for a record that is not an alert (a forecast)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"404":{"description":"Incident not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/incidents/nearby":{"get":{"operationId":"nearbyIncidents","summary":"Find incidents near a location","description":"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.","tags":["Incidents"],"parameters":[{"name":"lat","in":"query","required":true,"description":"Latitude","schema":{"type":"number"},"example":-33.87},{"name":"lng","in":"query","required":true,"description":"Longitude","schema":{"type":"number"},"example":151.21},{"name":"radius","in":"query","required":true,"description":"Radius in kilometres (max 500)","schema":{"type":"number"},"example":50},{"name":"limit","in":"query","schema":{"type":"integer","default":100}},{"name":"state","in":"query","schema":{"type":"string"}},{"name":"eventType","in":"query","schema":{"type":"string"}},{"name":"severity","in":"query","schema":{"type":"string"}},{"name":"category","in":"query","description":"Comma-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.","schema":{"type":"string"},"example":"fire,weather"},{"name":"urgency","in":"query","schema":{"type":"string"}},{"name":"certainty","in":"query","schema":{"type":"string"}},{"name":"warningLevel","in":"query","schema":{"type":"string"}},{"name":"agency","in":"query","schema":{"type":"string"}},{"name":"official","in":"query","description":"Filter 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.\n\nRead 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.","schema":{"type":"boolean"}},{"name":"status","in":"query","description":"Comma-separated incident statuses (active, contained, controlled, safe, completed). Defaults to all.","schema":{"type":"string"}},{"name":"include_retracted","in":"query","description":"Set true to include retracted incidents. Default false; retracted incidents are hidden, matching /api/v1/incidents.","schema":{"type":"boolean","default":false}},{"name":"include_boundary","in":"query","description":"Set 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.","schema":{"type":"boolean","default":false}}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"80000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.08"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"80000"}}]},"responses":{"200":{"description":"Nearby incidents as GeoJSON FeatureCollection","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/geo+json":{"schema":{"$ref":"#/components/schemas/IncidentCollection"}}}},"400":{"description":"Missing or invalid parameters","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/incidents/snapshot":{"get":{"operationId":"incidentSnapshot","summary":"Audit trail snapshot","description":"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.","tags":["Incidents"],"parameters":[{"name":"datetime","in":"query","required":true,"description":"ISO 8601 datetime to query (cannot be in the future)","schema":{"type":"string","format":"date-time"},"example":"2026-04-20T14:30:00+09:30"},{"name":"state","in":"query","description":"Filter by state code. Required for archive (pre-2026-04-08) snapshots.","schema":{"type":"string"},"example":"sa"},{"name":"event_type","in":"query","description":"Filter by event type","schema":{"type":"string"},"example":"bushfire"},{"name":"feature_type","in":"query","description":"Comma-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.","schema":{"type":"string"},"example":"incident,road_disruption"},{"name":"limit","in":"query","description":"Max results (default 500). An integer from 1 to 500; anything else is a 400.","schema":{"type":"integer","default":500,"minimum":1,"maximum":500}},{"name":"include_boundary","in":"query","description":"Set 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.","schema":{"type":"boolean","default":false}}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"200000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.20"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"200000"}}]},"responses":{"200":{"description":"Incidents active at the requested datetime","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/geo+json":{"schema":{"$ref":"#/components/schemas/IncidentCollection"}}}},"400":{"description":"Missing 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)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"403":{"description":"Archive access requires a paid plan, or the datetime predates your tier's lookback window","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"Rate limit exceeded","headers":{"RateLimit-Limit":{"schema":{"type":"integer"}},"RateLimit-Remaining":{"schema":{"type":"integer"}},"RateLimit-Reset":{"schema":{"type":"integer"}},"Retry-After":{"description":"Seconds until the monthly quota resets.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/incidents/history":{"get":{"operationId":"listHistoricalIncidents","summary":"Historical incident data (paid tier)","description":"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.","tags":["Incidents"],"parameters":[{"name":"state","in":"query","description":"Comma-separated state codes","schema":{"type":"string"},"example":"wa,sa"},{"name":"eventType","in":"query","description":"Comma-separated event types","schema":{"type":"string"},"example":"bushfire,flood"},{"name":"official","in":"query","description":"Filter 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.\n\nRead 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.","schema":{"type":"boolean"}},{"name":"after","in":"query","description":"Start of date range (ISO 8601, inclusive). Tier-limited.","schema":{"type":"string","format":"date-time"},"example":"2022-01-01T00:00:00Z"},{"name":"before","in":"query","description":"End of date range (ISO 8601, exclusive). Defaults to now.","schema":{"type":"string","format":"date-time"}},{"name":"cursor","in":"query","description":"Opaque 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`.","schema":{"type":"string"}},{"name":"limit","in":"query","description":"Max results per page (1-500, default 100)","schema":{"type":"integer","default":100,"maximum":500}}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"200000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.20"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"200000"}}]},"responses":{"200":{"description":"Historical incidents matching filters","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/geo+json":{"schema":{"$ref":"#/components/schemas/HistoricalIncidentCollection"}}}},"400":{"description":"Invalid before or after, filters, limit or cursor, or a window too large to answer within the database budget (narrow it)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"403":{"description":"Free tier blocked or depth limit exceeded","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"Rate limit exceeded","headers":{"RateLimit-Limit":{"schema":{"type":"integer"}},"RateLimit-Remaining":{"schema":{"type":"integer"}},"RateLimit-Reset":{"schema":{"type":"integer"}},"Retry-After":{"description":"Seconds until the monthly quota resets.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/states":{"get":{"operationId":"listStates","summary":"Feed health by state","description":"Returns the status of each state feed, including last poll time, health, and incident count.","tags":["Meta"],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"80000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.08"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"80000"}}]},"responses":{"200":{"description":"Feed status for all states","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/json":{"schema":{"type":"object","properties":{"states":{"type":"array","items":{"type":"object","properties":{"state":{"type":"string"},"agency":{"type":"string"},"status":{"type":"string","enum":["healthy","degraded","down","unknown"]},"lastPolled":{"type":"string","format":"date-time"},"lastSuccess":{"type":"string","format":"date-time"},"incidentCount":{"type":"integer"},"errorCount":{"type":"integer"}}}}}}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/declarations/postcode/{postcode}":{"get":{"operationId":"declarationsByPostcode","summary":"Disaster declaration status for a postcode","description":"Returns the declaration STATUS for a postcode: declared, partial, activation_only, not_declared, uncertain, or unknown_postcode, with per-LGA detail and official source links. Reports declared-area status only; the billing/eligibility decision rests with the practitioner.","tags":["Declarations"],"parameters":[{"name":"postcode","in":"path","required":true,"schema":{"type":"string","pattern":"^\\d{4}$"},"example":"4380"},{"name":"as_at","in":"query","description":"Point-in-time check (YYYY-MM-DD). Defaults to today.","schema":{"type":"string","format":"date"}},{"name":"include_expired","in":"query","description":"Include expired records in the per-LGA lists. Never changes matchStatus.","schema":{"type":"boolean","default":false}},{"name":"instrument_type","in":"query","description":"Trim the returned record lists to one instrument type. Never changes matchStatus.","schema":{"type":"string","enum":["state_natural_disaster_declaration","drfa_activation_agrn","state_of_disaster_emergency_powers"]}},{"name":"suburb","in":"query","description":"Optional suburb/locality name (ABS SAL) to narrow the result to the local government areas that suburb falls in, within this postcode only. Matching is exact after normalisation; there is no fuzzy matching. An unmatched suburb never fails the lookup: the full-postcode result is returned with narrowing.applied=false, a reason, and the postcode's known suburbs. Narrowing can legitimately change matchStatus (for example partial to declared); a suburb that itself spans two LGAs stays partial, and a bare name that denotes suburbs on both sides of a border (Mingoola in 4380) matches all of them.","schema":{"type":"string"},"example":"Stanthorpe"}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"500000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.50"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"500000"}}]},"responses":{"200":{"description":"Declaration status (including unknown_postcode for an absent postcode)","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PostcodeDeclarationResult"}}}},"400":{"description":"Malformed postcode or as_at","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"401":{"description":"Missing or invalid API key. While pay per request is on, a request with no Authorization header gets 402 instead.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"403":{"description":"The declarations API is not on this account (it comes with the Organisation licence)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"Rate limit exceeded","headers":{"RateLimit-Limit":{"schema":{"type":"integer"}},"RateLimit-Remaining":{"schema":{"type":"integer"}},"RateLimit-Reset":{"schema":{"type":"integer"}},"Retry-After":{"description":"Seconds until the monthly quota resets.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/declarations/point":{"post":{"operationId":"declarationsByPoint","summary":"Disaster declaration status for an exact point","description":"Returns the declaration STATUS for the local government area containing a lat/lng point, resolved against ABS LGA 2022 (ASGS Edition 3) boundary polygons at full resolution. POST with a JSON body is used deliberately so coordinates never appear in URLs or request logs; the request is read-only and safe to retry. Coordinates are never stored, logged, or echoed back, and the response is Cache-Control: no-store. Reports declared-area status only; the billing decision rests with the practitioner. A point outside every Australian LGA returns unknown_location. A point exactly on a shared LGA boundary returns every covering area with onBoundary=true. LGA matching is at ABS code level. ABS gives each state one catch-all code for land outside councils, which joins separate places (Unincorporated NSW is the Far West, Lord Howe Island and parts of Sydney Harbour). Where we hold part boundaries (NSW and Victoria), the matched LGA carries the part the point is in as area, and records placed in another part are left out; a record we hold against a whole catch-all, because the source's name for it matches no part we can place, carries scope part_not_stated and, where it differs from the ABS name, the source's own name in publishedFor.","tags":["Declarations"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PointLookupRequest"}}}},"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"500000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.50"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"500000"}}]},"responses":{"200":{"description":"Declaration status for the covering LGA (including unknown_location when no LGA covers the point)","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PointDeclarationResult"}}}},"400":{"description":"Invalid body, lat, lng, or as_at. Error detail never repeats submitted values.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"401":{"description":"Missing or invalid API key. While pay per request is on, a request with no Authorization header gets 402 instead.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"403":{"description":"The declarations API is not on this account (it comes with the Organisation licence)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"Rate limit exceeded","headers":{"RateLimit-Limit":{"schema":{"type":"integer"}},"RateLimit-Remaining":{"schema":{"type":"integer"}},"RateLimit-Reset":{"schema":{"type":"integer"}},"Retry-After":{"description":"Seconds until the monthly quota resets.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/hazard-history/point":{"post":{"operationId":"hazardHistoryByPoint","summary":"Observed record and declared status for an exact point","description":"What official sources recorded near a location, unioned with the disaster declarations that covered its local government area. Two lanes are returned because both are required: the observed lane (historical archive plus live-era incident history within a radius) and the declared lane (declarations for the covering ABS LGA, counted once per AGRN even when several authorities recorded the same event; with declarations access, the Organisation licence, and otherwise `{ included: false, reason }`). A feed that republishes another feed's incidents is left out of the observed lane so they are not counted twice (today nsw-rfs-cap, which repeats nsw-rfs). Medical calls are left out for privacy, alarm calls because an alarm is not a recorded hazard (the agency either found no fire or did not record the outcome), and road and traffic feeds because they record roadworks, closures and traffic rather than hazards. Mapped areas (fire footprints, official warning areas) stay in, because they record what reached a place, so one fire can count once per source that recorded it. Measured example: a Lismore address returns the February 2022 flood only through the declared lane, because the spatial lane holds no record for it at address precision. POST with a JSON body is used deliberately so coordinates never appear in URLs or request logs; the request is read-only and safe to retry. Coordinates are never stored, logged, or echoed back, and the response is Cache-Control: no-store. This reports a RECORD and a declared STATUS. It is not an assessment of risk, insurability, or any obligation, and absence of a record is not evidence that nothing happened. Precision is reported per record: a record at postcode precision sits at a postcode centroid, which can be kilometres from the event.","tags":["Hazard history"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HazardHistoryRequest"}}}},"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"250000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.25"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"250000"}}]},"responses":{"200":{"description":"The observed record and declared status for the point. A point outside every Australian LGA returns a null location and an empty declared lane. This response uses one hazard history lookup.","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"},"X-DataQuoll-Lookups-Remaining":{"description":"Hazard history lookups left this UTC month. Absent for accounts with no lookup ceiling.","schema":{"type":"integer","minimum":0}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HazardHistoryResult"}}}},"400":{"description":"Invalid body, lat, lng, radiusKm, or records, or a lookup that did not finish within the time limit (try again in a moment or use a smaller radiusKm; the lookup is not counted). Error detail never repeats submitted values.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"401":{"description":"Missing or invalid API key. While pay per request is on, a request with no Authorization header gets 402 instead.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"403":{"description":"The account has used its hazard history lookups for the month (100 free, then blocks of 1,000)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"Rate limit exceeded","headers":{"RateLimit-Limit":{"schema":{"type":"integer"}},"RateLimit-Remaining":{"schema":{"type":"integer"}},"RateLimit-Reset":{"schema":{"type":"integer"}},"Retry-After":{"description":"Seconds until the monthly quota resets.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/declarations":{"get":{"operationId":"listDeclarations","summary":"List/filter declarations","description":"Browse and historically report on declaration records. Filters and keyset (cursor) pagination. Record status is derived at query time.","tags":["Declarations"],"parameters":[{"name":"jurisdiction","in":"query","schema":{"type":"string","example":"nsw"}},{"name":"status","in":"query","schema":{"type":"string","enum":["active","expired","all"],"default":"active"}},{"name":"instrument_type","in":"query","schema":{"type":"string"}},{"name":"disaster_type","in":"query","schema":{"type":"string"}},{"name":"active_on","in":"query","schema":{"type":"string","format":"date"}},{"name":"limit","in":"query","description":"Records fetched per page, 1 to 500. Status is derived after the fetch, so a page can hold fewer records than limit, or none, while links.next is still set. Follow links.next until it is null.","schema":{"type":"integer","minimum":1,"default":100,"maximum":500}},{"name":"cursor","in":"query","description":"Opaque pagination cursor. Follow links.next, which is this request with only the cursor changed. A cursor marks a position, not a query: if you send one yourself, send the same filters and limit as the request that returned it, or you page a different listing.","schema":{"type":"string"}}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"500000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.50"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"500000"}}]},"responses":{"200":{"description":"A page of declaration records","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeclarationList"}}}},"400":{"description":"Invalid active_on date, status, limit, or cursor","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"401":{"description":"Missing or invalid API key. While pay per request is on, a request with no Authorization header gets 402 instead.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"403":{"description":"The declarations API is not on this account (it comes with the Organisation licence)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"Rate limit exceeded","headers":{"RateLimit-Limit":{"schema":{"type":"integer"}},"RateLimit-Remaining":{"schema":{"type":"integer"}},"RateLimit-Reset":{"schema":{"type":"integer"}},"Retry-After":{"description":"Seconds until the monthly quota resets.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/declarations/agrn/{agrn}":{"get":{"operationId":"declarationByAgrn","summary":"One disaster event by AGRN (across sources)","description":"The declaration/activation for an Australian Government Reference Number, merged across sources with the full affected-LGA list.","tags":["Declarations"],"parameters":[{"name":"agrn","in":"path","required":true,"schema":{"type":"string","pattern":"^\\d{1,6}$"},"example":"1284"}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"500000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.50"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"500000"}}]},"responses":{"200":{"description":"The merged declaration record","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeclarationDetail"}}}},"400":{"description":"Malformed AGRN (must be numeric)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"401":{"description":"Missing or invalid API key. While pay per request is on, a request with no Authorization header gets 402 instead.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"403":{"description":"The declarations API is not on this account (it comes with the Organisation licence)","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"404":{"description":"No declaration found for the AGRN","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"Rate limit exceeded","headers":{"RateLimit-Limit":{"schema":{"type":"integer"}},"RateLimit-Remaining":{"schema":{"type":"integer"}},"RateLimit-Reset":{"schema":{"type":"integer"}},"Retry-After":{"description":"Seconds until the monthly quota resets.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/status":{"get":{"operationId":"apiStatus","summary":"API health check","description":"Returns API health, version, uptime, and a summary of feed statuses.","tags":["Meta"],"responses":{"200":{"description":"API health status","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"ok"},"version":{"type":"string","example":"1.16.0"},"uptime":{"type":"string","example":"86400s"},"timestamp":{"type":"string","format":"date-time"},"counts":{"type":"object","description":"Summary of feed statuses. 'stale' is derived from last_polled_at age (a feed not polled within 2 hours reads as stale, so a dead poller is visible to monitors).","properties":{"total":{"type":"integer"},"healthy":{"type":"integer"},"degraded":{"type":"integer"},"down":{"type":"integer"},"stale":{"type":"integer","description":"Feeds not polled within 2 hours, derived from last_polled_at age regardless of stored status."},"unknown":{"type":"integer"}}},"feeds":{"type":"array","items":{"type":"object","properties":{"feedId":{"type":"string","description":"The feed's registry id, and the unique key for this entry. `state` and `agency` are NOT unique: two New South Wales RFS feeds and two Tasmanian TasALERT feeds each share a state/agency pair, so use `feedId` when you need to identify one exactly.","example":"nsw-rfs-cap"},"state":{"type":"string"},"agency":{"type":"string"},"status":{"type":"string","enum":["healthy","degraded","down","stale","unknown"]}}}}}}}}}}}},"/api/v1/attribution":{"get":{"operationId":"getAttribution","summary":"Data source attributions","description":"Returns attribution information for all data sources, including licence details. Required for CC BY compliance.","tags":["Meta"],"responses":{"200":{"description":"Attribution data for all sources","content":{"application/json":{"schema":{"type":"object","properties":{"description":{"type":"string"},"disclaimer":{"type":"string"},"count":{"type":"integer","description":"Number of sources returned"},"sources":{"type":"array","items":{"type":"object","properties":{"state":{"type":"string"},"agency":{"type":"string"},"name":{"type":"string"},"licence":{"type":"string","description":"The published licence. For the feeds we poll, only a recognised licence (CC BY, CC0, public domain) or an explicit 'Used with permission' statement is shown; anything else (internal working notes, unconfirmed sources) is reported as 'Licence under review — see https://dataquoll.io/compliance'. Other sources state the licence their publisher gives, such as the Open G-NAF EULA, the Open Database License (OpenStreetMap) or Commonwealth copyright."},"licenceUrl":{"type":"string","format":"uri","description":"The URL of the licence's own text, where we hold one (today, the Creative Commons page for CC licences). Absent where we hold none.","example":"https://creativecommons.org/licenses/by/4.0/"},"url":{"type":"string"},"official":{"type":"boolean","description":"true for a licensed statutory feed, false for every other source, such as the community-decoded pager feeds, agency feeds whose licence is not published (NT PFES), union and industry calendars, and OpenStreetMap."},"attribution":{"type":"string","description":"Agency-specified attribution text, present only when the source requires it."}}}}}}}}}}}},"/api/v1/events":{"get":{"operationId":"listEvents","summary":"List clustered events (incident intelligence)","description":"Returns spatially clustered emergency events as a GeoJSON FeatureCollection.\nEvents group related incidents using PostGIS ST_ClusterDBSCAN spatial clustering.\nEach event has a boundary polygon, centroid, affected suburbs, contributing agencies,\nand auto-generated title and summary. Only active events are returned by default.\n","tags":["Events"],"parameters":[{"name":"limit","in":"query","description":"Maximum events to return (default 50, max 200)","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}},{"name":"state","in":"query","description":"Comma-separated state codes to filter by (e.g. nsw,vic). Uses array overlap matching.","schema":{"type":"string"},"example":"nsw,vic"},{"name":"eventType","in":"query","description":"Comma-separated event types (e.g. bushfire,flood)","schema":{"type":"string"},"example":"bushfire,flood"},{"name":"severity","in":"query","description":"Comma-separated max severity levels, matched against maxSeverity as published: the highest severity any member's agency states, Unknown where none states one.","schema":{"type":"string"},"example":"Extreme,Severe"},{"name":"warningLevel","in":"query","description":"Comma-separated max warning levels, matched against maxWarningLevel as published: the highest level any member's agency states, none where none states one. An event whose maximum cannot be confirmed matches nothing.","schema":{"type":"string"},"example":"emergency_warning,watch_and_act"}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"80000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.08"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"80000"}}]},"responses":{"200":{"description":"A GeoJSON FeatureCollection of clustered events","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"},"RateLimit-Limit":{"schema":{"type":"integer"}},"RateLimit-Remaining":{"schema":{"type":"integer"}},"RateLimit-Reset":{"schema":{"type":"integer"}}},"content":{"application/geo+json":{"schema":{"$ref":"#/components/schemas/EventCollection"}}}},"401":{"description":"Missing or invalid API key. While pay per request is on, a request with no Authorization header gets 402 instead.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"Rate limit exceeded","headers":{"RateLimit-Limit":{"schema":{"type":"integer"}},"RateLimit-Remaining":{"schema":{"type":"integer"}},"RateLimit-Reset":{"schema":{"type":"integer"}},"Retry-After":{"description":"Seconds until the monthly quota resets.","schema":{"type":"integer"}}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/events/{id}":{"get":{"operationId":"getEvent","summary":"Get a single event with optional linked incidents","description":"Returns a single clustered event by ID. Use `include_incidents=true` to also\nretrieve all incidents that belong to this event cluster.\n","tags":["Events"],"parameters":[{"name":"id","in":"path","required":true,"description":"Event UUID","schema":{"type":"string","format":"uuid"}},{"name":"include_incidents","in":"query","description":"Include linked incidents in the response","schema":{"type":"boolean","default":false}}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"80000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.08"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"80000"}}]},"responses":{"200":{"description":"A single event as a GeoJSON Feature","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/geo+json":{"schema":{"allOf":[{"$ref":"#/components/schemas/EventFeature"},{"type":"object","properties":{"incidents":{"type":"array","description":"With include_incidents=true only: the event's incidents, newest first (500 at most), as /api/v1/incidents returns them.","items":{"$ref":"#/components/schemas/IncidentFeature"}}}}]}}}},"401":{"description":"Missing or invalid API key. While pay per request is on, a request with no Authorization header gets 402 instead.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"404":{"description":"Event not found","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/schema":{"get":{"operationId":"getSchema","summary":"API schema and valid enum values","description":"Returns all valid enum values for event types, categories, states, warning levels, and other filterable fields. Use this to discover what values are accepted by filter parameters. No authentication required.","tags":["Meta"],"responses":{"200":{"description":"All valid enum values and category mappings","content":{"application/json":{"schema":{"type":"object","properties":{"eventTypes":{"type":"array","items":{"type":"string"}},"eventCategories":{"type":"array","items":{"type":"string"}},"categoryMapping":{"type":"object","description":"Maps each category to its constituent event types"},"states":{"type":"array","items":{"type":"string"}},"warningLevels":{"type":"array","items":{"type":"string"}},"statuses":{"type":"array","items":{"type":"string"}},"severities":{"type":"array","items":{"type":"string"}},"urgencies":{"type":"array","items":{"type":"string"}},"certainties":{"type":"array","items":{"type":"string"}},"formats":{"type":"array","items":{"type":"string"}}}}}}}}}},"/api/v1/gauges":{"get":{"operationId":"listGauges","summary":"River gauge stations with live flood status","description":"Returns river gauge stations with their latest water level, the Bureau of Meteorology flood classification thresholds for each gauge, and a derived floodClass (below_minor, minor, moderate, major, or unclassified) computed from the latest reading against the published thresholds. Water-level readings are in metres relative to each gauge's local datum (each gauge carries its own unit, since some report in AHD). readingStatus flags stale data (bom-kiwis sourced stations are a 1-2 day archive, stale horizon 72 hours; bcc-telemetry are event-driven council ALERT loggers, stale horizon 48 hours; telemetry sources 24 hours). Defaults to water-level gauges; pass variable=rainfall for observed rainfall gauges, which report incremental millimetres and carry no flood classification. Status reporting, not flood prediction.","tags":["Gauges"],"parameters":[{"name":"variable","in":"query","description":"Measured variable. Defaults to water_level; rainfall returns observed rain gauges (millimetres, incremental, no flood class).","schema":{"type":"string","enum":["water_level","rainfall"],"default":"water_level"}},{"name":"state","in":"query","description":"Lowercase state code (nsw, vic, qld, sa, wa, tas, nt, act)","schema":{"type":"string"},"example":"nsw"},{"name":"floodClass","in":"query","description":"Filter to gauges at or above this class (>= semantics: minor matches moderate and major too). Water-level only; cannot combine with variable=rainfall.","schema":{"type":"string","enum":["minor","moderate","major"]}},{"name":"lga","in":"query","description":"ABS LGA code (the same LGA_2022 vocabulary as the declarations API)","schema":{"type":"string"},"example":"17750"},{"name":"source","in":"query","description":"Polling source (hydstra-nsw, hydstra-vic, hydstra-qld, aquarius-sa, aquarius-tas, aquarius-nt, bom-kiwis, bcc-telemetry)","schema":{"type":"string"}},{"name":"bbox","in":"query","description":"Bounding box minLng,minLat,maxLng,maxLat (within Australia)","schema":{"type":"string"},"example":"138.4,-35.4,139.0,-34.6"},{"name":"limit","in":"query","description":"Max results per page (1-500, default 100)","schema":{"type":"integer","default":100,"maximum":500}},{"name":"cursor","in":"query","description":"Pagination cursor from meta.nextCursor","schema":{"type":"string"}}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"80000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.08"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"80000"}}]},"responses":{"200":{"description":"Gauge stations with latest readings and flood status","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GaugeCollection"}}}},"401":{"description":"Missing or invalid API key. While pay per request is on, a request with no Authorization header gets 402 instead.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/gauges/{id}":{"get":{"operationId":"getGauge","summary":"One gauge with a 6-hour recent window","description":"Returns a single gauge station plus its trailing 6 hours of raw readings (enough to see the current trend). Deeper history is the tier-gated /api/v1/gauges/{id}/readings endpoint.","tags":["Gauges"],"parameters":[{"name":"id","in":"path","required":true,"description":"Gauge id from /api/v1/gauges (e.g. hydstra-nsw-410001)","schema":{"type":"string"}}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"80000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.08"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"80000"}}]},"responses":{"200":{"description":"The gauge and its recent readings","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/json":{"schema":{"type":"object","properties":{"gauge":{"$ref":"#/components/schemas/Gauge"},"recent":{"type":"array","items":{"$ref":"#/components/schemas/GaugeReading"}},"meta":{"type":"object","properties":{"recentWindowHours":{"type":"integer","description":"The window recent covers: 6 hours."},"totalMm":{"type":"number","description":"Rainfall gauges only: the sum of the window's readings, in millimetres. Longer totals come from /api/v1/gauges/{id}/readings."},"unit":{"type":"string","description":"Rainfall gauges only: mm."},"generatedAt":{"type":"string","format":"date-time"}}},"links":{"type":"object","properties":{"self":{"type":"string"},"readings":{"type":"string","description":"This gauge's reading history."}}},"disclaimer":{"type":"string"},"attribution":{"type":"string","format":"uri"}}}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"404":{"description":"No active gauge with that id","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/gauges/{id}/readings":{"get":{"operationId":"listGaugeReadings","summary":"Gauge reading history (paid tier)","description":"Historical water level readings for one gauge. Free tier is blocked (the free surface is current readings on /api/v1/gauges and the 6-hour window on /api/v1/gauges/{id}). Starter tier limited to 1 year lookback, Developer and Business to 5 years, Pro, Organisation and Enterprise unlimited. Retention ladder: raw 30 days, hourly rollups 90 days, daily forever, plus full-resolution raw inside flood-event windows kept forever. interval=auto picks the finest granularity available for the requested window.","tags":["Gauges"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"after","in":"query","description":"Start of range (ISO 8601, inclusive). Tier-limited.","schema":{"type":"string","format":"date-time"}},{"name":"before","in":"query","description":"End of range (ISO 8601, exclusive). Defaults to now.","schema":{"type":"string","format":"date-time"}},{"name":"interval","in":"query","description":"raw, hourly, daily, or auto (default)","schema":{"type":"string","enum":["raw","hourly","daily","auto"],"default":"auto"}},{"name":"above","in":"query","description":"Only readings at/above this published flood classification for the gauge","schema":{"type":"string","enum":["minor","moderate","major"]}},{"name":"limit","in":"query","schema":{"type":"integer","default":500,"maximum":1000}},{"name":"cursor","in":"query","description":"Pagination cursor from meta.nextCursor (ISO timestamp keyset)","schema":{"type":"string"}}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"80000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.08"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"80000"}}]},"responses":{"200":{"description":"Readings for the gauge, newest first","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/json":{"schema":{"type":"object","properties":{"gaugeId":{"type":"string"},"interval":{"type":"string"},"above":{"type":"string","enum":["minor","moderate","major"],"description":"Present with the above filter: the class asked for."},"aboveThresholdM":{"type":"number","description":"Present with the above filter: that class's published threshold for this gauge, in metres."},"readings":{"type":"array","items":{"$ref":"#/components/schemas/GaugeReading"}},"meta":{"type":"object","properties":{"count":{"type":"integer"},"hasMore":{"type":"boolean"},"nextCursor":{"type":"string","description":"Present when hasMore: the last reading's time (an ISO timestamp, or a date for daily buckets); pass it back as cursor."},"unit":{"type":"string","description":"mm for rainfall; for water level, metres and the gauge's datum, e.g. m (local gauge datum)."},"aboveNote":{"type":"string","description":"Present with the above filter: how an aggregated bucket matches it."},"generatedAt":{"type":"string","format":"date-time"}}},"links":{"type":"object","properties":{"self":{"type":"string"}}},"disclaimer":{"type":"string"},"attribution":{"type":"string","format":"uri"}}}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"403":{"description":"Free tier blocked or depth limit exceeded","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/gauges/summary":{"get":{"operationId":"getGaugeSummary","summary":"Flood status counts by state or LGA","description":"Counts of gauges at or above minor/moderate/major flood classification, grouped by state or LGA, plus the full list of at-or-above-minor stations (capped at 500). STALE GUARD: only readings within the staleness horizon enter class counts: a days-old reading above minor is counted as stale, never as a current flood signal.","tags":["Gauges"],"parameters":[{"name":"variable","in":"query","description":"Measured variable. Defaults to water_level (rain gauges carry no flood class, so they are excluded from the counts by default).","schema":{"type":"string","enum":["water_level","rainfall"],"default":"water_level"}},{"name":"groupBy","in":"query","description":"state (default) or lga (requires the state parameter)","schema":{"type":"string","enum":["state","lga"],"default":"state"}},{"name":"state","in":"query","schema":{"type":"string"},"example":"sa"}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"80000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.08"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"80000"}}]},"responses":{"200":{"description":"Flood status summary","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/json":{"schema":{"type":"object","properties":{"summary":{"type":"object","properties":{"total":{"type":"integer"},"minor":{"type":"integer"},"moderate":{"type":"integer"},"major":{"type":"integer"},"belowMinor":{"type":"integer","description":"Gauges with a current reading below the minor threshold."},"stale":{"type":"integer"},"unclassified":{"type":"integer"},"atOrAboveMinor":{"type":"integer"}}},"groupBy":{"type":"string","enum":["state","lga"]},"groups":{"type":"array","description":"One entry per state (key state) or LGA (key lgaCode, or unassigned), with that group's total, minor, moderate, major, belowMinor, stale and unclassified counts.","items":{"type":"object"}},"aboveMinorStations":{"type":"array","items":{"$ref":"#/components/schemas/Gauge"}},"meta":{"type":"object","properties":{"stationsEvaluated":{"type":"integer"},"truncated":{"type":"boolean","description":"True when more gauges are at or above minor than aboveMinorStations lists (500 at most)."},"staleGuard":{"type":"string"},"generatedAt":{"type":"string","format":"date-time"}}},"links":{"type":"object","properties":{"self":{"type":"string"}}},"disclaimer":{"type":"string"},"attribution":{"type":"string","format":"uri"}}}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/facilities":{"get":{"operationId":"listFacilities","summary":"Emergency service facility locations","description":"Where responders come from: the locations of police, ambulance, metropolitan fire, rural and country fire, and SES facilities across Australia, from Geoscience Australia under CC BY 4.0. A static reference layer, not a live feed.\n\nTwo lanes, and at least one is required. Either a radius search (lat, lng and radius together) or a filter (state and/or class). A bare call is rejected rather than returning all 8,888 facilities.\n\nAddress columns derived from G-NAF are deliberately not collected, because they carry a separate licence to the rest of the dataset.\n","tags":["Facilities"],"parameters":[{"name":"lat","in":"query","description":"Latitude of the search centre. Required with lng and radius.","schema":{"type":"number","minimum":-90,"maximum":90}},{"name":"lng","in":"query","description":"Longitude of the search centre. Required with lat and radius.","schema":{"type":"number","minimum":-180,"maximum":180}},{"name":"radius","in":"query","description":"Search radius in kilometres. Required with lat and lng.","schema":{"type":"number","exclusiveMinimum":0,"maximum":500}},{"name":"state","in":"query","description":"Lowercase state code. Note that three Australian Federal Police facilities in the Indian Ocean Territories carry no state and are returned only by radius search.\n","schema":{"type":"string","enum":["nsw","vic","qld","sa","wa","tas","nt","act"]}},{"name":"class","in":"query","description":"Facility class, as a short alias or the full source string.","schema":{"type":"string","enum":["police","ambulance","fire","rural_fire","ses","other"]}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":100}}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"80000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.08"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"80000"}}]},"responses":{"200":{"description":"Matching facilities","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer"},"disclaimer":{"type":"string","description":"States that a listed facility is not necessarily staffed or able to respond."},"facilities":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":["string","null"]},"class":{"type":"string","enum":["AMBULANCE STATION","POLICING FACILITY","METRO FIRE FACILITY","RURAL/COUNTRY FIRE SERVICE FACILITY","SES FACILITY","OTHER EMERGENCY MANAGEMENT FACILITY"]},"operationalStatus":{"type":["string","null"]},"coordinates":{"type":["object","null"],"properties":{"lat":{"type":"number"},"lng":{"type":"number"}}},"location":{"type":"object","properties":{"address":{"type":["string","null"]},"suburb":{"type":["string","null"]},"state":{"type":["string","null"]},"postcode":{"type":["string","null"]}}},"spatialConfidence":{"type":["string","null"]},"source":{"type":"object","properties":{"publisher":{"type":"string"},"agency":{"type":["string","null"],"description":"The state or territory agency Geoscience Australia sourced the record from."}}},"fetchedAt":{"type":"string","format":"date-time"}}}}}}}}},"400":{"description":"Neither lane supplied, or a parameter out of range"},"401":{"description":"Missing or invalid API key. While pay per request is on, a request with no Authorization header gets 402 instead."},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"Rate limit exceeded"}}}},"/api/v1/address":{"post":{"operationId":"lookupAddress","summary":"Look up an Australian address and what is known about it","description":"One Australian address in, one call: the address matched EXACTLY against G-NAF (every Australian address, Geoscape Australia under the Open G-NAF EULA), and what DataQuoll knows about its point: the local government area, declared-area status (with the declarations scope), active incidents within radiusKm, the nearest river gauge, the nearest emergency facilities and the mobile network sites around it.\n\nMatching is exact, never fuzzy: a misspelt street or suburb returns status no_match with the part that failed (reason and part), never a guess and never a list of addresses. Units (3/12, Unit 3, U3), levels, lots (Lot 101 Port Wakefield Rd), ranges (87-89) and suffixes (12A) are read exactly. Give the state or the postcode.\n\nprecision says how far G-NAF's point can be trusted: address (on the property), street, locality or interpolated. The LGA and declared-area status are given only for an address-level point, because a street or suburb point can sit in another LGA. The address is sent in the body and is never logged, stored or echoed; responses are not cached. Hazard history for the point is a separate call to /api/v1/hazard-history/point with the returned coordinates.\n","tags":["Addresses"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["address"],"properties":{"address":{"type":"string","maxLength":200,"description":"One line, e.g. \"12 Smith St, Morphett Vale SA 5162\". State or postcode required."},"radiusKm":{"type":"number","exclusiveMinimum":0,"maximum":50,"default":10,"description":"Radius for the incidents lane, in km."}}}}}},"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"80000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.08"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"80000"}}]},"responses":{"200":{"description":"A match with its answers, or status no_match with the part that failed","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["matched","no_match"]},"reason":{"type":"string","description":"no_match only.","enum":["not_understood","needs_state","no_locality","ambiguous_locality","no_street","ambiguous_street","no_number","no_lot","ambiguous_number","needs_unit","no_unit","ambiguous_unit","postcode_mismatch"]},"part":{"type":"string","description":"no_match only. The part of the address that failed, never its text.","enum":["address","postcode","state","unit","level","number","street","locality","po_box"]},"count":{"type":"integer","description":"needs_unit and the ambiguous reasons. How many addresses share that part (never listed)."},"understood":{"type":"object","description":"Which parts the parser found (true or false for building, unit, level, lot, number, state, postcode). Names only, never the text sent.","additionalProperties":{"type":"boolean"}},"address":{"type":"object","properties":{"gnafPid":{"type":"string"},"formatted":{"type":"string"},"components":{"type":"object","properties":{"building":{"type":["string","null"]},"level":{"type":["object","null"]},"unit":{"type":["object","null"]},"number":{"type":["string","null"]},"lot":{"type":["string","null"]},"street":{"type":"string"},"locality":{"type":"string"},"state":{"type":"string"},"postcode":{"type":["string","null"]}}},"coordinates":{"type":"object","properties":{"lat":{"type":"number"},"lng":{"type":"number"}}},"precision":{"type":"string","enum":["address","street","interpolated","locality","unstated"]},"geocodeType":{"type":["string","null"],"description":"G-NAF's default geocode type, e.g. PC (property centroid), STL, LOC, GG."},"confidence":{"type":["integer","null"],"description":"G-NAF's confidence: 2 is held by three or more contributors, -1 by none currently."},"lowConfidence":{"type":"boolean"},"alias":{"type":"boolean"},"addressType":{"type":["string","null"],"enum":["rural","urban",null]},"meshBlocks":{"type":"object","description":"ABS mesh block codes (2021 and 2026 editions).","properties":{"2021":{"type":["string","null"]},"2026":{"type":["string","null"]}}}}},"location":{"type":"object","properties":{"state":{"type":["string","null"]},"lga":{"type":"object","description":"code and name, or null with a reason when the point is not on the property."}}},"declarations":{"type":"object","description":"Declared-area status (the /api/v1/declarations/point answer) with included true, or included false and a reason. Status only, never eligibility. Any lane (location.lga, declarations, incidents, nearestGauge, facilities, mobileSites) that fails on its own answers { error } instead, and the rest of the answer stands."},"incidents":{"type":"object","properties":{"radiusKm":{"type":"number"},"count":{"type":"integer"},"nearest":{"type":"array","items":{"type":"object"},"description":"Up to 10 incident features, nearest first."}}},"nearestGauge":{"type":["object","null"],"description":"The nearest river (water-level) gauge with its distance in metres."},"facilities":{"type":"object","description":"The nearest emergency facility of each class within 25 km."},"mobileSites":{"type":"object","description":"Mobile site records within 2 km, counted per operator, and the nearest 5."},"disclaimer":{"type":"string"}}}}}},"400":{"description":"The body is not a JSON object with an address string, or radiusKm is out of range"},"401":{"description":"Missing or invalid API key. While pay per request is on, a request with no Authorization header gets 402 instead."},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"Rate limit exceeded"}}}},"/api/v1/mobile-sites":{"get":{"operationId":"listMobileSites","summary":"Mobile network site locations","description":"Where the mobile networks' radio sites are: Telstra, Optus, TPG and the Optus-TPG shared network (MOCN), from the ACCC Mobile Infrastructure Report data release under CC BY 2.5 AU. A yearly snapshot as at 31 January, not a live feed.\n\nEach record is one operator at one site. A tower shared by three networks appears three times, and Optus-TPG MOCN records repeat Optus actively shared sites, so a record count is not a tower count. rfnsaId is not unique even within one operator; id is the record key.\n\nTwo lanes, and at least one is required. Either a radius search (lat, lng and radius together, nearest first) or a filter (at least one of state, lga or operator). Both page with limit and offset; hasMore says whether another page exists. To find incidents near a site, pass its coordinates to /api/v1/incidents/nearby.\n","tags":["Mobile sites"],"parameters":[{"name":"lat","in":"query","description":"Latitude of the search centre. Required with lng and radius.","schema":{"type":"number","minimum":-90,"maximum":90}},{"name":"lng","in":"query","description":"Longitude of the search centre. Required with lat and radius.","schema":{"type":"number","minimum":-180,"maximum":180}},{"name":"radius","in":"query","description":"Search radius in kilometres. Required with lat and lng.","schema":{"type":"number","exclusiveMinimum":0,"maximum":500}},{"name":"operator","in":"query","description":"Network operator. mocn is accepted for optus-tpg-mocn.","schema":{"type":"string","enum":["telstra","optus","tpg","optus-tpg-mocn","mocn"]}},{"name":"state","in":"query","description":"Lowercase state code, from the local government area the site falls in. Sites in the ABS Other Territories (Christmas Island, Jervis Bay Territory) carry no state and are returned only by radius or lga; a few on water or offshore, outside every LGA, only by radius.\n","schema":{"type":"string","enum":["nsw","vic","qld","sa","wa","tas","nt","act"]}},{"name":"lga","in":"query","description":"Five-digit ABS local government area code (2022 edition), e.g. 17200 for Sydney.","schema":{"type":"string","pattern":"^[0-9]{5}$"}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":100}},{"name":"offset","in":"query","description":"Records to skip, for paging. The order is fixed, so pages never repeat or skip a record.","schema":{"type":"integer","minimum":0,"default":0}}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"80000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.08"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"80000"}}]},"responses":{"200":{"description":"Matching site records","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer"},"hasMore":{"type":"boolean"},"offset":{"type":"integer"},"asAt":{"type":"string","format":"date","description":"The date the ACCC snapshot describes (31 January of the release year)."},"disclaimer":{"type":"string","description":"States that a listed site is a location reference, not proof of service or coverage."},"sites":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","description":"Stable within one annual release only."},"rfnsaId":{"type":"string","description":"The Radio Frequency National Site Archive ID, as published. Shared by operators on one site."},"operator":{"type":"string","enum":["telstra","optus","tpg","optus-tpg-mocn"]},"coordinates":{"type":"object","properties":{"lat":{"type":"number"},"lng":{"type":"number"}}},"technologies":{"type":"array","items":{"type":"string"},"description":"The technology and band columns the ACCC marks for this record, e.g. LTE700, NR3500."},"generations":{"type":"array","items":{"type":"string","enum":["2G","3G","4G","5G"]}},"coFunded":{"type":["boolean","null"],"description":"true when built under a government co-contribution program. null means not recorded as co-funded, which is not the same as not co-funded: programs only had to be identified from 18 May 2020 (Mobile Black Spot from 2015).\n"},"coContributionProgram":{"type":["string","null"]},"fundingRound":{"type":["string","null"]},"activeSharing":{"type":["boolean","null"],"description":"Optus records only, as published."},"activeSharingParty":{"type":["string","null"]},"location":{"type":"object","properties":{"state":{"type":["string","null"]},"lgaCode":{"type":["string","null"]},"lgaName":{"type":["string","null"]}}},"distanceKm":{"type":"number","description":"Radius search only."},"asAt":{"type":"string","format":"date"},"source":{"type":"object","properties":{"publisher":{"type":"string"}}}}}}}}}}},"400":{"description":"Neither lane supplied, an unknown operator or state, or a parameter out of range"},"401":{"description":"Missing or invalid API key. While pay per request is on, a request with no Authorization header gets 402 instead."},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"Rate limit exceeded"}}}},"/api/v1/calendars":{"get":{"operationId":"listCalendars","summary":"Industry calendar editions","description":"Every industry-calendar edition on the platform, one per jurisdiction and year (NSW, VIC, QLD, WA, SA, TAS, ACT and NT for 2026), with its publisher, cover range and per-category counts. RDOs, public holidays, school holidays and industry shutdowns, read from each branch calendar and verified against the Fair Work Ombudsman list and the education departments' term dates.","tags":["Calendars"],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"80000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.08"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"80000"}}]},"responses":{"200":{"description":"The editions","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer"},"calendars":{"type":"array","items":{"type":"object","properties":{"jurisdiction":{"type":"string"},"year":{"type":"integer"},"title":{"type":"string"},"publisher":{"type":"string"},"source_url":{"type":"string","format":"uri"},"applies_to":{"type":"string","description":"Who the calendar is for. An RDO is the contracting industry's day, not a public holiday."},"covers":{"type":"object","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"}}},"timezone":{"type":"string","example":"Australia/Adelaide"},"counts":{"type":"object","additionalProperties":{"type":"integer"},"description":"Rows per category"},"discrepancies":{"type":"integer","description":"Recorded disagreements between the calendar and the official list"},"path":{"type":"string","example":"/api/v1/calendars/sa"}}}}}}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/calendars/{jurisdiction}":{"get":{"operationId":"getCalendarDays","summary":"Calendar days for a jurisdiction","description":"The day rows for one jurisdiction across a date range, each date answered by exactly one edition. Defaults to the current calendar year in the jurisdiction's own time zone; a lone from or to extends to the edge of its own year. Recorded disagreements between the calendar and the official list are returned under discrepancies. Rows can be CSV with format=csv.","tags":["Calendars"],"parameters":[{"name":"jurisdiction","in":"path","required":true,"description":"Jurisdiction code","schema":{"type":"string","enum":["nsw","vic","qld","sa","wa","tas","act","nt"]}},{"name":"from","in":"query","description":"First date, YYYY-MM-DD","schema":{"type":"string","format":"date"}},{"name":"to","in":"query","description":"Last date, YYYY-MM-DD","schema":{"type":"string","format":"date"}},{"name":"category","in":"query","description":"Comma-separated categories to include (default all). Values are the CalendarDay category enum.","schema":{"type":"string","example":"rdo,public_holiday"}},{"name":"format","in":"query","description":"json (default) or csv. 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.","schema":{"type":"string","enum":["json","csv"]}}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"80000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.08"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"80000"}}]},"responses":{"200":{"description":"The days in range","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/json":{"schema":{"type":"object","properties":{"jurisdiction":{"type":"string"},"timezone":{"type":"string","example":"Australia/Adelaide"},"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"},"count":{"type":"integer"},"days":{"type":"array","items":{"$ref":"#/components/schemas/CalendarDay"}},"editions":{"type":"array","items":{"$ref":"#/components/schemas/CalendarEdition"}},"discrepancies":{"type":"array","items":{"$ref":"#/components/schemas/CalendarDiscrepancy"}}}}},"text/csv":{"schema":{"type":"string"}}}},"400":{"description":"Unknown jurisdiction, malformed date, unknown category, or from after to","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/calendars/{jurisdiction}/{date}":{"get":{"operationId":"getCalendarDay","summary":"Is this a working day","description":"The answer for one date in one jurisdiction. A jurisdiction-wide public holiday wins, then the weekend, then the calendar's own entries in order (industry shutdown, RDO, part-day holiday, annual leave, industry event); otherwise working. Restricted holidays (a show day for one region, a public-service-only day) never decide it and are returned under restricted for the caller to apply to the employer's area.","tags":["Calendars"],"parameters":[{"name":"jurisdiction","in":"path","required":true,"description":"Jurisdiction code","schema":{"type":"string","enum":["nsw","vic","qld","sa","wa","tas","act","nt"]}},{"name":"date","in":"path","required":true,"description":"The date, YYYY-MM-DD","schema":{"type":"string","format":"date"}}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"80000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.08"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"80000"}}]},"responses":{"200":{"description":"The verdict","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CalendarVerdict"}}}},"400":{"description":"Unknown jurisdiction or malformed date","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"404":{"description":"No edition covers the date; the detail names the editions that exist","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}}}}},"/api/v1/publications":{"get":{"operationId":"listPublications","summary":"Official documents from the publisher registry","description":"Official documents, newest first: media releases, news, alerts and notices from the publishers in the registry (listPublishers). Today that is South Australia Police media releases, collected continuously since 26 September 2026, and Tasmania Police media releases and news, back to June 2010; both are kept after the publisher deletes them. Filter by state, publisher type or source, document kind, a publisher's own section, and a UTC date range; page with the cursor in links.next.\n\nFree keys see the last 7 days, from 00:00 UTC seven days back. A since or until outside that window is refused with 403 and counts against quota. Paid plans see the whole archive.\n\nA media release follows the event, often by hours or days, and an appeal for information is not a finding of fact. Where the text places the event in one suburb, extract.place gives the suburb and, when the text names one, the street, matched to G-NAF (Geoscape's national address file; attribution at /api/v1/attribution). extract also gives eventAt (when the text says the event happened), category (one of ten kinds, from the title) and attributes.is_appeal (the release asks the public for information); each is null when the text does not state it clearly, and extract.place is null when the text does not place the event in one suburb. Nothing is guessed. extract is null for a release not read yet, or one whose page has no text. Images are counted in imageCount; whether they are served is set per publisher.\n","tags":["Publications"],"parameters":[{"name":"state","in":"query","description":"Jurisdiction code, or a comma list. A jurisdiction with no publisher yet returns an empty list, not an error.","example":"sa","schema":{"type":"string"}},{"name":"type","in":"query","description":"Publisher type, or a comma list: police, fire, ses, ambulance, health, transport, council, union, other.","example":"police","schema":{"type":"string"}},{"name":"source","in":"query","description":"Publisher id from listPublishers, or a comma list.","example":"sa-police","schema":{"type":"string"}},{"name":"kind","in":"query","description":"Document kind, or a comma list: media_release, news, alert, notice.","example":"media_release","schema":{"type":"string"}},{"name":"section","in":"query","description":"One of the publisher's own sections. For South Australia Police, a district, region or topic such as northern-police-district, traffic or missing-persons. Tasmania Police has no site sections; its documents carry `feed` or `feed-walk`, the collection pass that saw them.","example":"northern-police-district","schema":{"type":"string"}},{"name":"since","in":"query","description":"First UTC date, YYYY-MM-DD, inclusive.","example":"2026-09-21","schema":{"type":"string","format":"date"}},{"name":"until","in":"query","description":"Last UTC date, YYYY-MM-DD, inclusive.","example":"2026-09-27","schema":{"type":"string","format":"date"}},{"name":"includeRemoved","in":"query","description":"true to include documents the publisher has since taken down. They stay in the archive with removedAt set. Default false.","example":false,"schema":{"type":"boolean","default":false}},{"name":"limit","in":"query","example":20,"schema":{"type":"integer","minimum":1,"maximum":500,"default":100}},{"name":"cursor","in":"query","description":"The opaque cursor from links.next.","schema":{"type":"string"}}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"80000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.08"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"80000"}}]},"responses":{"200":{"description":"The page of publications","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/json":{"schema":{"type":"object","properties":{"publications":{"type":"array","items":{"$ref":"#/components/schemas/Publication"}},"meta":{"type":"object","properties":{"generatedAt":{"type":"string","format":"date-time"},"count":{"type":"integer"},"depthDays":{"type":["integer","null"],"description":"Days of history this key sees; null for the whole archive."}}},"links":{"type":"object","properties":{"next":{"type":["string","null"]}}},"attribution":{"type":"string","format":"uri"}}},"example":{"publications":[{"id":"83c37297-3803-404c-babd-02225d57372e","source":"sa-police","publisher":{"name":"South Australia Police","agency":"SAPOL","type":"police","jurisdiction":"sa"},"kind":"media_release","slug":"dashcam-sought-after-eudunda-road-rage","title":"Dashcam sought after Eudunda road rage","summary":"Police are seeking witnesses and dashcam footage following a road rage incident at Eudunda.","publishedAt":"2026-09-26T00:26:36+00:00","modifiedAt":"2026-09-26T00:26:54+00:00","sections":["barossa-region","more-news","rss-news","yorke-mid-north-region"],"url":"https://www.police.sa.gov.au/sa-police-news-assets/front-page-news/dashcam-sought-after-eudunda-road-rage","versionCount":1,"removedAt":null,"attributes":{"crimeStoppersRef":"251098","metaTopstory":"no"},"extract":{"eventAt":"2026-09-25T01:45:00+00:00","place":{"suburb":"Eudunda","street":"Worlds End Highway","lat":-34.13564732,"lng":139.07308797,"precision":"street"},"category":null,"attributes":{"is_appeal":true},"method":"regex","extractedAt":"2026-10-21T05:00:00+00:00"},"imageCount":0}],"meta":{"generatedAt":"2026-09-27T03:00:00.000Z","count":1,"depthDays":null},"links":{"next":null},"attribution":"https://dataquoll.io/api/v1/attribution"}}}},"400":{"description":"Unknown state, type, source or kind, a malformed date, section, limit or cursor","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"401":{"description":"Missing or invalid API key. While pay per request is on, a request with no Authorization header gets 402 instead."},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"403":{"description":"A free key asked for dates outside its 7-day window","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"Rate limit exceeded"}}}},"/api/v1/publications/{id}":{"get":{"operationId":"getPublication","summary":"One publication in full","description":"One publication in full: the text body, every path it was published under, and its version list. Publishers edit releases in place and every edit is kept as a new version; the current version is returned unless version is given. images is null while the publisher's images are withheld (South Australia Police and Tasmania Police images are withheld pending legal advice on identifiable people) and for a document the publisher has taken down (removedAt set); otherwise a list of one-hour signed URLs. Free keys can read publications from the last 7 days.\n","tags":["Publications"],"parameters":[{"name":"id","in":"path","required":true,"description":"Publication id (a UUID) from listPublications.","example":"83c37297-3803-404c-babd-02225d57372e","schema":{"type":"string","format":"uuid"}},{"name":"version","in":"query","description":"A version number from the version list. Default the current version.","example":1,"schema":{"type":"integer","minimum":1}}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"80000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.08"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"80000"}}]},"responses":{"200":{"description":"The publication","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/json":{"schema":{"type":"object","properties":{"publication":{"$ref":"#/components/schemas/PublicationFull"},"meta":{"type":"object","properties":{"generatedAt":{"type":"string","format":"date-time"}}},"attribution":{"type":"string","format":"uri"}}},"example":{"publication":{"id":"83c37297-3803-404c-babd-02225d57372e","source":"sa-police","publisher":{"name":"South Australia Police","agency":"SAPOL","type":"police","jurisdiction":"sa"},"kind":"media_release","slug":"dashcam-sought-after-eudunda-road-rage","title":"Dashcam sought after Eudunda road rage","summary":"Police are seeking witnesses and dashcam footage following a road rage incident at Eudunda.","publishedAt":"2026-09-26T00:26:36+00:00","modifiedAt":"2026-09-26T00:26:54+00:00","sections":["barossa-region","more-news","rss-news","yorke-mid-north-region"],"url":"https://www.police.sa.gov.au/sa-police-news-assets/front-page-news/dashcam-sought-after-eudunda-road-rage","versionCount":1,"removedAt":null,"attributes":{"crimeStoppersRef":"251098","metaTopstory":"no"},"extract":{"eventAt":"2026-09-25T01:45:00+00:00","place":{"suburb":"Eudunda","street":"Worlds End Highway","lat":-34.13564732,"lng":139.07308797,"precision":"street"},"category":null,"attributes":{"is_appeal":true},"method":"regex","extractedAt":"2026-10-21T05:00:00+00:00"},"imageCount":0,"version":1,"body":"Police are seeking witnesses and dashcam footage following a road rage incident at Eudunda...","paths":["/sa-police-news-assets/barossa-region/dashcam-sought-after-eudunda-road-rage","/sa-police-news-assets/front-page-news/dashcam-sought-after-eudunda-road-rage","/sa-police-news-assets/yorke-mid-north-region/dashcam-sought-after-eudunda-road-rage"],"versions":[{"versionNo":1,"modifiedAt":"2026-09-26T00:26:54+00:00","title":"Dashcam sought after Eudunda road rage"}],"images":null},"meta":{"generatedAt":"2026-09-27T03:00:00.000Z"},"attribution":"https://dataquoll.io/api/v1/attribution"}}}},"400":{"description":"The id is not a UUID, or version is not a positive integer","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"401":{"description":"Missing or invalid API key. While pay per request is on, a request with no Authorization header gets 402 instead."},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"403":{"description":"A free key asked for a publication older than its 7-day window","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"404":{"description":"No publication with that id, or no such version","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"Rate limit exceeded"}}}},"/api/v1/publishers":{"get":{"operationId":"listPublishers","summary":"Publishers of official documents","description":"Every publisher of official documents on the platform: its jurisdiction and type, licence and required attribution, the document kinds it publishes, whether its images are served, the publisher-specific fields its documents carry in attributes and what each means, and live counts. A new publisher appears here the day it goes active; while it is paused (being collected or backfilled, not yet published) it is not listed, /api/v1/publications serves none of its documents and /api/v1/attribution does not credit it.\n","tags":["Publications"],"parameters":[{"name":"state","in":"query","description":"Jurisdiction code, or a comma list.","example":"sa","schema":{"type":"string"}},{"name":"type","in":"query","description":"Publisher type, or a comma list.","example":"police","schema":{"type":"string"}},{"name":"source","in":"query","description":"Publisher id, or a comma list.","example":"sa-police","schema":{"type":"string"}}],"security":[{"BearerAuth":[]},{"PaymentAuth":[]}],"x-payment-info":{"offers":[{"amount":"80000","currency":"0x20C000000000000000000000b9537d11c60E8b50","description":"One request","intent":"charge","method":"tempo"}],"price":{"mode":"fixed","currency":"USD","amount":"0.08"},"protocols":[{"mpp":{"method":"tempo","intent":"charge","currency":"0x20C000000000000000000000b9537d11c60E8b50"}},{"x402":{"scheme":"exact","network":"eip155:8453","asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913","amount":"80000"}}]},"responses":{"200":{"description":"The publishers","headers":{"Payment-Receipt":{"$ref":"#/components/headers/PaymentReceipt"}},"content":{"application/json":{"schema":{"type":"object","properties":{"publishers":{"type":"array","items":{"$ref":"#/components/schemas/Publisher"}},"meta":{"type":"object","properties":{"generatedAt":{"type":"string","format":"date-time"},"count":{"type":"integer"}}},"attribution":{"type":"string","format":"uri"}}},"example":{"publishers":[{"id":"sa-police","name":"South Australia Police","agency":"SAPOL","type":"police","jurisdiction":"sa","homeUrl":"https://www.police.sa.gov.au","licence":"CC BY 4.0","licenceUrl":"https://creativecommons.org/licenses/by/4.0/","attribution":"Contains SA Police media releases, (c) South Australia Police, used under CC BY 4.0.","commercialUse":true,"kinds":["media_release"],"serveImages":false,"attributes":{"crimeStoppersRef":"The Crime Stoppers reference an appeal asks readers to quote, when the release carries one."},"collection":{"kind":"scrape","cadence":"Front-page lists every 5 minutes, district, region and topic sections every 20."},"status":"active","publications":{"total":498,"live":498,"latestPublishedAt":"2026-09-27T02:01:36+00:00"},"lastCollectedAt":"2026-09-27T03:10:00+00:00"}],"meta":{"generatedAt":"2026-09-27T03:00:00.000Z","count":1},"attribution":"https://dataquoll.io/api/v1/attribution"}}}},"400":{"description":"Unknown state, type or source","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"401":{"description":"Missing or invalid API key. While pay per request is on, a request with no Authorization header gets 402 instead."},"402":{"description":"Pay 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.","headers":{"WWW-Authenticate":{"$ref":"#/components/headers/PaymentChallenge"}},"content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}},"application/json":{"schema":{"$ref":"#/components/schemas/ProblemDetails"}}}},"429":{"description":"Rate limit exceeded"}}}}},"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"API key in format: eak_live_... . Keys work from any origin by default. A key can optionally be restricted to specific browser origins in the dashboard; a request from a browser origin not on the allowlist is rejected with 403. Requests without an Origin header (server-side) are never blocked by this."},"PaymentAuth":{"type":"http","scheme":"payment","description":"Pay per request with MPP (the Machine Payments Protocol), for an agent with no API key. Send the request with no Authorization header and the 402 response carries the price in its WWW-Authenticate header. Pay it in USDC.e on Tempo with an MPP client, then send the request again with `Authorization: Payment <credential>`; the response carries a Payment-Receipt header. Offered only on the operations that list it, and only while pay per request is on. A request with a Bearer key is never charged. Prices, receipts and refunds: https://docs.dataquoll.io/machine-payments"}},"headers":{"PaymentChallenge":{"description":"The MPP payment challenge, scheme Payment: the price, the token, where to pay, the realm (dataquoll.io) and when the price expires, 5 minutes after it is issued. Pay it with an MPP client and send the request again with Authorization: Payment.","schema":{"type":"string"}},"PaymentReceipt":{"description":"Sent only on the response to a paid request (Authorization: Payment): the receipt for the payment, naming its transaction. Never sent when a key was used.","schema":{"type":"string"}}},"schemas":{"Publication":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"source":{"type":"string","description":"Publisher id; see listPublishers."},"publisher":{"type":"object","properties":{"name":{"type":"string"},"agency":{"type":"string"},"type":{"type":"string"},"jurisdiction":{"type":"string"}}},"kind":{"type":"string","enum":["media_release","news","alert","notice"]},"slug":{"type":"string"},"title":{"type":["string","null"]},"summary":{"type":["string","null"]},"publishedAt":{"type":"string","format":"date-time"},"modifiedAt":{"type":"string","format":"date-time","description":"The publisher's last edit of the current version."},"sections":{"type":"array","items":{"type":"string"},"description":"Every section of the publisher's site the document was listed under. Tasmania Police has no site sections; its documents carry `feed` or `feed-walk`, the collection pass that saw them."},"url":{"type":["string","null"],"format":"uri","description":"Where the publisher published it (the earliest path seen). Publishers delete documents, so it can stop resolving; the archive does not."},"versionCount":{"type":"integer"},"removedAt":{"type":["string","null"],"format":"date-time","description":"When the publisher stopped publishing it; null while still published."},"attributes":{"type":"object","additionalProperties":true,"description":"Publisher-specific fields. Their meanings are listed per publisher by listPublishers."},"extract":{"type":["object","null"],"description":"What was read from the release's own text: when, where, what kind of event, and whether it asks the public for information. Each field is null when the text does not state it clearly; nothing is guessed. Null when the release has not been read yet, or its page has no text.","properties":{"eventAt":{"type":["string","null"],"format":"date-time","description":"When the text says the event happened: a clock time with its day, either stated ('About 12.30am on Tuesday 20 October') or counted back from the release's own publication ('about 10am this morning', 'about 11.15pm on Saturday night'), read in the publisher's time zone and given as an instant (ISO 8601, UTC, like every timestamp here). Null when no single time could be read: a range, a roundup of several incidents, a time with no day, a stated date that does not fit, a coming event, or a time the release gives for when the event was found rather than when it happened."},"place":{"type":["object","null"],"description":"Null when the text does not place the event in one suburb. Otherwise where the text says the event happened, matched to G-NAF (Geoscape's national address file; attribution at /api/v1/attribution). suburb and street are G-NAF's names.","properties":{"suburb":{"type":["string","null"]},"street":{"type":["string","null"],"description":"The street the text names, or both streets of an intersection (\"Cross Street and Railway Terrace\"). Null when the text names none, or several."},"lat":{"type":["number","null"]},"lng":{"type":["number","null"]},"precision":{"type":["string","null"],"enum":["exact","address","street","locality","postcode","lga","state",null],"description":"street = on the named street within the named suburb: G-NAF's point for the street (the event was on it, somewhere along it, and on a long road that can be kilometres from the event), or, for an intersection the text names, the point where the two streets meet (attributes.intersection names them; placed only when G-NAF's addresses on the two streets come within 150 m). locality = the suburb's G-NAF point; a street, when given, has no point of its own here (an intersection G-NAF could not place, or a street G-NAF holds without a point or twice in that suburb). address is reserved for a house the text names; none is placed yet."}}},"category":{"type":["string","null"],"enum":["crash","drink_drug_driving","traffic_offence","theft_break_in","assault","drugs_weapons","fire","missing_person","death","community_advice",null],"description":"The kind of event, read from the title: crash; drink_drug_driving (drink or drug driving); traffic_offence (speeding, licence and other driving offences, pursuits); theft_break_in (theft, break-in, robbery); assault (assault and other violence); drugs_weapons (drugs, firearms and other weapons); fire; missing_person; death (a death that is not a crash); community_advice (warnings, scams and safety advice). Null when the title fits none of these, or several."},"attributes":{"type":"object","additionalProperties":true,"description":"Extraction details. is_appeal = true when the release asks the public for information (a Crime Stoppers ask included); help lines and general safety advice do not count. intersection = the two streets (G-NAF's names) of an intersection placed at their meeting point."},"method":{"type":"string"},"extractedAt":{"type":"string","format":"date-time"}}},"imageCount":{"type":"integer","description":"How many images the current version carries, served or not."}}},"PublicationFull":{"allOf":[{"$ref":"#/components/schemas/Publication"},{"type":"object","properties":{"version":{"type":"integer"},"body":{"type":["string","null"],"description":"The document text. The raw HTML is archived but never served."},"paths":{"type":"array","items":{"type":"string"}},"versions":{"type":"array","items":{"type":"object","properties":{"versionNo":{"type":"integer"},"modifiedAt":{"type":"string","format":"date-time"},"title":{"type":["string","null"]}}}},"images":{"type":["array","null"],"description":"Null while the publisher's images are withheld, and for a document the publisher has taken down (removedAt set); otherwise one-hour signed URLs.","items":{"type":"object","properties":{"position":{"type":"integer"},"url":{"type":"string","format":"uri"},"originalUrl":{"type":"string","format":"uri"},"sha256":{"type":["string","null"]},"bytes":{"type":["integer","null"]},"contentType":{"type":["string","null"]}}}}}}]},"Publisher":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"agency":{"type":"string"},"type":{"type":"string","enum":["police","fire","ses","ambulance","health","transport","council","union","other"]},"jurisdiction":{"type":"string","enum":["nsw","vic","qld","sa","wa","tas","act","nt","national"]},"homeUrl":{"type":"string","format":"uri"},"licence":{"type":"string"},"licenceUrl":{"type":"string","format":"uri"},"attribution":{"type":"string","description":"The attribution the licence requires wherever the documents are reused."},"commercialUse":{"type":"boolean"},"kinds":{"type":"array","items":{"type":"string"}},"serveImages":{"type":"boolean"},"attributes":{"type":"object","additionalProperties":{"type":"string"},"description":"Publisher-specific field name to meaning."},"collection":{"type":"object","properties":{"kind":{"type":"string","enum":["scrape","feed"]},"cadence":{"type":"string"}}},"status":{"type":"string","enum":["active","retired"],"description":"active = collected now; retired = no longer collected, and what it published stays served. A paused publisher is never listed."},"publications":{"type":"object","properties":{"total":{"type":"integer"},"live":{"type":"integer"},"latestPublishedAt":{"type":["string","null"],"format":"date-time"}}},"lastCollectedAt":{"type":["string","null"],"format":"date-time"}}},"IncidentFeature":{"type":"object","properties":{"type":{"type":"string","const":"Feature"},"id":{"type":"string","example":"nsw-rfs-1234567"},"geometry":{"type":"object","properties":{"type":{"type":"string","enum":["Point","Polygon","MultiPolygon"]},"coordinates":{"oneOf":[{"type":"array","items":{"type":"number"},"description":"[longitude, latitude] for Point"},{"type":"array","items":{"type":"array","items":{"type":"array","items":{"type":"number"}}},"description":"Ring arrays for Polygon"},{"type":"array","items":{"type":"array","items":{"type":"array","items":{"type":"array","items":{"type":"number"}}}},"description":"Polygon arrays for MultiPolygon (an incident whose area has several parts)"}]}}},"properties":{"type":"object","properties":{"source":{"type":"object","properties":{"state":{"type":"string"},"agency":{"type":"string"},"feedId":{"type":"string"}}},"title":{"type":"string"},"eventType":{"type":"string","enum":["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"]},"eventCategory":{"type":"string","enum":["fire","weather","rescue","hazmat","medical","alarm","planned","earth","hazard","other"],"description":"Groups related event types: the value the category filter matches, and always the /api/v1/schema categoryMapping of eventType. Documented since v1.12.3 but carried on features only from v1.97.0."},"featureType":{"type":"string","enum":["incident","incident_area","warning_area","fire_ban_area","road_disruption","forecast"],"description":"Point incident, boundary polygon, road segment or forecast. Defaults to 'incident'; list endpoints return only incidents unless ?featureType= is supplied."},"status":{"type":"string","enum":["active","contained","controlled","safe","completed"]},"warningLevel":{"type":"string","enum":["advice","watch_and_act","emergency_warning","none"],"description":"The Australian Warning System level, only as the agency states it. none means no warning level is published for this record: the agency states none, or the feed carries no warning level. DataQuoll never derives a level, and never reports none for a level it cannot confirm: where a feed's stored level could be DataQuoll's rather than the agency's (a level read from CAP severity where the alert names no AWS level, or a default), this property is absent. A Bureau of Meteorology warning on VicEmergency (Gale, Strong Wind, Severe Weather or Severe Thunderstorm Warning) states none: its kind is in title."},"severity":{"type":"string","enum":["Extreme","Severe","Moderate","Minor","Unknown"],"description":"CAP-AU severity, only as the agency states it; Unknown where it states none. DataQuoll never derives it from a warning level, resources, status or magnitude, and where a feed's stored value could be ours rather than the agency's, it reads Unknown. Most agencies state no severity, so most records read Unknown; use warningLevel for the agency's own warning."},"urgency":{"type":"string","enum":["Immediate","Expected","Future","Past","Unknown"],"description":"CAP-AU urgency, only as the agency states it; Unknown where it states none, as severity is. DataQuoll never derives it from a warning level or status."},"certainty":{"type":"string","enum":["Observed","Likely","Possible","Unlikely","Unknown"],"description":"CAP-AU certainty, only as the agency states it; Unknown where it states none, as severity is. A satellite's own confidence in a hotspot is in details.confidence."},"location":{"type":"object","properties":{"address":{"type":"string"},"suburb":{"type":"string"},"state":{"type":"string"},"lga":{"type":"string"},"latitude":{"type":"number","description":"Centroid latitude (extracted from geometry)"},"longitude":{"type":"number","description":"Centroid longitude (extracted from geometry)"},"precision":{"type":"string","enum":["exact","address","interpolated","street","grid_square","locality","postcode","lga","state","unstated"],"description":"How far the point can be trusted. 'exact' = the agency's own coordinates. 'grid_square' = the centre of the map-book grid square an SA pager message names (confidence grid_ref): a UBD square 125 to 313 m across, an SA Atlas town cell about 250 m; published 'exact' before v1.88.0. 'address', 'interpolated' and 'street' = an SA pager message placed with G-NAF. When the message names a usable map grid square the point is checked against it: at the address or intersection it names, within 50 m of the square ('interpolated' where G-NAF estimates that address along the street), or on the street it names, inside the square (confidence gnaf_address, gnaf_intersection or gnaf_street). When it names none, only an exact G-NAF match to the number, street and suburb it names is used ('address' or 'interpolated'; there is no square to check it against). 'locality' = the centre of the suburb or town the record names, or of a CFS map-book 1 km grid square. 'postcode' or 'lga' = approximate centroid backfilled for historical archive rows that logged no point. 'state' = the record could not be placed and the point only stands for somewhere in the state; radius and bounding-box searches leave these records out. 'unstated' = a historical archive record whose source never said how it was located (the label /api/v1/hazard-history/point gives the same record). Absent when no coordinates are available (geometry is null)."},"mapRef":{"type":"string","description":"SA pager records only: the map-book reference the message states, as paged (book, page and grid square, e.g. ADL 60 P14). The square grid_square and the gnaf_* confidences check a point against."},"confidence":{"type":"string","enum":["grid_ref","gnaf_address","gnaf_intersection","gnaf_street","geocoded","suburb","centroid"],"description":"How the point was placed, on records where the source did not supply it directly: grid_ref = the centre of a map-book grid cell; gnaf_address, gnaf_intersection and gnaf_street = an SA pager message matched in G-NAF (Geoscape's national address file; attribution at /api/v1/attribution) to the address, intersection or street it names, checked against the message's map grid square when it names one (within 50 m; on the street: inside it); with no usable square, only an exact address match is used. geocoded = poller 1.49.0 and later never write it. It remains on archived WA DFES records, where it marks the agency's own coordinates. suburb = the centre of the town or suburb. For SA pager messages since poller 1.49.0 it is the median of that locality's G-NAF addresses, or, with a regional map-book code, the median for that book's town (also when a facility is named). Earlier SA pager records may carry an OpenStreetMap-derived town point (credited at /api/v1/attribution). centroid = on a point, not placed (precision 'state'); on a historical archive area, the importer derived the record's location from the shape's centre, which says nothing about the shape. Set by the SA pager and WA DFES feeds, on any record that fell back to a state point, and on some archive fire and flood areas. Absent when the agency's own coordinates were used."},"postcode":{"type":["string","null"],"description":"Archive records only (meta.source archive): the postcode a QFD historical record names. Most such records logged no point and sit at the postcode's centroid (precision postcode)."},"region":{"type":["string","null"],"description":"Archive records only: the region a VIC fire history record names, as published (often empty)."},"regions":{"type":["string","null"],"description":"Archive records only: the regions an AIDR historical disaster record names, as published."},"district":{"type":["string","null"],"description":"Archive records only: the DBCA district code a WA fire history record states, e.g. SWC."},"brigade":{"type":["string","null"],"description":"Archive records only: the brigade an SA MFS or CFS historical record names, e.g. 20 ADELAIDE."},"description":{"type":["string","null"],"description":"Archive records only: the source's own words for the place, e.g. a Geoscience Australia earthquake's NORSEMAN, 50KM SE (also some QLD and WA flood and historical records)."}}},"boundary":{"type":["object","null"],"description":"The area the agency published for this incident (a fire perimeter, a warning area, a burn area), or null when it published none. geometry keeps the agency's point. Present on /api/v1/incidents/{id}, and on list endpoints only with include_boundary=true. Coordinates are rounded to 6 decimal places, like area geometry (points are rounded to 4).","properties":{"type":{"type":"string","enum":["Polygon","MultiPolygon"]},"coordinates":{"type":"array","description":"Ring arrays for Polygon; an array of those for MultiPolygon.","items":{}}}},"details":{"type":"object","description":"Agency-specific incident metadata, passed through from the source feed. OPTIONAL and varies by feed AND by incident (it is not standardised across agencies, and some feeds carry none). Render whatever keys are present rather than expecting a fixed set. The properties below are the common ones; the full per-feed breakdown (every field, its type and meaning) is documented at https://dataquoll.io/guides/incident-details-fields. An archive record (a snapshot before 2026-04-08) can also carry date_as_published or end_as_published: the source's own start or end where we replaced or cleared it.","properties":{"description":{"type":"string","description":"Source detail text; structure varies by feed (NSW RFS alert block, a place name, raw pager text, etc.)."},"resources":{"type":"integer","description":"Count of resources (crews/appliances/units) assigned or responding."},"aircraft":{"type":"integer","description":"Count of aircraft assigned (SA CFS)."},"region":{"type":"string","description":"Agency operational region, e.g. the SA CFS region number 1-6. Not a place name."},"fire_ban_district":{"type":"string","description":"Fire ban district, e.g. MOUNT LOFTY RANGES (SA CFS/MFS). Agency spelling, not normalised."},"decoded_units":{"type":"array","items":{"type":"string"},"description":"Responding unit names we decode from the unit callsigns in the pager message (SA pager feeds; our decode, not stated by the agency). Absent when no callsign decodes unambiguously."},"alarm_level":{"type":"integer","description":"The alarm (turn-out) level an SA fire or SES page states. A response level, not a public warning: pager rows carry warningLevel none and severity and urgency Unknown."},"alarm_level_description":{"type":"string","description":"The alarm level in words, e.g. \"Alarm level 2\". Rows archived before October 2026 say Advice, Watch and Act or Emergency Warning: our words for the same number, never agency warnings."},"priority":{"type":"integer","description":"The dispatch priority code an SA Ambulance page states, e.g. 1."},"priority_description":{"type":"string","description":"Our reading of the priority code (SA Ambulance pager)."},"incident_level":{"type":"integer","description":"The incident level SA CFS or MFS states (1 to 3, AIIMS): how big and complex the response is, not a public warning."},"size":{"type":"string","description":"Incident size label, e.g. Small/Medium/Large (VIC OSOM)."},"cad_id":{"type":"string","description":"CAD dispatch identifier (e.g. WA DFES 6-digit number)"},"source_id":{"type":"string","description":"Upstream agency record ID"},"source_url":{"type":"string","format":"uri","description":"Deep link to the incident on the source agency website"}},"additionalProperties":true},"timestamps":{"type":"object","properties":{"reported":{"type":["string","null"],"format":"date-time","description":"When the source reported it. An archive record carries its source's stated time where the source gave one (QFD, ACT ESA, earthquakes); one its source dated only to a day or a period carries that day (a period's first day) at the start of the day, UTC. Null when there is none, or where we have not yet carried the source's time over (the archive's CFA incidents and cyclone track points)."},"updated":{"type":["string","null"],"format":"date-time","description":"When the source last updated it. On an archive record, only a time its source stated: QFD's control or stop time, ACT ESA's call closing time, DEECA's under-control or record edit date; null elsewhere, where the archive stored an import time or a copy of the start."},"fetched":{"type":"string","format":"date-time"},"timeStated":{"type":"boolean","enum":[false],"description":"Present, and false, only when the source gave a date but no time: reported and updated then carry the right date at a time of day that is not the event's. SA CFS records from 17 April to 14 September 2026, whose time was never read. Absent means the times are the source's own."}}},"retraction":{"type":"object","description":"Present when the record has left its source. /api/v1/incidents shows such a record only with include_retracted=true. On a recent /api/v1/incidents/snapshot it can carry a withdrawal later than the snapshot moment: the record shows the latest state we hold, and upstream_removed is how an incident normally ends.","properties":{"retracted":{"type":"boolean"},"retractedAt":{"type":["string","null"],"format":"date-time"},"reason":{"type":"string"}}},"archive":{"type":"object","description":"Historical enrichment. Present only on deep-archive snapshot results (meta.source = archive). Each field appears only when populated.","properties":{"eventStartDate":{"type":"string","format":"date"},"eventEndDate":{"type":"string","format":"date"},"datePrecision":{"type":"string","enum":["month","season","financial_year","year","period"],"description":"Present only when the source stated less than a day: eventStartDate is then the first day of the stated period and datePeriodEnd its last, never a stated day."},"datePeriodEnd":{"type":"string","format":"date","description":"The last day of the stated period. Present with datePrecision."},"magnitude":{"type":"number","description":"The size the source states, in magnitudeScale units: the area burnt in hectares (fires and burns), or an earthquake's magnitude (MLa, mb, Mw and others)."},"magnitudeScale":{"type":"string"}}}}}}},"HistoricalIncidentFeature":{"type":"object","description":"One record from /api/v1/incidents/history. Its properties are flat and snake_case, unlike IncidentFeature on /api/v1/incidents: archive records and the pollers' own history share this shape.","properties":{"type":{"type":"string","const":"Feature"},"id":{"type":"string","example":"black-summer-1"},"geometry":{"type":["object","null"],"description":"GeoJSON Point, Polygon or MultiPolygon, the same shapes as IncidentFeature; null when the record has no location."},"properties":{"type":"object","properties":{"source_state":{"type":"string"},"source_agency":{"type":["string","null"]},"title":{"type":["string","null"]},"eventType":{"type":"string","description":"The same values as IncidentFeature eventType (GET /api/v1/schema lists them)."},"eventCategory":{"type":"string","enum":["fire","weather","rescue","hazmat","medical","alarm","planned","earth","hazard","other"],"description":"The value the category filter matches, and always the /api/v1/schema categoryMapping of eventType. Carried from v1.97.0."},"status":{"type":["string","null"]},"warningLevel":{"type":["string","null"],"description":"As IncidentFeature.warningLevel: only as the agency states it; absent where it cannot be confirmed. An imported archive record as its dataset recorded it."},"severity":{"type":["string","null"],"description":"As IncidentFeature.severity: only as the agency states it, Unknown where it states none. An imported archive record as its dataset recorded it."},"urgency":{"type":["string","null"],"description":"As IncidentFeature.urgency. An imported archive record as its dataset recorded it."},"certainty":{"type":["string","null"],"description":"As IncidentFeature.certainty. An imported archive record as its dataset recorded it."},"location":{"type":"object","description":"Location detail. Every located record states location.precision; an archive record its source never placed reads 'unstated'."},"details":{"type":"object","description":"Per-feed fields (see /guides/incident-details-fields). An archive record whose source stated only a period also carries date_precision and date_period_end here. Where we replaced a source value, details keeps it on any archive record, date_as_published (a start) or end_as_published (an end)."},"reported_at":{"type":["string","null"],"format":"date-time","description":"When the incident was reported. A period-dated archive record's reported_at is its period's first day at the start of the day, UTC, not a stated time."},"updated_at":{"type":["string","null"],"format":"date-time","description":"When the source last updated it. On an archive record, only a time its source stated: QFD's control or stop time, ACT ESA's call closing time, DEECA's under-control or record edit date; null elsewhere, where the archive stored an import time or a copy of the start."},"event_start_date":{"type":["string","null"],"format":"date","description":"The day the source states the event began; for a period-dated archive record, the period's first day (see date_precision)."},"event_end_date":{"type":["string","null"],"format":"date","description":"The end the source states. A few archive records state an end before their start; a snapshot ignores such an end."},"date_precision":{"type":"string","enum":["month","season","financial_year","year","period"],"description":"Present, with date_period_end, only on an archive record its source dated to a period rather than a day. Absent means a stated day."},"date_period_end":{"type":"string","format":"date","description":"The stated period's last day. Present exactly when date_precision is."},"time_stated":{"type":"boolean","enum":[false],"description":"Present, and false, only when the source gave a date but no time: reported_at and updated_at then carry the right date at a time of day that is not the event's. SA CFS records from 17 April to 14 September 2026, whose time was never read. Absent means the times are the source's own."},"featureType":{"type":"string","description":"Engine-era rows only, when the caller asked for areas with feature_type."},"retraction":{"type":"object","description":"Engine-era rows only, when a record was withdrawn for a reason other than leaving its agency's feed.","properties":{"retracted":{"type":"boolean"},"retractedAt":{"type":["string","null"],"format":"date-time"},"reason":{"type":"string"}}},"boundary":{"type":"object","description":"The incident's area polygon, when include_boundary=true and the record has one."}}}}},"HistoricalIncidentCollection":{"type":"object","properties":{"type":{"type":"string","const":"FeatureCollection"},"features":{"type":"array","items":{"$ref":"#/components/schemas/HistoricalIncidentFeature"}},"meta":{"type":"object","properties":{"total_count":{"type":"integer","description":"Records on this page."},"has_more":{"type":"boolean"},"size_limited":{"type":"boolean","description":"True when the page ended at the ~4 MB size cap rather than at limit; has_more is then true, so follow the cursor."},"next_cursor":{"type":["string","null"],"description":"Pass back as cursor for the next page, or follow links.next."},"sources":{"type":"array","description":"Which tables answered this window.","items":{"type":"string","enum":["archive","engine"]}},"generatedAt":{"type":"string","format":"date-time"}}},"links":{"type":"object","properties":{"self":{"type":"string"},"next":{"type":"string"}}},"attribution":{"type":"string","format":"uri"}}},"IncidentCollection":{"type":"object","properties":{"type":{"type":"string","const":"FeatureCollection"},"features":{"type":"array","items":{"$ref":"#/components/schemas/IncidentFeature"}},"meta":{"type":"object","properties":{"total_count":{"type":"integer"},"has_more":{"type":"boolean"},"next_cursor":{"type":"string"},"size_limited":{"type":"boolean","description":"/api/v1/incidents/snapshot. True when the answer ended at the ~4 MB size cap rather than at limit, so fewer records than asked for came back; truncated is then true too (narrow by state or event_type)."},"truncated":{"type":"boolean","description":"/api/v1/incidents/snapshot. True when more records were active at that moment than came back: the answer stopped at `limit` or at the size cap (`size_limited`). Raise limit (500 at most) or narrow by state or event_type."},"snapshot_datetime":{"type":"string","format":"date-time","description":"/api/v1/incidents/snapshot. The moment reconstructed, in UTC."},"source":{"type":"string","enum":["archive","live"],"description":"/api/v1/incidents/snapshot. archive: rebuilt from the historical archive (before 2026-04-08); live: from incident history and currently active incidents."},"generated_at":{"type":"string","format":"date-time","description":"/api/v1/incidents/snapshot. When this answer was built."},"generatedAt":{"type":"string","format":"date-time"}}},"links":{"type":"object","properties":{"self":{"type":"string"},"next":{"type":"string"}}},"data_freshness":{"type":"array","description":"How current each state's data is, one entry per state. Present on the GeoJSON and JSON responses; the csv, cap-au and cap-atom formats return before it is built.","items":{"type":"object","properties":{"state":{"type":"string","example":"sa"},"lastPolled":{"type":["string","null"],"format":"date-time","description":"The OLDEST successful poll across that state's feeds, so it bounds how current the state's data can be. It is deliberately not the most recent: taking the newest let one fast feed hide slower siblings and made a down feed invisible behind a healthy one. Null when any feed in the state has never succeeded."},"updateInterval":{"type":"string","description":"Shortest polling interval among that state's feeds, or `unknown`.","example":"60s"},"feedCount":{"type":"integer","description":"How many feeds this state has."},"feedsHealthy":{"type":"integer","description":"How many of them are currently healthy. Below feedCount means the state is degraded and some sources are not reporting."}}}},"attribution":{"type":"string"}}},"EventFeature":{"type":"object","properties":{"type":{"type":"string","const":"Feature"},"id":{"type":"string","format":"uuid","example":"fb6e6418-3edb-40ac-83c3-1afb2550e887"},"geometry":{"type":"object","description":"Boundary polygon (convex hull of cluster) or centroid point","properties":{"type":{"type":"string","enum":["Polygon","Point"]},"coordinates":{"oneOf":[{"type":"array","items":{"type":"array","items":{"type":"array","items":{"type":"number"}}},"description":"Ring arrays for Polygon boundary"},{"type":"array","items":{"type":"number"},"description":"[longitude, latitude] for Point centroid"}]}}},"properties":{"type":"object","properties":{"title":{"type":"string","example":"Cherry Gardens bushfire"},"incidentCount":{"type":"integer","example":42},"affectedSuburbs":{"type":"array","items":{"type":"string"},"example":["Cherry Gardens","Lobethal","Woodside"]},"affectedStates":{"type":"array","items":{"type":"string"},"example":["sa"]},"agencies":{"type":"array","items":{"type":"string"},"example":["CFS","MFS","GA-HOTSPOTS"]},"eventTypes":{"type":"array","items":{"type":"string"},"example":["bushfire"]},"maxSeverity":{"type":"string","enum":["Extreme","Severe","Moderate","Minor","Unknown"],"description":"The highest severity a member incident publishes (only as its agency states it), Unknown where none states one."},"maxWarningLevel":{"type":"string","enum":["advice","watch_and_act","emergency_warning","none"],"description":"The highest warning level a member incident publishes (only as its agency states it), none where none states one. Absent when a member's level cannot be confirmed and no confirmed one is an Emergency Warning."},"estimatedHectares":{"type":["number","null"],"example":2400.5},"summary":{"type":"string","example":"42 incidents from CFS, MFS, GA-HOTSPOTS affecting Cherry Gardens, Lobethal, Woodside."},"firstDetectedAt":{"type":["string","null"],"format":"date-time"},"lastUpdatedAt":{"type":"string","format":"date-time"},"isActive":{"type":"boolean"}}}}},"EventCollection":{"type":"object","properties":{"type":{"type":"string","const":"FeatureCollection"},"features":{"type":"array","items":{"$ref":"#/components/schemas/EventFeature"}},"meta":{"type":"object","properties":{"totalEvents":{"type":"integer"},"generatedAt":{"type":"string","format":"date-time"}}},"attribution":{"type":"string"}}},"CalendarDay":{"type":"object","description":"One row of an industry calendar. Null-valued fields are omitted from this description but always present in the JSON.","properties":{"date":{"type":"string","format":"date"},"weekday":{"type":"string","enum":["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]},"category":{"type":"string","enum":["public_holiday","part_day_public_holiday","restricted_public_holiday","poster_holiday","rdo","industry_shutdown","annual_leave","industry_event","union_event","school_holiday","school_term"],"description":"public_holiday is official and jurisdiction-wide. restricted_public_holiday is official but only for the area or sector in scope. poster_holiday is a day the source calendar colours as a holiday that is not one, kept for audit."},"subtype":{"type":["string","null"],"description":"The calendar's own split where it has one (scheduled, flexible, 36_hour_week, 38_hour_week, industry, eba, contracting, award, construction); null otherwise"},"scope":{"type":["string","null"],"description":"For restricted_public_holiday, the area or sector the day applies to; null otherwise"},"name":{"type":"string"},"poster_marking":{"type":["string","null"],"description":"What the source calendar shows for the day; null where it has no cell"},"official_match":{"type":["boolean","null"],"description":"For official holidays, whether the source calendar agrees; null where the question does not apply"},"part_day_from":{"type":["string","null"],"example":"19:00","description":"Local start time of a part-day holiday; null otherwise"},"range_end":{"type":["string","null"],"format":"date","description":"Last day of the range this row belongs to (a shutdown, a school break, a term); null otherwise"},"note":{"type":["string","null"]}}},"CalendarEdition":{"type":"object","properties":{"jurisdiction":{"type":"string"},"year":{"type":"integer"},"title":{"type":"string"},"publisher":{"type":"string"},"source_url":{"type":"string","format":"uri"},"applies_to":{"type":"string"},"covers":{"type":"object","properties":{"from":{"type":"string","format":"date"},"to":{"type":"string","format":"date"}}},"timezone":{"type":"string"}}},"CalendarDiscrepancy":{"type":"object","properties":{"date":{"type":"string","format":"date"},"issue":{"type":"string"}}},"CalendarVerdict":{"type":"object","properties":{"jurisdiction":{"type":"string"},"date":{"type":"string","format":"date"},"weekday":{"type":"string","enum":["Mon","Tue","Wed","Thu","Fri","Sat","Sun"]},"timezone":{"type":"string"},"status":{"type":"string","enum":["public_holiday","weekend","industry_shutdown","rdo","part_day_public_holiday","annual_leave","industry_event","working"]},"working_day":{"type":"boolean"},"applies_to":{"type":"string"},"entries":{"type":"array","items":{"$ref":"#/components/schemas/CalendarDay"},"description":"Every row on the date, including the ones that do not decide the verdict"},"restricted":{"type":"array","items":{"$ref":"#/components/schemas/CalendarDay"},"description":"Official holidays that apply only to the area or sector in their scope"},"edition":{"$ref":"#/components/schemas/CalendarEdition"}}},"ProblemDetails":{"type":"object","description":"RFC 9457 Problem Details","properties":{"type":{"type":"string","example":"https://emergencyapi.com/errors/rate-limit-exceeded"},"title":{"type":"string","example":"Rate Limit Exceeded"},"status":{"type":"integer","example":429},"detail":{"type":"string"},"instance":{"type":"string"}}},"DeclarationRecord":{"type":"object","properties":{"agrn":{"type":["string","null"]},"title":{"type":"string"},"instrumentType":{"type":"string","enum":["state_natural_disaster_declaration","drfa_activation_agrn","state_of_disaster_emergency_powers"]},"jurisdiction":{"type":"string"},"disasterTypes":{"type":"array","items":{"type":"string"}},"startDate":{"type":["string","null"],"format":"date"},"endDate":{"type":["string","null"],"format":"date"},"status":{"type":"string","enum":["active","expired","unknown"]},"source":{"type":"string","description":"Display name of the highest-precedence reporting source"},"sources":{"type":"array","items":{"type":"string"},"description":"Every government source reporting this AGRN+instrument for this LGA. Multiple entries = multiple sources corroborate it."},"sourceUrl":{"type":"string"},"sourcePublishedAt":{"type":["string","null"],"format":"date-time"},"scope":{"type":"string","enum":["part_not_stated"],"description":"Present only when we hold this record against a whole ABS catch-all area (for example Unincorporated SA) because the source's name for the area matches no part we can place. It still counts toward the status, except that a declaration held this way reads uncertain, never declared."},"publishedFor":{"type":"array","items":{"type":"string"},"description":"With scope only: the sources' own names for the area, verbatim (for example \"Unincorporated South Australia (Gawler Ranges)\"), leaving out any that is just the ABS name. Omitted when none remain."}}},"PostcodeDeclarationRecord":{"allOf":[{"$ref":"#/components/schemas/DeclarationRecord"},{"type":"object","properties":{"currencyConfidence":{"type":["string","null"],"enum":["strong","moderate","weak",null],"description":"TCDE currency-confidence band for an in-force record (null when not in force). Transparent evidence, never a numeric 'chance you can bill' score."},"basis":{"type":"string","description":"Short human-readable basis for this record's verdict (the evidence behind its status)."}}}]},"MatchedLga":{"type":"object","properties":{"lgaCode":{"type":"string"},"lgaName":{"type":"string"},"area":{"type":"object","description":"Present only when the location is inside an ABS catch-all code whose parts we hold boundaries for (NSW and Victoria): the part it is in. lgaCode stays the ABS code, and records the sources place in a different part are left out.","properties":{"code":{"type":"string","example":"19399-LHI"},"name":{"type":"string","example":"Lord Howe Island"}}},"populationShare":{"type":["number","null"],"description":"Share of the postcode's population in this LGA (ABS correspondence). Always the postcode-level share, even when the response is narrowed by suburb (never renormalised). null for point lookups, where population share is not a meaningful concept."},"declarationStatus":{"type":"string","enum":["declared","uncertain","activation_only","not_declared"]},"declarations":{"type":"array","items":{"$ref":"#/components/schemas/PostcodeDeclarationRecord"}}}},"SuburbNarrowing":{"type":"object","description":"Present on postcode responses only when the suburb parameter was supplied.","properties":{"requested":{"type":"string","description":"The trimmed caller input (up to 100 characters)"},"applied":{"type":"boolean"},"method":{"type":"string","enum":["spatial_derivation","abs_sal_lga_correspondence"],"description":"How suburb-to-LGA membership was derived. spatial_derivation = area-weighted intersection of ABS SAL 2021 and LGA 2022 boundary polygons (the current source; ABS publishes no SAL 2021 to LGA 2022 correspondence); abs_sal_lga_correspondence = a published ABS population-weighted correspondence, if one is adopted later."},"matchedSuburbs":{"type":"array","items":{"type":"object","properties":{"salCode":{"type":"string"},"salName":{"type":"string"}}},"description":"The ABS SAL suburb(s) the input matched within this postcode. More than one entry means the bare name denotes multiple suburbs (their LGA sets are unioned)."},"reason":{"type":"string","enum":["suburb_not_found_in_postcode","suburb_lgas_outside_postcode","unknown_postcode"],"description":"Present only when applied is false"},"knownSuburbs":{"type":"array","items":{"type":"string"},"description":"Present only when applied is false and the postcode is known: the postcode's suburb names, for typo recovery"}}},"PostcodeDeclarationResult":{"type":"object","properties":{"postcode":{"type":"string"},"matchStatus":{"type":"string","enum":["declared","partial","not_declared","uncertain","activation_only","unknown_postcode"]},"matchStatusReason":{"type":"string","description":"Present when matchStatus is uncertain or activation_only"},"matchedLgas":{"type":"array","items":{"$ref":"#/components/schemas/MatchedLga"}},"narrowing":{"$ref":"#/components/schemas/SuburbNarrowing"},"asAt":{"type":"string","format":"date","description":"Date the status was evaluated against; the requested as_at value or today (AEST) when omitted"},"dataLastUpdated":{"type":["string","null"],"format":"date-time"},"stale":{"type":"boolean"},"disclaimer":{"type":"string"},"meta":{"type":"object","properties":{"generatedAt":{"type":"string","format":"date-time"}}},"attribution":{"type":"string"}}},"HazardHistoryRequest":{"type":"object","required":["lat","lng"],"properties":{"lat":{"type":"number","description":"Latitude in decimal degrees, -90 to 90. Never logged or echoed.","example":-28.8078061},"lng":{"type":"number","description":"Longitude in decimal degrees, -180 to 180. Never logged or echoed.","example":153.2766097},"radiusKm":{"type":"number","description":"Search radius for the observed lane, greater than 0 and no more than 5. Defaults to 1.","default":1,"example":1},"records":{"type":"integer","description":"Maximum observed records returned in the list. Aggregates always cover everything in radius. 1 to 100, defaults to 25.","default":25,"example":25}}},"HazardHistoryResult":{"type":"object","properties":{"location":{"type":"object","description":"The ABS local government area containing the point. All fields are null when the point lies outside every Australian LGA.","properties":{"lgaCode":{"type":["string","null"],"example":"14850"},"lgaName":{"type":["string","null"],"example":"Lismore"},"stateCode":{"type":["string","null"],"example":"NSW"},"area":{"type":"object","description":"Present only inside an ABS catch-all code whose parts we hold boundaries for (NSW and Victoria): the part the point is in. Declarations placed in another part are left out.","properties":{"code":{"type":"string","example":"19399-LHI"},"name":{"type":"string","example":"Lord Howe Island"}}}}},"radiusKm":{"type":"number","example":1},"declared":{"type":"object","description":"Disaster declarations covering the local government area, counted once per AGRN. Declared status needs declarations access (the Organisation licence): without it this object is `{ included: false, reason }` and carries no record.","properties":{"included":{"type":"boolean","description":"Present and false only when the key's account has no declarations access; the lane then carries only `reason`."},"reason":{"type":"string","description":"Where declared status is available, when `included` is false."},"distinctCount":{"type":"integer","description":"Number of distinct AGRNs, not a row count. One event recorded by three authorities counts once.","example":27},"earliest":{"type":["string","null"],"format":"date"},"latest":{"type":["string","null"],"format":"date"},"records":{"type":"array","items":{"type":"object","properties":{"agrn":{"type":"string","example":"1012"},"title":{"type":"string"},"startDate":{"type":["string","null"],"format":"date"},"endDate":{"type":["string","null"],"format":"date"},"endDatePublished":{"type":"boolean","description":"Whether the authority published an end date. False with a null endDate means no end has been published, which does NOT mean the declaration is in force."},"jurisdiction":{"type":["string","null"]},"sources":{"type":"array","description":"Every source that recorded this AGRN, so a single row is traceable to the several authorities behind it.","items":{"type":"string"}},"scope":{"type":"string","enum":["part_not_stated"],"description":"Present only when we hold the declaration against a whole ABS catch-all area because the source's name for the area matches no part we can place."}}}},"sourceUrls":{"type":"object","description":"Official source URL per AGRN, where known. Omitted when none are.","additionalProperties":{"type":"string"}}}},"observed":{"type":"object","description":"What official sources recorded within the radius, from both lanes. byType, byPrecision, earliest, latest and records cover the historical archive and the live-era incident history together; archiveTotal and liveTotal split the count by lane.","properties":{"archiveTotal":{"type":"integer","example":7,"description":"Records from the historical archive."},"liveTotal":{"type":"integer","example":19,"description":"Records from the live-era incident history (2026-04-08 onward)."},"earliest":{"type":["string","null"],"format":"date","description":"The earliest dated record's date: the first day of its stated period when that record is dated only to a period (see earliestDatePrecision)."},"latest":{"type":["string","null"],"format":"date","description":"The latest dated record's date, the first day of its stated period when it has one (see latestDatePrecision)."},"earliestDatePrecision":{"type":"string","enum":["month","season","financial_year","year","period"],"description":"Present only when the earliest record is dated only to a period, not a day."},"latestDatePrecision":{"type":"string","enum":["month","season","financial_year","year","period"],"description":"Present only when the latest record is dated only to a period, not a day."},"undatedCount":{"type":"integer","description":"Records that carry no date. Present in the counts, flagged dated=false, never given an invented date."},"byType":{"type":"array","items":{"type":"object","properties":{"eventType":{"type":"string"},"eventCategory":{"type":["string","null"]},"count":{"type":"integer"},"earliest":{"type":["string","null"],"format":"date"},"latest":{"type":["string","null"],"format":"date"},"undated":{"type":"integer","description":"Records of this type that carry no date (counted, never placed in earliest or latest)."},"earliestDatePrecision":{"type":"string","enum":["month","season","financial_year","year","period"],"description":"As observed.earliestDatePrecision, for this type."},"latestDatePrecision":{"type":"string","enum":["month","season","financial_year","year","period"],"description":"As observed.latestDatePrecision, for this type."}}}},"byPrecision":{"type":"array","description":"How the matched records were located. Postcode-precision records sit at a postcode centroid, not at the event.","items":{"type":"object","properties":{"precision":{"type":"string","example":"postcode"},"geometryType":{"type":"string","example":"MultiPolygon"},"count":{"type":"integer"}}}},"records":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":["string","null"]},"eventType":{"type":"string"},"eventCategory":{"type":["string","null"]},"onDate":{"type":["string","null"],"format":"date"},"dated":{"type":"boolean"},"datePrecision":{"type":"string","enum":["month","season","financial_year","year","period"],"description":"Present only when the source stated less than a day: onDate is then the first day of the stated period (a month, a burn or fire season, a financial year, a calendar year, or another stated span) and datePeriodEnd its last. Neither is a stated day."},"datePeriodEnd":{"type":"string","format":"date","description":"The last day of the stated period. Present with datePrecision."},"precision":{"type":"string"},"geometryType":{"type":"string"},"sourceAgency":{"type":["string","null"]},"sourceFeedId":{"type":["string","null"]},"lane":{"type":"string","enum":["archive","live"],"description":"archive = the historical archive; live = the live-era incident history (2026-04-08 onward)."}}}}}},"gauge":{"type":["object","null"],"description":"Nearest active river gauge, for context. Not a flood assessment.","properties":{"name":{"type":"string"},"jurisdiction":{"type":["string","null"]},"distanceM":{"type":"integer"}}},"coverage":{"type":"array","description":"The measured limits of this answer. Rides on every response.","items":{"type":"string"}},"disclaimer":{"type":"string"}}},"PointLookupRequest":{"type":"object","required":["lat","lng"],"properties":{"lat":{"type":"number","minimum":-90,"maximum":90},"lng":{"type":"number","minimum":-180,"maximum":180},"as_at":{"type":"string","format":"date","description":"Point-in-time check (YYYY-MM-DD). Defaults to today."},"include_expired":{"type":"boolean","default":false,"description":"Include expired records in the per-LGA lists. Never changes matchStatus."},"instrument_type":{"type":"string","enum":["state_natural_disaster_declaration","drfa_activation_agrn","state_of_disaster_emergency_powers"],"description":"Trim the returned record lists to one instrument type. Never changes matchStatus."}}},"PointDeclarationResult":{"type":"object","properties":{"matchStatus":{"type":"string","enum":["declared","partial","not_declared","uncertain","activation_only","unknown_location"]},"matchStatusReason":{"type":"string","description":"Present when matchStatus is uncertain or activation_only"},"matchedLgas":{"type":"array","items":{"$ref":"#/components/schemas/MatchedLga"},"description":"Normally one area. Two areas only when the point lies exactly on a shared boundary (onBoundary=true); partial is then possible and means the covering areas have different statuses."},"onBoundary":{"type":"boolean","description":"Present (true) only when the point lies on a shared LGA boundary and more than one area is returned."},"boundaryEdition":{"type":"string","example":"LGA_2022","description":"ABS boundary edition the point was resolved against. Informative, not an enum: it changes with ASGS edition refreshes. LGA matching is at ABS code level; point-in-polygon cannot be more precise than the code."},"asAt":{"type":"string","format":"date","description":"Date the status was evaluated against; the requested as_at value or today (AEST) when omitted"},"dataLastUpdated":{"type":["string","null"],"format":"date-time"},"stale":{"type":"boolean"},"disclaimer":{"type":"string"},"meta":{"type":"object","properties":{"generatedAt":{"type":"string","format":"date-time"}}},"attribution":{"type":"string"}}},"DeclarationListItem":{"allOf":[{"$ref":"#/components/schemas/DeclarationRecord"},{"type":"object","properties":{"lgaCount":{"type":"integer"}}}]},"DeclarationList":{"type":"object","properties":{"declarations":{"type":"array","items":{"$ref":"#/components/schemas/DeclarationListItem"}},"dataLastUpdated":{"type":["string","null"],"format":"date-time"},"stale":{"type":"boolean"},"disclaimer":{"type":"string"},"meta":{"type":"object","properties":{"generatedAt":{"type":"string","format":"date-time"},"count":{"type":"integer","description":"Records on this page."}}},"links":{"type":"object","properties":{"next":{"type":["string","null"],"description":"The next page: this request's path and query with only cursor changed, so every filter and the limit carry over. Null when there is no next page."}}},"attribution":{"type":"string"}}},"DeclarationDetail":{"type":"object","properties":{"agrn":{"type":"string"},"title":{"type":"string"},"instrumentType":{"type":"string"},"jurisdiction":{"type":"string"},"disasterTypes":{"type":"array","items":{"type":"string"}},"startDate":{"type":["string","null"],"format":"date"},"endDate":{"type":["string","null"],"format":"date"},"status":{"type":"string","enum":["active","expired","unknown"]},"source":{"type":"string"},"sourcePublishedAt":{"type":["string","null"],"format":"date-time"},"sourceUrl":{"type":"string"},"contributingSources":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string"},"instrumentType":{"type":"string"},"sourceUrl":{"type":"string"}}}},"affectedLgas":{"type":"array","items":{"type":"object","properties":{"lgaCode":{"type":["string","null"]},"lgaName":{"type":"string"},"area":{"type":"object","description":"Present only when a source named a part of an ABS catch-all code (for example Lord Howe Island within Unincorporated NSW). lgaCode is then the catch-all's ABS code.","properties":{"code":{"type":"string","example":"19399-LHI"},"name":{"type":"string","example":"Lord Howe Island"}}}}}},"dataLastUpdated":{"type":["string","null"],"format":"date-time"},"stale":{"type":"boolean"},"disclaimer":{"type":"string"},"meta":{"type":"object","properties":{"generatedAt":{"type":"string","format":"date-time"}}},"attribution":{"type":"string"}}},"Gauge":{"type":"object","description":"A gauge station with its latest reading. Water-level readings are metres relative to the gauge's local datum, not sea level; rainfall readings are incremental millimetres. floodClass, thresholds and datum are present only on water-level gauges.","properties":{"id":{"type":"string","example":"hydstra-nsw-410001"},"name":{"type":"string"},"river":{"type":["string","null"]},"state":{"type":"string","example":"NSW"},"agency":{"type":["string","null"]},"source":{"type":"string"},"variable":{"type":"string","enum":["water_level","rainfall"],"description":"The measured variable. Rainfall gauges carry no floodClass, thresholds or datum."},"awrcStationNo":{"type":["string","null"]},"coordinates":{"type":"object","properties":{"lat":{"type":"number"},"lng":{"type":"number"}}},"lga":{"type":["object","null"],"properties":{"code":{"type":"string"},"name":{"type":["string","null"]}}},"latest":{"type":["object","null"],"properties":{"value":{"type":"number"},"observedAt":{"type":"string","format":"date-time"},"quality":{"type":["string","null"]}}},"readingStatus":{"type":"string","enum":["live","stale"]},"unit":{"type":"string","description":"Present on rainfall gauges (always 'mm'). Water-level gauges carry their unit inside thresholds.unit.","example":"mm"},"floodClass":{"type":"string","enum":["below_minor","minor","moderate","major","unclassified"],"description":"Water-level gauges only. Derived at read time from the latest reading vs the published BoM thresholds; never stored as judgement."},"thresholds":{"type":"object","description":"Water-level gauges only.","properties":{"minor":{"type":["number","null"]},"moderate":{"type":["number","null"]},"major":{"type":["number","null"]},"unit":{"type":"string"},"source":{"type":["string","null"]},"version":{"type":["string","null"]},"fetchedAt":{"type":["string","null"],"format":"date-time"}}},"datum":{"type":["object","null"],"description":"Water-level gauges only.","properties":{"gaugeZeroM":{"type":["number","null"]},"datum":{"type":["string","null"]}}}}},"GaugeReading":{"type":"object","description":"A raw reading (observedAt/value/quality) or an aggregated bucket (bucket/min/max/mean/nObs), depending on the interval.","properties":{"observedAt":{"type":"string","format":"date-time"},"value":{"type":"number"},"quality":{"type":["string","null"]},"bucket":{"type":"string"},"min":{"type":"number"},"max":{"type":"number"},"mean":{"type":"number"},"nObs":{"type":"integer"}}},"GaugeCollection":{"type":"object","properties":{"gauges":{"type":"array","items":{"$ref":"#/components/schemas/Gauge"}},"meta":{"type":"object","properties":{"count":{"type":"integer"},"hasMore":{"type":"boolean"},"nextCursor":{"type":"string"},"generatedAt":{"type":"string","format":"date-time"}}},"links":{"type":"object","properties":{"self":{"type":"string"}}},"disclaimer":{"type":"string"},"attribution":{"type":"string"}}}}},"security":[{"BearerAuth":[]}],"tags":[{"name":"Incidents","description":"Emergency incident data"},{"name":"Declarations","description":"Australian disaster declaration and DRFA funding-activation status by postcode and LGA. Reports declared-area status; the practitioner makes the billing/eligibility decision."},{"name":"Events","description":"Spatially clustered incident intelligence. Groups related incidents into events with boundary polygons, affected areas, and structured summaries."},{"name":"Gauges","description":"River gauge observations against the Bureau of Meteorology flood classifications. Status reporting, not flood prediction, and not a substitute for official warnings."},{"name":"Facilities","description":"Emergency service facility locations from Geoscience Australia: where responders come from. A reference layer, not a feed."},{"name":"Addresses","description":"Every Australian address from G-NAF, matched exactly, with what is known about its point. One address per call, never a list."},{"name":"Mobile sites","description":"Mobile network site records from the ACCC Mobile Infrastructure Report data release, a yearly snapshot. A location reference, not coverage."},{"name":"Calendars","description":"Industry calendars for NSW, VIC, QLD, WA, SA, TAS, ACT and NT: RDOs, public holidays, school holidays and shutdowns, verified against the official lists, with every source disagreement recorded."},{"name":"Publications","description":"Official documents from the publisher registry: media releases, news, alerts and notices, versioned and kept after the publisher deletes them. South Australia Police and Tasmania Police first."},{"name":"Meta","description":"API metadata and health"}]}