Where the Try it consoles send requests. Stored in this browser only. The API
needs no key — why.
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.
Request
Alerts returned
What 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.
# The subset that happens to overlap today — rarely what you wantcurl "$API_BASE/api/alerts?active=true"# What was in force at feed time — almost always what you wantcurl "$API_BASE/api/alerts?active=true&at=2026-04-27T11:22:38Z"# epoch seconds work toocurl "$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 includedcurl "$API_BASE/api/stops/778/arrivals?limit=5"# Only calls at or after feed time — the live-departure-board questioncurl "$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.