Model card
What the forecasts are built from, and — importantly — what they cannot do.
/api/punctuality Read this before using the other three. It returns the model's provenance, its sample counts per mode, its defaults, and an explicit limits array listing what the model is not capable of. Those limits are part of the response rather than buried in documentation because a forecast that outlives its caveats is worse than no forecast.
The model is rebuilt from whatever snapshot is loaded, so builtAt and the observation counts move with the data rather than being baked in.
The headline result, from a held-out check: the p10–p90 interval is well calibrated (78% coverage against a target of 80%), but the median has *no* skill over simply assuming the delay will not change. Use the spread, not the midpoint — the full numbers and why.
Response
A single object under data, with no meta.
curl "$API_BASE/api/punctuality" {
"data": {
"description": "Empirical delay forecasts derived from the current GTFS-realtime snapshot.",
"method": "A TripUpdate carries a delay for every remaining call, so one snapshot yields delay-versus-horizon observations. A forecast anchors the trip's live delay to the empirical distribution of how far delay drifts over N stops, sliced route → mode → global and backed off until a slice has enough samples.",
"limits": [
"Built from a single point-in-time snapshot: it cannot model time of day, day of week or weather.",
"Downstream delays are the operator's own forecasts, not outcomes observed after the fact.",
"The feed reports no trip-level delay, so 'current delay' means the delay at the trip's next call."
],
"modes": [
{
"mode": "bus",
"trips": 791
},
{
"mode": "metro",
"trips": 70
},
{
"mode": "tram",
"trips": 53
},
{
"mode": "ferry",
"trips": 19
}
],
"defaults": {
"delayBasis": "departure",
"toleranceSeconds": 60
},
"observations": {
"departure": {
"trips": 933,
"drifts": 15451
},
"arrival": {
"trips": 933,
"drifts": 15451
}
},
"endpoints": [
{
"method": "GET",
"path": "/api/punctuality/trips/:tripId",
"description": "Forecast every remaining call of a live trip"
},
{
"method": "GET",
"path": "/api/punctuality/predict",
"description": "Forecast from caller-supplied trip detail"
},
{
"method": "GET",
"path": "/api/punctuality/baseline",
"description": "Cross-sectional punctuality of the network"
}
],
"model": {
"feedTimestamp": "2026-04-27T11:22:38.000Z",
"builtAt": "2026-08-07T12:36:57.044Z",
"delayBasis": "departure",
"tripObservations": 933,
"driftObservations": 15451,
"minSamples": 30
}
}
}