Realtime/SL

It's a snapshot, not a live feed

The data is a fixed capture from 27 April 2026. Time-based filters compare against your clock, not the feed's — the single most likely thing to confuse you.

That would be a footnote, except for one thing: the endpoints that filter on time compare against the wall clock of whatever machine is running the API, not against the feed's own timestamp. The API has no way to know you meant “when the feed was made” unless you say so. So the defaults quietly answer a question about today, using data from April.

Where it bites

Alerts and ?active=

isActive is computed by testing an alert's activePeriods against an instant, which defaults to now. Service alerts often run for months, so a meaningful fraction of the capture's alerts still overlap today's date — which makes this failure mode worse than returning nothing, because it returns something plausible.

RequestAlerts returnedWhat you actually asked
/api/alerts 177 Everything in the capture, unfiltered.
/api/alerts?active=true ~40 Only the long-running alerts whose periods happen to still span today. An arbitrary subset, and it shrinks as more of them expire.
/api/alerts?active=true&at=2026-04-27T11:22:38Z 177 What was genuinely in force when the agency generated the feed. This is almost always the question you meant.

at takes epoch seconds or ISO 8601, and it works on list alerts, get alert, stop alerts and get route.

terminal
# The subset that happens to overlap today — rarely what you want
curl "$API_BASE/api/alerts?active=true"

# What was in force at feed time — almost always what you want
curl "$API_BASE/api/alerts?active=true&at=2026-04-27T11:22:38Z"

# epoch seconds work too
curl "$API_BASE/api/alerts?active=true&at=1777288958"

Arrivals and ?after=

Stop arrivals takes the opposite approach, deliberately. It does not filter to “upcoming” by default, because on an archived capture that would return an empty list every time — which looks like a broken stop rather than a stale feed. So you get every call the feed knew about, past and future, earliest first.

When you do want a window, after takes the same epoch-or-ISO format. Calls carrying no clock time at all are kept regardless: they cannot be proven to fall outside the window, and silently dropping them would be a guess.

terminal
# Everything the feed knew about this station, past calls included
curl "$API_BASE/api/stops/778/arrivals?limit=5"

# Only calls at or after feed time — the live-departure-board question
curl "$API_BASE/api/stops/778/arrivals?after=2026-04-27T11:22:38Z&limit=5"

Freshness, and the two timestamps

Every list response carries two different times in meta, and they answer different questions:

  • feedTimestamp — when the agency generated the feed. This is the instant the data describes, and the one to reason about. It is fixed at 2026-04-27T11:22:38Z.
  • loadedAt — when this server process last read the files off disk. It moves every time the API restarts or you call reload, and it tells you nothing about how fresh the data is.

On a live deployment the gap between the two is your staleness measure. Here, loadedAt is recent and feedTimestamp is months old, which is exactly what a stale feed looks like — the API is not hiding it.