v4
latestOpenAPI 3.1.0Proprietary2026-08-034715226.2 KBGet event by ID
Returns full detail for a single event. Active events are always returned. Archived events are gated by plan: on plans without analytics access (allow_analytics: false) the request is rejected with 403 when the event's effective start_time (COALESCE(start_time, created_at)) is older than 7 days. Plans with analytics access have no such restriction.
Path parameters
Response
Event detail
How the event was archived. NULL while status='active'; set alongside archived_at at archival time.
- observed — upstream returned a clean response and the event was not in it, so the per-poll archival path retired it. This is the normal case.
- stale_sweep — the per-poll path could not retire the event because upstream responses were empty or errored (so we cannot prove the event is gone vs. a transient outage). After roughly poll_interval × sweep_factor with no fresh observation (default factor = 15), a safety-net sweep forces the event to archived. A persistently high stale_sweep ratio on a source signals that the upstream feed often fails to emit clearance records or is unreliable in general — treat the archived_at for such events as "presumed gone by", not a precise end timestamp.
- expired — the event outlived its own end_time by more than the grace period (90 days) while the upstream feed was still publishing it as current. Some feeds are registries that never retire a record, so neither path above can ever fire on them: without this, work orders whose validity window closed years ago would be served as active indefinitely. Because the verdict is derived from the record's own end_time on every poll, such an event returns to active automatically if upstream later moves the end date forward. Treat archived_at as "first poll at which the event was more than 90 days past its stated end", not as an observed end — the real end is end_time.
Set the moment our sweep first observed the event missing from the upstream feed.
Optional underlying operational cause, classified independently of type (unlike sub_type, which is scoped under type). A crash reported by the source as a closure has type=closure, sub_type=lane_closure, and cause=accident — so filtering cause=accident catches accident-caused events regardless of how the source modeled them. Omitted when no cause could be detected. Additive: never replaces type, sub_type, or severity.
When we first stored this event.
Best available end time for the event. Equals end_time when the upstream feed reported one; otherwise falls back to archived_at (the moment our sweep first observed the event had disappeared from the feed). NULL only for active events with no upstream-reported end — i.e., events that are still ongoing. Use this field for "incident duration" analytics.
Upstream-reported end time. NULL for events the upstream feed never assigned an explicit end (the common case — most 511 feeds simply drop resolved incidents rather than emitting a final timestamp).
When this event's content last changed in our data — not when we last polled it. Re-observing an unchanged event does not move it, so a long-running roadworks entry can legitimately carry a last_updated that is months old while still being live and confirmed on every poll. Use it to answer "what changed since I last synced", and do not read it as a freshness or liveness signal.
The comparison covers the fields we publish (type, sub_type, cause, status, severity, title, description, location, affected_roads, direction, lanes_affected, end_time, the estimated_* times and road_class); it is byte-level, so a re-worded description counts as a change.
/events and /events/geojson sort by severity first and last_updated descending second (see the endpoint descriptions).
Feature.last_updated means the same thing as of 2026-07-23; it used to be poll time.
GeoJSON geometry (Point, LineString, or Polygon) describing where the event applies.
Raw upstream attributes preserved as opaque JSON. Shape varies by source.
Jurisdiction code
Upstream-reported creation timestamp, when available.
Upstream-reported last-modified timestamp, when available.
Optional additive second-level classification under type (e.g. type=incident, sub_type=accident). Omitted when the event could not be classified. Never replaces type — existing type filters are unaffected.