Where can I find bus route "towards"


I’m migrating from using legacy APIs to the unified API, and I’m having trouble finding a particular piece of data.

If you look at 466 bus route - Transport for London, you’ll see towards “Addington Village”. This is different from Name and DestinationName in the routeSections (“Purley / Downlands Precinct - Addington Village Interchange” and “Addington Village Interchange” respectively), and I can’t find it anywhere else in the lines or routes.

Can anyone point me at the right place please?


Looking at api.tfl.gov.uk/Line/466/Route/Sequence/inbound, I’m seeing 490003101E as the last stop of branch 2 in stopPointSequences. This has a name of Addington Village Interchange and is stop E there. Its topmost parent is 490G000380 (entry 45 in the stations section), also called Addington Village Interchange and representing the whole cluster of stops at this location. If you look in orderedLineRoutes, you will see that both routes are also shown as terminating at Addington Village Interchange. Like you, I’m not sure where Tfl are getting the Addington Village name, although I suspect it’s probably the name on the destination blind on the physical bus.

Exactly, and that’s what I need. They must be getting it from somewhere, but I can’t see it anywhere

Does this extract from the Datastore XML file help?

		<DestinationDisplay>Addington Village</DestinationDisplay>
				<Description>Single Decker Low Floor+Wheelchair</Description>
					<MondayToFriday />

Hi Michael,

It does, in that I can see the info I need is right there in the Addington Village element.

Ideally, though, I want to be able to get that information from the Unified API, rather than having to go to two sources. After all, that’s probably what “unified” means :slight_smile:

Do you think the website is using this XML file behind the scenes?


Good question but one I’m not really qualified to answer. While I would expect them to be related, they may derive from a common parent rather than one using the other.

Looking at one of the applications that uses the live feed (London Vehicle Finder at https://lvf.io/) I see a third variation “Addington Vill”. Using this application on some of my local routes I have noticed in the past that what appears on LVF matches what appears on the screens at bus stops. For the 184, for example, I see “Barnet” (the bus itself shows “Barnet, Chesterfield Road”). On the other hand I also see “Barnet Spires” on the 326 and “Barnet Church” on the 34 and “Barnet Hospital” on the 263 (thouigh just “Barnet” for the 389. I’m assuming this is because of limitations on the number of characters that can fit on the screens. It does imply though that something other than “Addington Village Interchange” is stored in the live feed but I would not know whether “Addington Village” is there alongside “Addington Vill”.

As an aside, the 184 illustrates the difficulty of naming places/stops in a way that makes sense to all users. Someone in Wood Green might not know where Chesterfield Road (the actual destination) is but would recognise Barnet. Someone waiting in Barnet for a bus to Chesterfield Road would not be helped by a sign showing “Barnet” but then they are probably used to it!

1 Like

Hi @stile,

Yes the Unified API does use that TransXChange XML behind the scenes. The “towards” you are referring to is actually from the Line/Search API rather than being returned from Line/Route as you’d expect. This is a limitation of the API that I wasn’t aware of which I’ll add to our backlog.

The web page in question 466 bus route - Transport for London calls the Route API, but then passes the lineId into Line/Search, and looks for the first match in the right direction. It makes that additional API call solely to retrieve the “towards” string from the vehicleDestinationText property. D’oh.


  "input": "466",
  "searchMatches": [
      "lineId": "466",
      "mode": "bus",
      "lineName": "466",
      "lineRouteSection": [
          "routeId": 2516,
          "direction": "inbound",
          "destination": "Addington Village Interchange",
          "fromStation": "Westway",
          "toStation": "Addington Village Interchange",
          "serviceType": "Regular",
          "vehicleDestinationText": "Addington Village"
          "routeId": 2518,
          "direction": "outbound",
          "destination": "Westway",
          "fromStation": "Addington Village Interchange",
          "toStation": "Westway",
          "serviceType": "Regular",
          "vehicleDestinationText": "Caterham-on-the-Hill"

The VehicleDestinationText is indeed what would be shown on the vehicle blind. In fact, for the 466 in the outbound direction this is “Caterham-on-the-Hill” - quite different from the name of the last stop on the route. So it is a useful piece of information for customers looking to catch the correct bus!

For now you might be able to use the same work around. I’ve raised an item on our backlog to get the VehicleDestinationText returned from the Route API so that two API calls aren’t necessary. SVC-4433

1 Like

Hi Tim,

Ah, mystery solved! I had suspected it would be there somewhere. Thanks very much for the info - I’ll use the same workaround for now.

Kind regards,

is there any update on SVC-4433 please ?

Thank you

Hi @nakkore

I will bring this up in the next sprint prioritisation on Thursday and let you know when we can do this.

Thank you

@jamesevans there any update on SVC-4433 please ?

Thank you


I’ve just myself been going though the data in this file

    const WHEREAMI = "https://tfl.gov.uk/tfl/syndication/feeds/journey-planner-timetables.zip";

The code to extract this looks sort-of like this

    $strZipFilename = $this->getCachedCopyOfMe();
    $zip = new ZipArchive;
    $strTempFolder = sys_get_temp_dir() . "\\JourneyPlannerTimetables";
    echo PHP_EOL . "put temp files in $strTempFolder";
    if (!file_exists($strTempFolder)) {
    if (file_exists($strZipFilename)) {
        foreach (glob($strTempFolder . "/*") as $strItem) {
        if ($zip->open($strZipFilename) === true) {
            echo ' unzip ok';
        } else {
            echo ' unzip failed';
        foreach (glob($strTempFolder . "/*.zip") as $strItem) {
            echo PHP_EOL . ($strItem) . " starts ";
            $zip = new ZipArchive;
            echo " done ";
        foreach (glob($strTempFolder . "/*.xml") as $strItem) {
            $this->insert(basename($strItem), file_get_contents($strItem));

and it does contain all the section information. It’s in XML but you can certainly find all the sections a bus route in there. The format of the XML files is given here - http://naptan.dft.gov.uk/transxchange/schema/2.5/doc/TransXChangeSchemaGuide-2.5-v-59.pdf

Here’s one of the files in an XML viewer. You can see how the sections link up

the data you want I think is in the JourneyPatternSections data section.

More specifically, look for “DestinationDisplay” in VehicleJourneys->VehicleJourney

 foreach ($this->TransXChange as $item1) {
        foreach ($item1->getElementsByTagName("VehicleJourneys") as $VehicleJourneys) {
            foreach ($VehicleJourneys->getElementsByTagName('VehicleJourney') as $VehicleJourney) {
                $DestinationDisplay = SearchDOMDocument::searchByArray($VehicleJourney, ["DestinationDisplay"]);

Thanks @briantist. I’d need a mobile friendly solution to get this simple information and it would be great if it were available directly in the unified api.


With TfL having literally billions in funding shortfall, I wouldn’t lay out much hope of changes tot the unified api. Just write a bit of your own backend code!

I agree, indeed. (Although TfL seems to have fundings for the almost pointless TfL Go app instead of focusing on the API).
As it’s tough times for everyone it means no backend costs for me as well, we’ll survive without it :slight_smile: