Stop Structure (station and stop topology) API

The Stop Structure API provides data about the topology of a station, stop, pier or other stop point. In other words, it includes data about entrances, concourses, ticket halls and platforms, as well as possible interchanges between these areas.

The API is documented below. If you have any questions, please reply and let us know.

Endpoint

The request endpoint is:
https://api.tfl.gov.uk/jp_public/api10/XML_STOPSTRUCTURE_REQUEST?

Parameters must be appended to this URL as described below:

Query string parameters

app_key (required)

Your subscription key, which can be found on your user profile.

sSStopNr (required)

The ID of the station you would like to retrieve the internal structure of. This can be in one of the following formats:

  • ATCO Code: equivalent to a StopPoint object’s naptanId property. Example: 940GZZLUSJP.
  • EFA ID: equivalent to a StopPoint object’s icsCode property. Example: 1000221.

sSFF

By default, assigned stops are not taken into account. With this parameter it is possible to specify the ID of a stop to which the footpaths are output.

sSESM

Exact stop match.

Possible values:

  • 0 (default): Include surrounding stops and interchanges to those stops.
  • 1: Do not include surrounding stops or interchanges to those stops.

sSFEA

Filter empty areas.

Possible values:

  • 0 (default): Return all areas.
  • 1: Do not return empty areas.

sSInclSL

Include serving lines.

Possible values:

  • 0 (default): Do not return data about serving lines.
  • 1: Include data about the lines that serve each area.

sSInclSP

Include stop points.

Possible values:

  • 0 (default): Do not return stop point data.
  • 1: Include data about individual platforms and bus stops.

sSOnlyDF

Only direct footpath.

Possible values:

  • 0: Include footpaths between areas that require travelling through other areas.
  • 1 (default): Only include footpaths that directly connect two areas.

onlyDefaultFootpaths

Only unrestricted footpaths.

Possible values:

  • 0 (default): Return all interchanges.
  • 1: Do not return interchanges intended for customers with step-free requirements, such as lifts.

coordOutputFormat

The coordinate system used in the output.

Possible values:

  • MDV (default): a proprietary coordinate system.
  • WGS84[DD.DDDDD] (recommended): WGS 84, a standard coordinate system compatible with most geographic information systems.

Example requests

Minimum recommended request

Finding the stop structure of St James’s Park Tube station:
https://api.tfl.gov.uk/jp_public/api10/XML_STOPSTRUCTURE_REQUEST?sSStopNr=940GZZLUSJP&coordOutputFormat=WGS84[dd.ddddd]&app_key=YOUR_API_KEY

A more complex request

Finding the stop structure of Victoria Tube station with additional data and customised filtering:
https://api.tfl.gov.uk/jp_public/api10/XML_STOPSTRUCTURE_REQUEST?sSStopNr=1000248&sSESM=1&sSFEA=1&sSInclSL=1&sSInclSP=1&sSOnlyDF=0&onlyDefaultFootpaths=1&coordOutputFormat=WGS84[dd.ddddd]&app_key=YOUR_API_KEY

Response elements

stopArea

An area within a stop/station. Contains an itdPoint.

Attributes:

  • level: The level that the area is on. Negative levels are below ground, positive levels are above ground.
  • areaType: The type of area. See below.
  • stopName: The name of the stop.
  • areaName: A short, textual identifier for the area.

itdPoint

A point within a stopArea.

Attributes:

  • stopID: The EFA ID for the stop the area is in.
  • area: The area’s ID within the stop. This is only unique to a specific stopID.
  • gid: The stop’s ATCO Code.
  • x and y: The geographic coordinates of the stop.

footpathInfo

Information about an interchange between two child itdPoints.

Attributes:

  • duration: The number of minutes the interchange takes.
  • distance: The distance of the interchange in metres. Has a value of 0 if unavailable.

footpathPartInfo

Information about part of a footpathInfo.

Attributes:

  • type: The means of interchange. Possible values: LEVEL (walkway), STAIRS, ESCALATOR, ELEVATOR, RAMP.

areaType flags

The stopArea element’s areaType attribute is the decimal sum of the values of a combination of bitwise flags, detailed below:

Flag Decimal value Description
PUBLICTRANSPORT 1
PARKANDRIDE 2
BIKEAREA 4
TAXI 8
LINESCARRYING_BIKES 16 Served by public transport lines that allow bikes
CONNECTABLE_GIS 32 Stop area can be connected to GIS network
LOCALTRAINS 64 Transition to local trains
LONGTRAINS 128 Transition to long distance services
PLANES 256 Transition to air traffic
META1 512 Transition point for distributed journey planning, method 1
SOS 1024 Emergency call available
STAFFED 2048 Staff available at this area
MEZZANINE 4096
META2 8192 Transition point for distributed journey planning, method 2
META3 16384 Transition point for distributed journey planning, method 3

For example, a value of 96 = 64 + 32, meaning both the CONNECTABLE_GIS and LOCALTRAINS flags apply.

1 Like

This is an amazing dataset! Is there a clear way to know whether a stopPoint is a platform? I’d love to be able to cycle through and find the interchange times from the entrance halls to platform, and between platforms - which I think is possible looking by eye, but it seems very inconsistent the area names. For example for Brixton the platforms seem to be Vict1 and Vict2, but then other Victoria line stations are VicSB and VicNB.

@andyb - I suppose terminal stations are inherently different. Both platforms at Brixton are NB, while at Pimlico (say) NB vs SB makes more sense (are the platforms even numbered there? I genuinely can’t remember, so if they are, nobody takes any notice of them). What do they show at stations like Arnos Grove (where the middle platform can swing both ways, so as to speak) or interchange stations like Green Park?

Yes, completely agreed on terminal stations being different.

This is the excerpt for Green Park, from scanning through you can see a variety, “JubWB”, “JubEB”, “Picca”, “VicNB”.

I have no idea what some of the other area names relate to, and if there’s a way to find this info :smiley:

I guess the only way is to find a pretty exhaustive list of areaNames that signify a stopPoint being a platform and match those.

<stopStructure>
<stopAreaLinesSeq>
<stopAreaLines>
<stopArea level="0" duration="0" areaType="33" stopName="Green Park Station" areaName="">
<itdPoint stopID="1000093" area="0" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14299" y="51.50685" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>
<stopAreaLines>
<stopArea level="0" duration="0" areaType="97" stopName="Berkeley Street" areaName="HoB">
<itdPoint stopID="1003924" area="0" platform="" gid="490G000412" pointGid="" x="-0.14301" y="51.50815" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>
<stopAreaLines>
<stopArea level="-5" duration="2" areaType="81" stopName="Green Park Station" areaName="Picca">
<itdPoint stopID="1000093" area="1" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14193" y="51.50712" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>
<stopAreaLines>
<stopArea level="-4" duration="0" areaType="4096" stopName="Green Park Station" areaName="LoCon">
<itdPoint stopID="1000093" area="2" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14180" y="51.50677" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>
<stopAreaLines>
<stopArea level="-5" duration="2" areaType="81" stopName="Green Park Station" areaName="JubWB">
<itdPoint stopID="1000093" area="3" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14169" y="51.50618" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>
<stopAreaLines>
<stopArea level="0" duration="0" areaType="32" stopName="Green Park Station" areaName="D-P-S">
<itdPoint stopID="1000093" area="4" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14314" y="51.50647" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>
<stopAreaLines>
<stopArea level="-1" duration="0" areaType="4096" stopName="Green Park Station" areaName="BookH">
<itdPoint stopID="1000093" area="5" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14274" y="51.50673" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>
<stopAreaLines>
<stopArea level="-2" duration="0" areaType="4096" stopName="Green Park Station" areaName="MiCon">
<itdPoint stopID="1000093" area="6" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14204" y="51.50626" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>
<stopAreaLines>
<stopArea level="-3" duration="2" areaType="65" stopName="Green Park Station" areaName="VicSB">
<itdPoint stopID="1000093" area="7" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14226" y="51.50650" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>
<stopAreaLines>
<stopArea level="0" duration="0" areaType="32" stopName="Green Park Station" areaName="B-P-S">
<itdPoint stopID="1000093" area="8" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14274" y="51.50673" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>
<stopAreaLines>
<stopArea level="-5" duration="2" areaType="81" stopName="Green Park Station" areaName="JubEB">
<itdPoint stopID="1000093" area="9" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14158" y="51.50616" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>
<stopAreaLines>
<stopArea level="0" duration="0" areaType="32" stopName="Green Park Station" areaName="A-P-N">
<itdPoint stopID="1000093" area="10" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14283" y="51.50684" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>
<stopAreaLines>
<stopArea level="0" duration="0" areaType="32" stopName="Green Park Station" areaName="E-STR">
<itdPoint stopID="1000093" area="11" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14298" y="51.50685" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>
<stopAreaLines>
<stopArea level="0" duration="0" areaType="32" stopName="Green Park Station" areaName="C-GRE">
<itdPoint stopID="1000093" area="12" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14291" y="51.50652" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>
<stopAreaLines>
<stopArea level="-3" duration="2" areaType="65" stopName="Green Park Station" areaName="VicNB">
<itdPoint stopID="1000093" area="13" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14226" y="51.50654" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>
<stopAreaLines>
<stopArea level="0" duration="3" areaType="97" stopName="Green Park Station" areaName="Bus">
<itdPoint stopID="1000093" area="14" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14289" y="51.50684" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>
<stopAreaLines>
<stopArea level="0" duration="0" areaType="4096" stopName="Green Park Station" areaName="MET">
<itdPoint stopID="1000093" area="16" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14279" y="51.50695" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>
<stopAreaLines>
<stopArea level="-2" duration="0" areaType="4096" stopName="Green Park Station" areaName="VIP">
<itdPoint stopID="1000093" area="17" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14258" y="51.50634" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>
<stopAreaLines>
<stopArea level="-3" duration="0" areaType="4096" stopName="Green Park Station" areaName="VIC">
<itdPoint stopID="1000093" area="18" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14226" y="51.50654" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>
<stopAreaLines>
<stopArea level="-5" duration="0" areaType="4096" stopName="Green Park Station" areaName="JUB">
<itdPoint stopID="1000093" area="19" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14169" y="51.50618" mapName="TFLV"/>
</stopArea>
<itdServingLines/>
</stopAreaLines>

Hi, @andyb, and welcome to the forum!

My recommendation would be to use the sSInclSL=1 argument in the request URL. The itdServingLines elements will then be populated with the lines that run through each stopArea. Of course, London Underground lines will only run through the areas where the platforms are located.

Green Park, for example:
https://api.tfl.gov.uk/jp_public/api10/XML_STOPSTRUCTURE_REQUEST?sSStopNr=1000093&coordOutputFormat=WGS84[DD.DDDDD]&sSInclSL=1&app_key=YOUR_KEY_HERE

<stopAreaLines>
  <stopArea level="-5" duration="2" areaType="81" stopName="Green Park Station" areaName="Picca">
    <itdPoint stopID="1000093" area="1" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14193" y="51.50712" mapName="TFLV"/>
  </stopArea>
  <itdServingLines>
    <itdServingLine selected="0" code="1" number="" symbol="PIC" motType="2" productId="1" realtime="0" direction="" valid="y05 current project" compound="0" TTB="0" STT="1" ROP="1" type="unknown" spTr="" destID="" stateless="tfl:01PIC: :H:y05" oK="-1" lineDisplay="line">
      <itdNoTrain/>
      <motDivaParams line="01PIC" project="y05" direction="H" supplement=" " network="tfl"/>
      <itdRouteDescText>Heathrow Airport/Uxbridge - Hammersmith - Cockfosters</itdRouteDescText>
      <itdOperator>
        <code>LUL</code>
        <name>London Underground</name>
        <publicCode>LUL</publicCode>
      </itdOperator>
    </itdServingLine>
    <itdServingLine selected="0" code="1" number="" symbol="PIC" motType="2" productId="1" realtime="0" direction="" valid="y05 current project" compound="0" TTB="0" STT="1" ROP="1" type="unknown" spTr="" destID="" stateless="tfl:01PIC: :R:y05" oK="-1" lineDisplay="line">
      <itdNoTrain/>
      <motDivaParams line="01PIC" project="y05" direction="R" supplement=" " network="tfl"/>
      <itdRouteDescText>Cockfosters - Hammersmith - Heathrow Airport/Uxbridge</itdRouteDescText>
      <itdOperator>
        <code>LUL</code>
        <name>London Underground</name>
        <publicCode>LUL</publicCode>
      </itdOperator>
    </itdServingLine>
  </itdServingLines>
</stopAreaLines>

Since it’s area="1" where the Piccadilly line runs though, that is the area containing the Piccadilly line platforms.

Note that there are stopAreas representing bus stops, and so the itdServingLines may include bus routes. You could use the itdServingLine’s motType attribute to identify the mode of transport for each line (a table of motTypes can be found in Section 4.1.1 of the Journey Planner documentation).

I hope this helps. Please let me know if you would like any further information.

2 Likes

Hey Leon,

Thanks for the welcome!

I’ve managed to use the above to find all the platforms using motType=“2”, which works great.

I had a couple further questions - (and please direct me to a set of documentation if it exists instead of me asking lots of questions where the answer is already written down!)

Is there a way to know which itdPoints are “entrances” - I’d like to work out the maximum time to a platform from any entrance (or just the mean time from all the entrances)?

What does the duration of the high level stopArea signify - duration from where? (For example:

<stopArea level="-5" duration="2" areaType="81" stopName="Green Park Station" areaName="Picca">
    <itdPoint stopID="1000093" area="1" platform="" gid="940GZZLUGPK" pointGid="" x="-0.14193" y="51.50712" mapName="TFLV"/>
  </stopArea>

)

Are the durations quite conservative? They seem to be a fair bit higher than this resource: LU LO DLR interchange values.xls

I’m basically trying to create a version of the above .xls that I can create programatically.

Hi, I think finding the entrances is less straightforward. You could potentially use the CONNECTABLE_GIS flag encoded within the areaType, which indicates an area that is accessible from the street. Using Green Park as an example, again:

area areaName areaType CONNECTABLE_GIS (areaType & 32)
0 33 TRUE
1 Picca 81 FALSE
2 LoCon 4096 FALSE
3 JubWB 81 FALSE
4 D-P-S 32 TRUE
5 BookH 4096 FALSE
6 MiCon 4096 FALSE
7 VicSB 65 FALSE
8 B-P-S 32 TRUE
9 JubEB 81 FALSE
10 A-P-N 32 TRUE
11 E-STR 32 TRUE
12 C-GRE 32 TRUE
13 VicNB 65 FALSE
14 Bus 97 TRUE
16 MET 4096 FALSE
17 VIP 4096 FALSE
18 VIC 4096 FALSE
19 JUB 4096 FALSE

You may wish to exclude areas without names or areas with serving lines (which would exclude bus stops such as Area 14 above).

I’ll check with our supplier of this API if there’s an easier way to find the entrances, as well as what the duration attribute on the stopArea represents.

To add to my previous message:

After speaking with our supplier, it’s really as I described in my post above. The area="0" is essentially a dummy area, so should be excluded.

This is the duration from a point within the area to a point within the same area. If you pass in the argument sSInclSP=1, then the <stopPoints> element will be populated with the points in each area (which I suppose is another way to find the platforms).

It’s not an exact science as such, but yes, the values do generally err on the side of advertising too long a time rather than too little a time.

Hi Leon,

Thanks for this - really helpful and I think all the info I need!

I’ve been running into some issues accessing this endpoint. I don’t want to trigger any rate limit issues, but not sure if my app_key has been associated with a bot?

You’re welcome.

Could you please describe in more detail what issues you’re experiencing? For instance, do you receive any error messages?