In Part 2 of this series, Dan gave examples of finding the “Locations of Things” using the Unified API. This week, I’ll focus on the “Routes of Things” – the lines, routes and services that join up the locations on the TfL network.
As before, all of the API examples in this page are live, however they do not include API authentication tokens. This means that if you follow the link as is, you will be using anonymous access, which is throttled for fair use, so you may get a 403 response. It is recommended for your own development you obtain an “app_key” and “app_id” by registering here. The data in these examples will be in JSON format, so installing a JSON formatter plugin in your browser will help you read the data returned.
Let’s begin with the most prominent use of routes on the website – the status board. In the Unified API a line is the top-level entity which groups the routes of a service together. The Line endpoint allows us to request all of the lines for a given set of modes, so is a useful starting point for navigating into the available routes. Showing the status of a line is such a common use case that the endpoint also includes an option to include the service status for each line by appending /Status to the URL:
The API response tells us a number of useful things for our chosen modes (the full list of modes is available from https://api.tfl.gov.uk/Line/Meta/Modes):
- The id of each line in the API, this is important for requesting route information;
- The status of each line as a severity ordinal, along with a human-readable description;
- The mode of each line (the homepage requests additional modes such as river and bus from the API, and groups the lines by mode for clarity).
Now that we have some line ids, we can look at one of those lines in more detail to see the available routes. I’ve deliberately chosen a complicated line with lots of routes – the London Overground line.
To get this information from the API we use the line id from the earlier API call, requesting the outbound services on the regular and (proposed) night timetables:
The structure of the API query string highlights a few key things to understand about routes: that they are the result of joining together a sequence of stops, using a service timetable in a particular direction (inbound or outbound). The resulting route, while running on physical infrastructure, can (and does) change dynamically in the API based on the timetable and the direction. For example, for most services one cannot simply reverse the route when changing direction – this is especially true of bus routes (think one-way streets) or complex tube lines (the District Line through Earl’s Court).
The API result gives us:
- A list of the StopPoints on the Line (i.e. across all routes), with their ids, and information about other lines and modes that route through them;
- A LineString, which is a list of lat/long co-ordinates connecting all the stops (for tube and rail services, this is straight lines StopPoint-to-StopPoint, for bus services this is a higher resolution line that follows the road);
- A collection of RouteSequences for the line where for each RouteSequence:
- The name of the RouteSequence is provided;
- The RouteSequence is sorted in the order that the service visits the StopPoints;
- The StopPoints are referenced by their id in the aforementioned StopPoint collection.
This information is used to build the page above – showing the full A-Z StopPoint list initially, and then allowing the user to select a RouteSequence by name from the drop-down. If the user switches direction, a new API call will be made to request the inbound services, which may follow different routes.
In a RouteSequence we resolve the timetabled route to the most relevant StopPoint in the NaPTAN hierarchy (which Dan explained last week). The timetabled route actually runs through platform-level StopPoints, but this would cause additional difficulties for developers in the most common use-case – showing the interchanges and facilities available along a route. By resolving to the station-level StopPoint, we are able to easily show, using the example above, that Highbury & Islington has additional Tube (Victoria line) and National Rail modes available, without having to make additional API calls to /StopPoint.
For bus routes, the platform-level StopPoint is used, as this is actually the place where bus interchanges take place, unless the bus stop is part of a station hierarchy (e.g. at Old Street Station, below). Either way, for each mode and heirarchy, the API takes care of this resolution to make life easier for developers. Routing through bus stops is clearly illustrated if we look at the LineString for a bus route:
What’s the frequency Kenneth?
Remember that Routes are built from the services that run on a timetable through the network of StopPoints? We can also request those timetables from the API.
Let’s look at the Northern Line through Camden Town Underground Station, and the timetable from there to Old Street. Since there are multiple routes out of Camden Town (representing the different branches of the Northern line) we make the user choose their destination station. We do this by requesting the valid destinations from Camden Town from the API, and presenting them in the right-hand drop-down on this page:
The API call https://api.tfl.gov.uk/StopPoint/940GZZLUCTN/CanReachOnLine/northern to returns the valid destination stations. Once the user has chosen one (Old Street in this case) we can request the timetable from the API using the two StopPoint ids https://api.tfl.gov.uk/Line/northern/Timetable/940GZZLUCTN/to/940GZZLUODS. The response tells us:
- A list of all of the Stations involved in the timetable for the route (i.e. the station-level StopPoints in the NaPTAN hierarchy);
- A list of all of the StopPoints involved in the timetable for the route (i.e. the platform-level StopPoints in the NaPTAN hierarchy);
- A detailed list of the schedules, giving the arrival time at platform for the service;
- A breakdown of the day into service periods – highlighting the period where the service is frequent (e.g. 6 am to midnight, every 2-5 mins).
Currently we display the exact service times grouped by hourly period for tube trains, but there is a lot of flexibility in the API response for application designers to display them differently. For example, when displaying a bus timetable, we use the periods of high frequency from the API instead of the exact times:
Walk the Line
The Routes API relies heavily on StopPoint ids and Line ids. Routes are the links between the StopPoints – determined by the service timetables – that group together to form a Line. As such, to uniquely identify a route, you will often need at least a Line id, StopPoint id and direction, or two StopPoint ids and a Line id so the direction can be determined by the API. Dan covered numerous ways to discover StopPoints in the API, so how about finding Lines?
- Line search e.g. https://api.tfl.gov.uk/Line/Search/victoria gets all of the lines named similarly to “victoria”;
- Lines by modes e.g. https://api.tfl.gov.uk/Line/Mode/tram gets all of the Tram lines;
- StopPoint details e.g. https://api.tfl.gov.uk/StopPoint/940GZZLUODS returns Old Street station, and all of the lines and transport modes serving the station;
- Routes from the StopPoint directly e.g. https://api.tfl.gov.uk/StopPoint/940GZZLUODS/Route returns all of the RouteSections that pass through Old Street station, including the route name, line id, mode and LineString for each. This is useful for drawing “spider maps” at a given station.
As always, please let the TfL Digital team know what you think of the API in the comments below, or send us a message through the API portal. We’d love to hear how you’re using it in your projects and what improvements we can make.