Skip to content

Public transport

The public transport dataset contains the stations, lines and operators in each country, and how many services run in a typical weekday morning. It is built from the same timetable data as the TravelTime API. This page explains what a station, a line and a frequency are, and which endpoint returns each one.

Source

The public transport dataset is TravelTime's own timetable data. The TravelTime API uses the same data to calculate journeys. We do not merge public transport from the three places sources. We do not add manual overrides, and we do not accept station data from users. Frequencies come from the timetable.

Stations and stops

A stop is one boarding point: a bus stop, a platform or a pier. A station is a group of stops that people think of as one place. We group stops into stations by location and by name. Every endpoint on this page returns stations. Stops appear only as the calling points of a line.

A station has one transport mode. A large interchange appears once per mode. GET /v1/pt/stations/near returns the stations within radius_m of a coordinate, nearest first.

bash

curl -H "Authorization: Bearer $POI_API_KEY" \
  "$POI_BASE/v1/pt/stations/near?country=GB&lat=51.5033&lng=-0.1145&radius_m=800&limit=3"

The results list Waterloo's Underground station and its bus stops as separate stations. Each station carries distinct_lines, the number of lines that call there, and unique_trips, the number of trips that call there in a week: for each line and each timetable band (below), the busiest variant that calls there in that band, times the band's hours, summed over the lines. Weekday bands count as if the line ran every weekday. Like the bands, it counts one direction per line. Trips leaving their first stop between 23:00 and 07:00 on a weekday are not counted, and a line with no timetable data adds 0.

GET /v1/pt/stations/{sid} returns one station with the lines that call there, each with its frequency, and up to 5 nearby stations within 500 m. Its departures_per_hour is the sum of the lines' weekday-morning trips_per_hour.

GET /v1/h3/transport/stations gives each top-level station in an area, up to per_cell_limit per cell, the same departures_per_hour, along with departures_per_hour_by_band (the same sum for each of the five bands, null where no line runs).

Lines, trips and frequency

A line is a named timetabled service, such as the Piccadilly line or a numbered bus route. A line has one operator and one mode. A trip is one timetabled journey along a line. A trip variant is one routing pattern of a line, and variants_total counts them.

On National Rail, a line is one operator's service between two end stations, such as Leeds ↔ York by Northern, with both directions counted as one line. The timetable has no route grouping above that. So a large station is served by many lines that each run less than hourly: Leeds has more than a hundred. To compare how well stations are served, use departures_per_hour rather than distinct_lines.

Each line carries a frequency object with five timetable bands: am_peak, interpeak, pm_peak, evening and weekend. Each band gives trips_per_hour and headway_min, the mean minutes between departures. The weekday bands use the timetable's clock time on a weekday the line runs: am_peak 07:00–09:30, interpeak 09:30–16:00, pm_peak 16:00–19:00 and evening 19:00–23:00. weekend is averaged over all 48 hours of Saturday and Sunday. A trip counts in the band in which it leaves its first stop. Each band is the rate of the line's busiest single trip variant, so it covers one direction and does not add branches together. For a rail line shown as A ↔ B, it is one of the two directions. A band is null when the line has no service in it. We recommend am_peak when you need one figure per line.

GET /v1/pt/lines/{sid} returns one line with its frequency and its ordered list of stops.

bash

LINE=08fef4cf6d58
curl -H "Authorization: Bearer $POI_API_KEY" \
  "$POI_BASE/v1/pt/lines/$LINE?country=GB"

This returns the Piccadilly line. Its am_peak band is 6 trips per hour, a headway of 10 minutes. Each stop carries interchange_count, the number of other lines that call at that station.

GET /v1/pt/lines filters lines by agency, by mode or by a name fragment in q. serves_stations takes a comma-separated list of station ids and returns the lines that call at all of them.

bash

curl -H "Authorization: Bearer $POI_API_KEY" \
  "$POI_BASE/v1/pt/lines?country=GB&serves_stations=5b5e4c13d99c,9dc4ad8d33d0"

This returns one line, the Piccadilly, because it is the only line that calls at both Cockfosters and Oakwood.

Operators and modes

Every line carries an agency, the operator that runs it, and a mode. GET /v1/pt/agencies lists the operators in a country with the number of lines each one runs. Operators appear as the timetable names them, so one large operator can appear under several names.

GET /v1/pt/modes lists the modes in a country with a station count and a line count. The list differs by country, so read it from the API. For Great Britain it returns eight modes.

bash

curl -H "Authorization: Bearer $POI_API_KEY" "$POI_BASE/v1/pt/modes?country=GB"

json

[
  {
    "mode": "Bus",
    "station_count": 321216,
    "line_count": 14481
  },
  {
    "mode": "CableCar",
    "station_count": 2,
    "line_count": 1
  },
  {
    "mode": "Coach",
    "station_count": 939,
    "line_count": 219
  },
  {
    "mode": "Ferry",
    "station_count": 229,
    "line_count": 176
  },
  {
    "mode": "RailNational",
    "station_count": 2614,
    "line_count": 3615
  },
  {
    "mode": "RailOverground",
    "station_count": 299,
    "line_count": 93
  },
  {
    "mode": "RailUnderground",
    "station_count": 311,
    "line_count": 14
  },
  {
    "mode": "Train",
    "station_count": 96,
    "line_count": 24
  }
]

Use mode to filter stations and lines, for example GET /v1/pt/stations/near?mode=RailUnderground or GET /v1/pt/lines?mode=Bus. Use agency to filter lines to one operator.

Interchanges

GET /v1/pt/lines/{line_sid}/stops/{station_sid}/interchanges returns every other line that calls at one station on a line. Lines are ordered by mode: rail first, then underground, then bus. You do not need to compute interchanges yourself.

bash

LINE=e132e5519e7e
STATION=6fe5b9187b8e
curl -H "Authorization: Bearer $POI_API_KEY" \
  "$POI_BASE/v1/pt/lines/$LINE/stops/$STATION/interchanges?country=GB"

This returns the lines you can change to from the Bakerloo line at Waterloo: Jubilee, Northern and Waterloo & City.

Endpoints

Every endpoint is a GET and takes an optional country. If you leave country out, the API works it out from the coordinates or ids in the request. Ids are 12-character stable_id values. They stay the same across data updates, so a link to a station or a line keeps working.

EndpointWhat to use it for
GET /v1/pt/metaStation count, line count and data_version, the date of the dataset.
GET /v1/pt/searchMatch stations and lines by name with q. Use it when a user typed something.
GET /v1/pt/highlightsBusiest interchanges, longest lines and largest operators, for an overview screen.
GET /v1/pt/stationsStations inside a bbox, given as south,west,north,east. bbox is required.
GET /v1/pt/stations/nearStations within radius_m of a lat and lng, nearest first.
GET /v1/pt/stations/{sid}One station, with the lines that call there and nearby stations.
GET /v1/pt/linesLines filtered by agency, mode, q or serves_stations.
GET /v1/pt/lines/{sid}One line, with its frequency and ordered stops.
GET /v1/pt/lines/{line_sid}/stops/{station_sid}/interchangesThe other lines at one station on a line.
GET /v1/pt/modesThe modes in a country, with station and line counts.
GET /v1/pt/agenciesThe operators in a country, with line counts.
GET /v1/h3/transport/summaryStation count, line count, mode mix and a hub flag per H3 cell.
GET /v1/h3/transport/stationsThe stations in each H3 cell.
GET /v1/h3/transport/linesThe lines serving each H3 cell.

The three /v1/h3/transport/ endpoints also accept POST with the cell list in a JSON body. This request returns the summary for the H3 cell around Trafalgar Square.

bash

curl -H "Authorization: Bearer $POI_API_KEY" \
  "$POI_BASE/v1/h3/transport/summary?country=GB&cells=89195da49b7ffff"

data_version in GET /v1/pt/meta changes when the dataset updates. See Data updates. Full parameter and response shapes are in the API reference.

Limits

  • Frequencies come from the timetable. There is no live data: no delays, cancellations or crowding.
  • Frequency has the five bands above. There is no per-day or per-hour breakdown.
  • Operators are not merged across the names the timetable uses.
  • Journey times and reachable areas are not in the TravelTime Data API. The TravelTime API calculates them and needs its own key. See Use with the TravelTime API.