Realtime/SL

Stop arrivals

Predicted calls at a stop, earliest first, across all trips.

GET /api/stops/:stopId/arrivals

Inverts the trip-updates view: instead of one trip's many stops, this is one stop's many trips. Each call is flattened, carrying its trip, route, headsign and vehicle alongside the prediction.

Accepts a station id or a platform id. Given a station, it automatically covers the child platforms and reports every id it searched in includedStopIds.

Past calls are included by default. Filtering to "upcoming" against the wall clock would return nothing on an archived capture, so the choice is yours to make: pass after to window it.

hasPredictedTime is false when the feed gave a delay but no clock time. Those calls sort last rather than being placed at a computed time — see Nothing is synthesised.

Try it

Runs from your browser against the API in .

Path

Query

GET
curl equivalent
 

Parameters

Path

ParameterTypeDefaultDescription
stopIdrequiredpathstring

Station id or platform id.

Query

ParameterTypeDefaultDescription
aftertimestamp

Keeps calls at or after this instant, as epoch seconds or ISO 8601. Calls with no clock time are kept regardless — they cannot be proven to fall outside the window.

limitinteger50

Page size, 1–1000. Values outside that range are a 400 rather than a silent clamp.

offsetinteger0

Rows to skip. Compare against meta.total to know when you have them all.

Response

The list envelope plus three extra top-level keys: stopId as you passed it, stop with its static detail, and includedStopIds — present only when the id expanded to more than itself.

GET /api/stops/778/arrivals?limit=2
curl "$API_BASE/api/stops/778/arrivals?limit=2"
200 · application/json
{
  "data": [
    {
      "tripId": "14010000710000247",
      "routeId": "9011001087500000",
      "route": {
        "routeId": "9011001087500000",
        "agencyId": "505000000000000001",
        "shortName": "875",
        "type": 700
      },
      "directionId": 1,
      "startDate": "20260427",
      "stopSequence": 6,
      "stop": {
        "stopId": "9022050000778004",
        "name": "Tyresö centrum",
        "latitude": 59.245505,
        "longitude": 18.230545,
        "locationType": 0,
        "parentStation": "778",
        "platformCode": "G"
      },
      "scheduleRelationship": "SCHEDULED",
      "arrival": {
        "delay": 9,
        "time": {
          "epoch": 1777288329,
          "iso": "2026-04-27T11:12:09.000Z"
        },
        "uncertainty": 0
      },
      "departure": {
        "delay": 100,
        "time": {
          "epoch": 1777288420,
          "iso": "2026-04-27T11:13:40.000Z"
        },
        "uncertainty": 0
      },
      "vehicle": {
        "id": "9031001001501595"
      },
      "hasPredictedTime": true
    },
    {
      "tripId": "14010000703221547",
      "routeId": "9011001080200000",
      "route": {
        "routeId": "9011001080200000",
        "agencyId": "505000000000000001",
        "shortName": "802",
        "type": 700
      },
      "directionId": 0,
      "startDate": "20260427",
      "stopSequence": 1,
      "stop": {
        "stopId": "9022050000778005",
        "name": "Tyresö centrum",
        "latitude": 59.243403,
        "longitude": 18.22798,
        "locationType": 0,
        "parentStation": "778",
        "platformCode": "I"
      },
      "scheduleRelationship": "SCHEDULED",
      "arrival": {
        "delay": 33,
        "time": {
          "epoch": 1777288353,
          "iso": "2026-04-27T11:12:33.000Z"
        },
        "uncertainty": 0
      },
      "departure": {
        "delay": 10,
        "time": {
          "epoch": 1777288390,
          "iso": "2026-04-27T11:13:10.000Z"
        },
        "uncertainty": 0
      },
      "vehicle": {
        "id": "9031001001501702"
      },
      "hasPredictedTime": true
    }
  ],
  "meta": {
    "count": 2,
    "total": 23,
    "limit": 2,
    "offset": 0,
    "feedTimestamp": "2026-04-27T11:22:38.000Z",
    "loadedAt": "2026-08-07T12:01:42.748Z"
  },
  "stopId": "778",
  "stop": {
    "stopId": "778",
    "name": "Tyresö centrum",
    "latitude": 59.244143,
    "longitude": 18.229239,
    "locationType": 1
  },
  "includedStopIds": [
    "778",
    "9022050000778001",
    "9022050000778002",
    "9022050000778003",
    "9022050000778004",
    "9022050000778005",
    "9022050000778006",
    "9022050000778007",
    "9022050000778008",
    "9022050000778009",
    "9022050000778010",
    "9022050000778011"
  ]
}

A station with no arrivals

Station 10316 expands to two platforms — visible in includedStopIds — but no trip update in this capture calls at either. An empty data with a populated includedStopIds means the expansion worked and there is genuinely nothing there.

GET /api/stops/10316/arrivals?limit=2
curl "$API_BASE/api/stops/10316/arrivals?limit=2"
200 · application/json
{
  "data": [],
  "meta": {
    "count": 0,
    "total": 0,
    "limit": 2,
    "offset": 0,
    "feedTimestamp": "2026-04-27T11:22:38.000Z",
    "loadedAt": "2026-08-07T12:01:42.748Z"
  },
  "stopId": "10316",
  "stop": {
    "stopId": "10316",
    "name": "Duvbo torg",
    "latitude": 59.370423,
    "longitude": 17.952471,
    "locationType": 1
  },
  "includedStopIds": [
    "10316",
    "9022050010316001",
    "9022050010316002"
  ]
}

Errors

400
{ "error": "request_failed", … }

`after` parsed as neither epoch seconds nor ISO 8601, or `limit`/`offset` out of range.