Find all TfL stoppoints

I am trying to find a mechanism to retrieve the full list of TfL stoppoints so that I can cache them and avoid the use of API calls. I am testing using the /StopPoint/mode/{mode}, with mode=“tube”. This returns 1700 StopPoints! I understand that the majority of these are platforms, bus stops etc… but the stoppoints are not returned in any useful hierarchy that I can fathom.

Using a bit of a “sledgehammer to crack a walnut” approach, I saved the JSON response from the URI above, and have tried parsing this into an object graph but I can’t find a natural primary key. Even “id” is producing duplicates…

I’ve had a read of https://blog.tfl.gov.uk/2015/10/08/unified-api-part-2-lot-location-of-things/ and a few other blog posts and can’t figure out what I’m getting wrong. I’m sure it’ll be fairly obvious when I know what it is!

In short, if I wanted to start a project by finding a list of all Tube stations (not platforms), how can I successfully whittle down the results of /StopPoint/mode/tube to give me just ~270 results?

Thanks in advance.

Welcome @originalarkus

I have the dataset to hand, so I can spot that the you’re probably looking for locations with a prefix of 940GZZLU however, locations that are tube and rail will start 910G

Abbey Wood    ->    910GABWD
Abbey Wood Crossrail    ->    910GABWD
Acton Central    ->    910GACTNCTL    
Acton Main Line    ->    910GACTONML    
Acton Town    ->    940GZZLUACT    
Albany Park    ->    910GALBNYPK    
Aldgate    ->    940GZZLUALD    
Aldgate East    ->    940GZZLUADE    
Alexandra Palace    ->    910GALEXNDP    
All Saints    ->    940GZZDLALL    
Alperton    ->    940GZZLUALP    
Anerley    ->    910GANERLEY    
Archway    ->    940GZZLUACY    
Arnos Grove    ->    940GZZLUASG    
Arsenal    ->    940GZZLUASL    
Baker Street    ->    940GZZLUBST    
Balham    ->    910GBALHAM    
Bank    ->    940GZZLUBNK    
Banstead    ->    910GBANSTED    
Barbican    ->    940GZZLUBBN    
Barking    ->    910GBARKING    
Barking Underground    ->    910GBARKING    
Barkingside    ->    940GZZLUBKE    
Barnes    ->    910GBARNES    
Barnes Bridge    ->    910GBNSBDGE    
Barons Court    ->    940GZZLUBSC    
Bat & Ball    ->    910GBATABAL    
Battersea Park    ->    910GQTRDBAT    
Bayswater    ->    940GZZLUBWT    
Beckenham Hill    ->    910GBCKNHMH    
Beckenham Junction    ->    910GBCKNHMJ    
Beckton    ->    940GZZDLBEC    
Beckton Park    ->    940GZZDLBPK    
Becontree    ->    940GZZLUBEC    
Bellingham    ->    910GBELNGHM    
Belmont    ->    910GBELM    
Belsize Park    ->    940GZZLUBZP    
Belvedere    ->    910GBELVEDR    
Bermondsey    ->    940GZZLUBMY    
Bethnal Green    ->    910GBTHNLGR    
Bexley    ->    910GBEXLEY    
Bickley    ->    910GBICKLEY    
Birkbeck    ->    910GBIRKBCK    
Blackfriars    ->    910GBLFR    
Blackheath    ->    910GBLKHTH    
Blackhorse Road    ->    910GBLCHSRD    
Blackwall    ->    940GZZDLBLA    
Bond Street    ->    940GZZLUBND    
Borough    ->    940GZZLUBOR    
Boston Manor    ->    940GZZLUBOS    
Bounds Green    ->    910GBOWESPK    
Bow Church    ->    940GZZDLBOW    
Bow Road    ->    940GZZLUBWR    
Bowes Park    ->    910GBOWESPK    
Brent Cross    ->    940GZZLUBTX    
Brentford    ->    910GBNTFORD    
Brimsdown    ->    910GBRIMSDN    
Brixton    ->    910GBRIXTON    
Brockley    ->    910GBROCKLY    
Bromley North    ->    910GBROMLYN    
Bromley South    ->    910GBROMLYS    
Bromley-By-Bow    ->    940GZZLUBBB    
Brondesbury    ->    910GBRBY    
Brondesbury Park    ->    910GBRBYPK    
Bruce Grove    ->    910GBRUCGRV    
Burnt Oak    ->    940GZZLUBTK    
Bush Hill Park    ->    910GBHILLPK    
Caledonian Road    ->    940GZZLUCAR    
Caledonian Road & Barnsbury    ->    910GCLDNNRB    
Cambridge Heath    ->    910GCAMHTH    
Camden Road    ->    910GCMDNRD    
Camden Town    ->    940GZZLUCTN    
Canada Water    ->    910GCNDAW    
Canary Wharf    ->    940GZZLUCYF    
Canary Wharf Crossrail    ->    940GZZLUCYF    
Canning Town    ->    940GZZLUCGT    
Cannon Street    ->    940GZZLUCST    
Canonbury    ->    910GCNNB    
Canons Park    ->    940GZZLUCPK    
Carshalton    ->    910GCRSHLTN    
Carshalton Beeches    ->    910GCRSHLTB    
Castle Bar Park    ->    910GCBARPAR    
Catford    ->    910GCATFBDG    
Catford Bridge    ->    910GCATFORD    
Chadwell Heath    ->    910GCHDWLHT    
Chalk Farm    ->    940GZZLUCFM    
Chancery Lane    ->    940GZZLUCHL    
Charing Cross    ->    910GCHRX    
Charlton    ->    910GCRLN    
Cheam    ->    910GCHEAM    
Chelsfield    ->    910GCHLSFLD    
Chessington North    ->    910GCHSSN    
Chessington South    ->    910GCHSSS    
Chingford    ->    910GCHINGFD    
Chipstead    ->    910GCHSD    
Chislehurst    ->    910GCHSLHRS    
Chiswick    ->    910GCHISWCK    
Chiswick Park    ->    940GZZLUCWP    
City Thameslink    ->    910GCTMSLNK    
Clapham Common    ->    940GZZLUCPC    
Clapham High Street    ->    910GCLPHHS    
Clapham Junction    ->    910GCLPHMJC    
Clapham North    ->    910GCLPHHS    
Clapham South    ->    940GZZLUCPS    
Clapton    ->    910GCLAPTON    
Clock House    ->    910GCLOCKHS    
Cockfosters    ->    940GZZLUCKS    
Colindale    ->    940GZZLUCND    
Colliers Wood    ->    940GZZLUCSD    
Coulsdon South    ->    910GCOLSDNS    
Coulsdon Town    ->    910GCOLSTWN    
Covent Garden    ->    940GZZLUCGN    
Crayford    ->    910GCRFD    
Crews Hill    ->    910GCRHL    
Cricklewood    ->    910GCRKLWD    
Crofton Park    ->    910GCFPK    
Crossharbour    ->    940GZZDLCLA    
Crouch Hill    ->    910GCROUCHH    
Crystal Palace    ->    910GCRYSTLP    
Custom House    ->    940GZZDLCUS    
Custom House CROSSRAIL    ->    940GZZDLCUS    
Cutty Sark    ->    940GZZDLCUT    
Cyprus    ->    940GZZDLCYP    
Dagenham Dock    ->    910GDGNHMDC    
Dagenham East    ->    940GZZLUDGE    
Dagenham Heathway    ->    940GZZLUDGY    
Dalston Junction    ->    910GDALS    
Dalston Kingsland    ->    910GDALS    
Dartford    ->    910GDARTFD    
Denham    ->    910GDENHAM    
Denham Golf Club    ->    910GDENHMGC    
Denmark Hill    ->    910GDENMRKH    
Deptford    ->    910GDEPTFD    
Deptford Bridge    ->    940GZZDLDEP    
Devons Road    ->    940GZZDLDEV    
Dollis Hill    ->    940GZZLUDOH    
Drayton Green    ->    910GDRAYGRN    
Drayton Park    ->    910GDRYP    
Ealing Broadway    ->    910GEALINGB    
Ealing Common    ->    940GZZLUECM    
Earls Court    ->    940GZZLUECT    
Earlsfield    ->    910GERLFLD    
East Acton    ->    940GZZLUEAN    
East Croydon    ->    910GECROYDN    
East Dulwich    ->    910GEDULWCH    
East Finchley    ->    940GZZLUEFY    
East Ham    ->    940GZZLUEHM    
East India    ->    940GZZDLEIN    
East Putney    ->    940GZZLUEPY    
Eastcote    ->    940GZZLUEAE    
Eden Park    ->    910GEDPK    
Edgware    ->    940GZZLUEGW    
Edgware Road (Bakerloo)    ->    940GZZLUERB    
Edgware Road (Circle)    ->    940GZZLUERC    
Edmonton Green    ->    910GEDMNGRN    
Elephant & Castle    ->    910GELPHNAC    
Elephant & Castle (Underground)    ->    910GELPHNAC    
Elm Park    ->    940GZZLUEPK    
Elmers End    ->    910GELMERSE    
Elmstead Woods    ->    910GELMW    
Eltham    ->    910GELTHAM    
Elverson Road    ->    940GZZDLELV    
Embankment    ->    910GCHRX    
Enfield Chase    ->    910GENFC    
Enfield Lock    ->    910GENFLDLK    
Enfield Town    ->    910GENFLDTN    
Erith    ->    910GERITH    
Essex Road    ->    910GESSEXRD    
Euston    ->    910GEUSTON    
Euston Square    ->    940GZZLUESQ    
Fairlop    ->    940GZZLUFLP    
Falconwood    ->    910GFALCNWD    
Farringdon    ->    910GFRNDNLT    
Farringdon Crossrail    ->    940GZZLUFCN    
Feltham    ->    910GFELTHAM    
Fenchurch Street    ->    910GFENCHRS    
Finchley Central    ->    940GZZLUFYC    
Finchley Road    ->    940GZZLUFYR    
Finchley Road & Frognal    ->    910GFNCHLYR    
Finsbury Park    ->    910GFNPK    
Forest Gate    ->    910GFRSTGT    
Forest Hill    ->    910GFORESTH    
Fulham Broadway    ->    940GZZLUFBY    
Fulwell    ->    910GFULWELL    
Gallions Reach    ->    940GZZDLGAL    
Gants Hill    ->    940GZZLUGTH    
Gidea Park    ->    910GGIDEAPK    
Gipsy Hill    ->    910GGIPSYH    
Gloucester Road    ->    940GZZLUGTR    
Golders Green    ->    940GZZLUGGN    
Goldhawk Road    ->    940GZZLUGHK    
Goodge Street    ->    940GZZLUGDG    
Goodmayes    ->    910GGODMAYS    
Gordon Hill    ->    910GGORDONH    
Gospel Oak    ->    910GGOSPLOK    
Grange Park    ->    910GGRPK    
Great Portland Street    ->    940GZZLUGPS    
Green Park    ->    940GZZLUGPK    
Greenford    ->    910GGFORD    
Greenwich    ->    910GGNWH    
Grove Park    ->    910GGRVPK    
Gunnersbury    ->    910GGNRSBRY    
Hackbridge    ->    910GHKBG    
Hackney Central    ->    910GHACKNYC    
Hackney Downs    ->    910GHACKNYC    
Hackney Wick    ->    910GHACKNYW    
Hadley Wood    ->    910GHADLYWD    
Haggerston    ->    910GHAGGERS    
Hainault    ->    940GZZLUHLT    
Hammersmith    ->    940GZZLUHSD    
Hammersmith (District and Piccadilly)    ->    940GZZLUHSC    
Hampstead    ->    940GZZLUHTD    
Hampstead Heath    ->    910GHMPSTDH    
Hampton (London)    ->    910GHAMPTON    
Hampton Wick    ->    910GHAMWICK    
Hanger Lane    ->    940GZZLUHGR    
Hanwell    ->    910GHANWELL    
Harlesden    ->    910GHARLSDN    
Harold Wood    ->    910GHRLDWOD    
Harringay    ->    910GHRGY    
Harringay Green Lanes    ->    910GHRGYGL    
Harrow & Wealdstone    ->    910GHROW    
Harrow-on-the-Hill    ->    910GHAROOTH    
Hatch End    ->    910GHTCHEND    
Haydons Road    ->    910GHYDNSRD    
Hayes & Harlington    ->    910GHAYESAH    
Hayes (Kent)    ->    910GHAYS    
Headstone Lane    ->    910GHEDSTNL    
Heathrow Airport Terminal 5    ->    910GHTRWTM5    
Hendon    ->    910GHDON    
Hendon Central    ->    940GZZLUHCL    
Herne Hill    ->    910GHERNEH    
Heron Quays    ->    940GZZDLHEQ    
High Barnet    ->    940GZZLUHBT    
High Street Kensington    ->    940GZZLUHSK    
Highams Park    ->    910GHGHMSPK    
Highbury & Islington    ->    910GHGHI    
Highgate    ->    940GZZLUHGT    
Hillingdon    ->    940GZZLUHGD    
Hither Green    ->    910GHTHRGRN    
Holborn    ->    940GZZLUHBN    
Holland Park    ->    940GZZLUHPK    
Holloway Road    ->    940GZZLUHWY    
Homerton    ->    910GHOMRTON    
Honor Oak Park    ->    910GHONROPK    
Hornchurch    ->    940GZZLUHCH    
Hornsey    ->    910GHRNSY    
Hounslow    ->    910GHOUNSLW    
Hounslow Central    ->    940GZZLUHWC    
Hounslow East    ->    940GZZLUHWE    
Hounslow West    ->    940GZZLUHWT    
Hoxton    ->    910GHOXTON    
Hyde Park Corner    ->    940GZZLUHPC    
Ickenham    ->    940GZZLUICK    
Ilford    ->    910GILFORD    
Imperial Wharf    ->    910GCSEAH    
Island Gardens    ->    940GZZDLISL    
Isleworth    ->    910GISLEWTH    
Kenley    ->    910GKNLY    
Kennington    ->    940GZZLUKNG    
Kensal Green    ->    910GKENSLG    
Kensal Rise    ->    910GKENR    
Kensington Olympia    ->    910GKENOLYM    
Kent House    ->    910GKENTHOS    
Kentish Town    ->    910GKNTSHTN    
Kentish Town West    ->    910GKNTSHTW    
Kenton    ->    910GKTON    
Kew Bridge    ->    910GKEWBDGE    
Kew Gardens    ->    910GKEWGRDN    
Kidbrooke    ->    910GKIDBROK    
Kilburn    ->    910GBRBY    
Kilburn High Road    ->    910GKLBRNHR    
Kilburn Park    ->    910GKLBRNHR    
Kings Cross    ->    910GKNGX    
Kingsbury    ->    940GZZLUKBY    
Kingston    ->    910GKGSTON    
Knightsbridge    ->    940GZZLUKNB    
Knockholt    ->    910GKNCKHLT    
Ladbroke Grove    ->    940GZZLULAD    
Ladywell    ->    910GLDYW    
Lambeth North    ->    940GZZLULBN    
Lancaster Gate    ->    940GZZLULGT    
Latimer Road    ->    940GZZLULRD    
Lea Bridge    ->    910GLEABDGE    
Lee (London)    ->    910GLEEE    
Leicester Square    ->    940GZZLULSQ    
Lewisham    ->    910GLEWISHM    
Leyton    ->    940GZZLULYN    
Leyton Midland Road    ->    910GLEYTNMR    
Leytonstone    ->    940GZZLULYS    
Leytonstone High Road    ->    910GLYTNSHR    
Limehouse    ->    910GLIMHSE    
Liverpool Street    ->    910GLIVST    
Liverpool Street Crossrail    ->    910GLIVST    
London Bridge    ->    910GLNDNBDC    
London Fields    ->    910GLONFLDS    
Loughborough Junction    ->    910GLBGHJN    
Lower Sydenham    ->    910GLSYDNHM    
Maida Vale    ->    940GZZLUMVL    
Malden Manor    ->    910GMALDENM    
Manor House    ->    940GZZLUMRH    
Manor Park    ->    910GMANRPK    
Mansion House    ->    940GZZLUMSH    
Marble Arch    ->    940GZZLUMBA    
Maryland    ->    910GMRYLAND    
Marylebone    ->    910GMARYLBN    
Maze Hill    ->    910GMAZEH    
Merdian Water    ->    940GZZLUAGL    
Mile End    ->    940GZZLUMED    
Mill Hill Broadway    ->    910GMLHB    
Mill Hill East    ->    940GZZLUMHL    
Mitcham Eastfields    ->    910GESTFLDS    
Mitcham Junction    ->    910GMITCHMJ    
Monument    ->    940GZZLUBNK    
Moor Park    ->    940GZZLUMPK    
Moorgate    ->    910GMRGT    
Morden    ->    940GZZLUMDN    
Morden South    ->    910GMORDENS    
Mornington Crescent    ->    940GZZLUMTC    
Mortlake    ->    910GMRTLKE    
Motspur Park    ->    910GMOTSPRP    
Mottingham    ->    910GMOTNGHM    
Mudchute    ->    940GZZDLMUD    
Neasden    ->    940GZZLUNDN    
New Barnet    ->    910GNBARNET    
New Beckenham    ->    910GNBCKNHM    
New Cross    ->    910GNWCRELL    
New Cross Gate    ->    910GNEWXGEL    
New Eltham    ->    910GNWELTHM    
New Malden    ->    910GNEWMLDN    
New Southgate    ->    910GNEWSGAT    
Newbury Park    ->    910GILFENBP    
Norbiton    ->    910GNRBITON    
Norbury    ->    910GNORBURY    
North Acton    ->    940GZZLUNAN    
North Dulwich    ->    910GNDULWCH    
North Ealing    ->    940GZZLUNEN    
North Greenwich    ->    940GZZLUNGW    
North Harrow    ->    940GZZLUNHA    
North Sheen    ->    910GNSHEEN    
North Wembley    ->    910GNWEMBLY    
Northfields    ->    940GZZLUNFD    
Northolt    ->    940GZZLUNHT    
Northolt Park    ->    910GNTHOLTP    
Northumberland Park    ->    910GNMBRLPK    
Northwick Park    ->    940GZZLUNKP    
Northwood    ->    940GZZLUNOW    
Northwood Hills    ->    940GZZLUNWH    
Norwood Junction    ->    910GNORWDJ    
Notting Hill Gate    ->    940GZZLUNHG    
Nunhead    ->    910GNUNHEAD    
Oakleigh Park    ->    910GOKLGHPK    
Oakwood    ->    940GZZLUOAK    
Old Street    ->    910GOLDST    
Orpington    ->    910GORPNGTN    
Osterley    ->    940GZZLUOSY    
Otford    ->    910GOTFORD    
Oval    ->    940GZZLUOVL    
Oxford Circus    ->    940GZZLUOXC    
Paddington    ->    910GPADTON    
Paddington CROSSRAIL    ->    940GZZLUPAC    
Palmers Green    ->    910GPALMRSG    
Park Royal    ->    940GZZLUPKR    
Parsons Green    ->    940GZZLUPSG    
Peckham Rye    ->    910GPCKHMRY    
Penge East    ->    910GPNGEE    
Penge West    ->    910GPENEW    
Perivale    ->    940GZZLUPVL    
Petts Wood    ->    910GPETSWD    
Piccadilly Circus    ->    940GZZLUPCC    
Pimlico    ->    940GZZLUPCO    
Pinner    ->    940GZZLUPNR    
Plaistow    ->    940GZZLUPLW    
Plumstead    ->    910GPLMS    
Ponders End    ->    910GPNDRSEN    
Poplar    ->    940GZZDLPOP    
Preston Road    ->    940GZZLUPRD    
Prince Regent    ->    940GZZDLPRE    
Pudding Mill Lane    ->    940GZZDLPUD    
Purley    ->    910GPURLEY    
Purley Oaks    ->    910GPURLEYO    
Putney    ->    910GPUTNEY    
Putney Bridge    ->    940GZZLUPYB    
Queens Park    ->    910GQPRK    
Queens Road (Peckham)    ->    910GPCKHMQD    
Queensbury    ->    940GZZLUQBY    
Queenstown Road (Battersea)    ->    910GQTRDBAT    
Queensway    ->    940GZZLUQWY    
Rainham (Essex)    ->    910GRNHAME    
Ravensbourne    ->    910GRBRN    
Ravenscourt Park    ->    940GZZLURVP    
Rayners Lane    ->    940GZZLURYL    
Raynes Park    ->    910GRAYNSPK    
Rectory Road    ->    910GRCTRYRD    
Reedham (Surrey)    ->    910GREEDHMS    
Regents Park    ->    940GZZLURGP    
Richmond    ->    910GRICHMND    
Riddlesdown    ->    910GRDLSDWN    
Romford    ->    910GROMFORD    
Rotherhithe    ->    910GCNDAW    
Royal Albert    ->    940GZZDLRAL    
Royal Oak    ->    940GZZLURYO    
Royal Victoria    ->    940GZZDLRVC    
Ruislip    ->    940GZZLURSP    
Ruislip Gardens    ->    940GZZLURSG    
Ruislip Manor    ->    940GZZLURSM    
Russell Square    ->    940GZZLURSQ    
Sanderstead    ->    910GSDSD    
Selhurst    ->    910GSELHRST    
Seven Kings    ->    910GSVNKNGS    
Seven Sisters    ->    940GZZLUSVS    
Shadwell    ->    910GSHADWEL    
Shepherds Bush    ->    910GSHPDSB    
Shepherds Bush Market    ->    940GZZLUSBM    
Shoreditch High Street    ->    910GSHRDHST    
Shoreham (Kent)    ->    910GSHRMKT    
Shortlands    ->    910GSHRTLND    
Sidcup    ->    910GSIDCUP    
Silver Street    ->    910GSIVRST    
Slade Green    ->    910GSLADEGN    
Sloane Square    ->    940GZZLUSSQ    
Snaresbrook    ->    940GZZLUSNB    
South Acton    ->    910GSACTON    
South Bermondsey    ->    910GSBRMNDS    
South Croydon    ->    910GSCROYDN    
South Ealing    ->    940GZZLUSEA    
South Greenford    ->    910GSGFORD    
South Hampstead    ->    910GSHMPSTD    
South Harrow    ->    940GZZLUSHH    
South Kensington    ->    940GZZLUSKS    
South Kenton    ->    910GSKENTON    
South Merton    ->    910GSMERTON    
South Quay    ->    940GZZDLSOQ    
South Ruislip    ->    910GSRUISLP    
South Tottenham    ->    910GSTOTNHM    
South Wimbledon    ->    940GZZLUSWN    
South Woodford    ->    940GZZLUSWF    
Southall    ->    910GSTHALL    
Southbury    ->    910GSBURY    
Southfields    ->    940GZZLUSFS    
Southgate    ->    940GZZLUSGT    
Southwark    ->    910GWLOE    
St Helier (Surrey)    ->    910GSHLIER    
St James Street    ->    910GSTJMSST    
St Jamess Park    ->    940GZZLUSJP    
St Johns (London)    ->    910GSTJOHNS    
St Johns Wood    ->    940GZZLUSJW    
St Margarets (London)    ->    910GSTMGTS    
St Mary Cray    ->    910GSTMRYC    
St Pancras International    ->    910GSTPADOM    
St Pauls    ->    940GZZLUSPU    
Stamford Brook    ->    940GZZLUSFB    
Stamford Hill    ->    910GSTMFDHL    
Stanmore    ->    940GZZLUSTM    
Stepney Green    ->    940GZZLUSGN    
Stockwell    ->    940GZZLUSKW    
Stoke Newington    ->    910GSTKNWNG    
Stonebridge Park    ->    910GSTNBGPK    
Stratford    ->    910GSTFD    
Stratford International    ->    910GSTFODOM    
Strawberry Hill    ->    910GSTRWBYH    
Streatham (Greater London)    ->    910GSTRETHM    
Streatham Common    ->    910GSTRHCOM    
Streatham Hill    ->    910GSTRHILL    
Sudbury & Harrow Road    ->    910GSDBRYHR    
Sudbury Hill    ->    910GSDBRYHH    
Sudbury Hill Harrow    ->    910GSDBRYHH    
Sudbury Town    ->    940GZZLUSUT    
Sundridge Park    ->    910GSNDP    
Surbiton    ->    910GSURBITN    
Surrey Quays    ->    910GSURREYQ    
Swiss Cottage    ->    940GZZLUSWC    
Sydenham    ->    910GSYDENHM    
Sydenham Hill    ->    910GSYDNHMH    
Syon Lane    ->    910GSYONLA    
Teddington    ->    910GTEDNGTN    
Temple    ->    940GZZLUTMP    
Tooting    ->    910GTOOTING    
Tooting Bec    ->    940GZZLUTBC    
Tooting Broadway    ->    940GZZLUTBY    
Tottenham Court Road    ->    940GZZLUTCR    
Tottenham Hale    ->    910GTTNHMHL    
Totteridge & Whetstone    ->    940GZZLUTAW    
Tower Gateway    ->    940GZZDLTWG    
Tower Hill    ->    910GFENCHRS    
Tufnell Park    ->    940GZZLUTFP    
Tulse Hill    ->    910GTULSEH    
Turkey Street    ->    910GTURKYST    
Turnham Green    ->    940GZZLUTNG    
Turnpike Lane    ->    940GZZLUTPN    
Twickenham    ->    910GTWCKNHM    
Upminster    ->    910GUPMNSTR    
Upminster Bridge    ->    940GZZLUUPB    
Upney    ->    940GZZLUUPY    
Upper Holloway    ->    910GUPRHLWY    
Upton Park    ->    940GZZLUUPK    
Uxbridge    ->    940GZZLUUXB    
Vauxhall    ->    910GVAUXHLM    
Victoria    ->    910GVICTRIC    
Waddon    ->    910GWADDON

(DLR stops start 940GZZDL if you want them too)

Then…

When you look at a location with https://api.tfl.gov.uk/StopPoint/910GHGHI

It says “tube” in the list of modes, right at the top.

Or you can use https://api.tfl.gov.uk/line/mode/tube/status to get a list of lines that are “tube” and look for those in the list of lines->id at a stop point.

The name of the station is the commonName

image

Does this help?

@originalarkus

Conceptually I think it’s quickest to just do this

Get the list of tube line names from https://api.tfl.gov.uk/line/mode/tube/status
Loop though the data returned from https://api.tfl.gov.uk/line/bakerloo/stoppoints using the line names returned from the first call

Then grab the station names from the top-level data

@originalarkus

    $strMode="tube";
    $arrFound = [];
    $tubeStatus = json_decode(file_get_contents("https://api.tfl.gov.uk/line/mode/{$strMode}/status"));
    foreach ($tubeStatus as $item) {
        $tubeStopPoints = json_decode(file_get_contents("https://api.tfl.gov.uk/line/" . $item->id . "/stoppoints"));
        foreach ($tubeStopPoints as $tubeStopPoint) {
            if (in_array($strMode, $tubeStopPoint->modes)) {
                $arrFound[$tubeStopPoint->id] = $tubeStopPoint->commonName;
            }
        }
    }
    echo  PHP_EOL. count($arrFound); 

This prints “270”.

Change to pirint out the array

    asort($arrFound);
    foreach ($arrFound as $key => $item) {
        echo PHP_EOL . "     $key $item";
    }


 940GZZLUACT Acton Town Underground Station
 940GZZLUADE Aldgate East Underground Station
 940GZZLUALD Aldgate Underground Station
 940GZZLUALP Alperton Underground Station
 940GZZLUAMS Amersham Underground Station
 940GZZLUAGL Angel Underground Station
 940GZZLUACY Archway Underground Station
 940GZZLUASG Arnos Grove Underground Station
 940GZZLUASL Arsenal Underground Station
 940GZZLUBST Baker Street Underground Station
 940GZZLUBLM Balham Underground Station
 940GZZLUBNK Bank Underground Station
 940GZZLUBBN Barbican Underground Station
 940GZZLUBKG Barking Underground Station
 940GZZLUBKE Barkingside Underground Station
 940GZZLUBSC Barons Court Underground Station
 940GZZLUBWT Bayswater Underground Station
 940GZZLUBEC Becontree Underground Station
 940GZZLUBZP Belsize Park Underground Station
 940GZZLUBMY Bermondsey Underground Station
 940GZZLUBLG Bethnal Green Underground Station
 940GZZLUBKF Blackfriars Underground Station
 940GZZLUBLR Blackhorse Road Underground Station
 940GZZLUBND Bond Street Underground Station
 940GZZLUBOR Borough Underground Station
 940GZZLUBOS Boston Manor Underground Station
 940GZZLUBDS Bounds Green Underground Station
 940GZZLUBWR Bow Road Underground Station
 940GZZLUBTX Brent Cross Underground Station
 940GZZLUBXN Brixton Underground Station
 940GZZLUBBB Bromley-by-Bow Underground Station
 940GZZLUBKH Buckhurst Hill Underground Station
 940GZZLUBTK Burnt Oak Underground Station
 940GZZLUCAR Caledonian Road Underground Station
 940GZZLUCTN Camden Town Underground Station
 940GZZLUCWR Canada Water Underground Station
 940GZZLUCYF Canary Wharf Underground Station
 940GZZLUCGT Canning Town Underground Station
 940GZZLUCST Cannon Street Underground Station
 940GZZLUCPK Canons Park Underground Station
 940GZZLUCAL Chalfont & Latimer Underground Station
 940GZZLUCFM Chalk Farm Underground Station
 940GZZLUCHL Chancery Lane Underground Station
 940GZZLUCHX Charing Cross Underground Station
 940GZZLUCSM Chesham Underground Station
 940GZZLUCWL Chigwell Underground Station
 940GZZLUCWP Chiswick Park Underground Station
 940GZZLUCYD Chorleywood Underground Station
 940GZZLUCPC Clapham Common Underground Station
 940GZZLUCPN Clapham North Underground Station
 940GZZLUCPS Clapham South Underground Station
 940GZZLUCKS Cockfosters Underground Station
 940GZZLUCND Colindale Underground Station
 940GZZLUCSD Colliers Wood Underground Station
 940GZZLUCGN Covent Garden Underground Station
 940GZZLUCXY Croxley Underground Station
 940GZZLUDGE Dagenham East Underground Station
 940GZZLUDGY Dagenham Heathway Underground Station
 940GZZLUDBN Debden Underground Station
 940GZZLUDOH Dollis Hill Underground Station
 940GZZLUEBY Ealing Broadway Underground Station
 940GZZLUECM Ealing Common Underground Station
 940GZZLUECT Earl's Court Underground Station
 940GZZLUEAN East Acton Underground Station
 940GZZLUEFY East Finchley Underground Station
 940GZZLUEHM East Ham Underground Station
 940GZZLUEPY East Putney Underground Station
 940GZZLUEAE Eastcote Underground Station
 940GZZLUERB Edgware Road (Bakerloo) Underground Station
 940GZZLUERC Edgware Road (Circle Line) Underground Station
 940GZZLUEGW Edgware Underground Station
 940GZZLUEAC Elephant & Castle Underground Station
 940GZZLUEPK Elm Park Underground Station
 940GZZLUEMB Embankment Underground Station
 940GZZLUEPG Epping Underground Station
 940GZZLUESQ Euston Square Underground Station
 940GZZLUEUS Euston Underground Station
 940GZZLUFLP Fairlop Underground Station
 940GZZLUFCN Farringdon Underground Station
 940GZZLUFYC Finchley Central Underground Station
 940GZZLUFYR Finchley Road Underground Station
 940GZZLUFPK Finsbury Park Underground Station
 940GZZLUFBY Fulham Broadway Underground Station
 940GZZLUGTH Gants Hill Underground Station
 940GZZLUGTR Gloucester Road Underground Station
 940GZZLUGGN Golders Green Underground Station
 940GZZLUGHK Goldhawk Road Underground Station
 940GZZLUGDG Goodge Street Underground Station
 940GZZLUGGH Grange Hill Underground Station
 940GZZLUGPS Great Portland Street Underground Station
 940GZZLUGPK Green Park Underground Station
 940GZZLUGFD Greenford Underground Station
 940GZZLUGBY Gunnersbury Underground Station
 940GZZLUHLT Hainault Underground Station
 940GZZLUHSD Hammersmith (Dist&Picc Line) Underground Station
 940GZZLUHSC Hammersmith (H&C Line) Underground Station
 940GZZLUHTD Hampstead Underground Station
 940GZZLUHGR Hanger Lane Underground Station
 940GZZLUHSN Harlesden Underground Station
 940GZZLUHAW Harrow & Wealdstone Underground Station
 940GZZLUHOH Harrow-on-the-Hill Underground Station
 940GZZLUHNX Hatton Cross Underground Station
 940GZZLUHR4 Heathrow Terminal 4 Underground Station
 940GZZLUHR5 Heathrow Terminal 5 Underground Station
 940GZZLUHRC Heathrow Terminals 2 & 3 Underground Station
 940GZZLUHCL Hendon Central Underground Station
 940GZZLUHBT High Barnet Underground Station
 940GZZLUHSK High Street Kensington Underground Station
 940GZZLUHAI Highbury & Islington Underground Station
 940GZZLUHGT Highgate Underground Station
 940GZZLUHGD Hillingdon Underground Station
 940GZZLUHBN Holborn Underground Station
 940GZZLUHPK Holland Park Underground Station
 940GZZLUHWY Holloway Road Underground Station
 940GZZLUHCH Hornchurch Underground Station
 940GZZLUHWC Hounslow Central Underground Station
 940GZZLUHWE Hounslow East Underground Station
 940GZZLUHWT Hounslow West Underground Station
 940GZZLUHPC Hyde Park Corner Underground Station
 940GZZLUICK Ickenham Underground Station
 940GZZLUKNG Kennington Underground Station
 940GZZLUKSL Kensal Green Underground Station
 940GZZLUKOY Kensington (Olympia) Underground Station
 940GZZLUKSH Kentish Town Underground Station
 940GZZLUKEN Kenton Underground Station
 940GZZLUKWG Kew Gardens Underground Station
 940GZZLUKPK Kilburn Park Underground Station
 940GZZLUKBN Kilburn Underground Station
 940GZZLUKSX King's Cross St. Pancras Underground Station
 940GZZLUKBY Kingsbury Underground Station
 940GZZLUKNB Knightsbridge Underground Station
 940GZZLULAD Ladbroke Grove Underground Station
 940GZZLULBN Lambeth North Underground Station
 940GZZLULGT Lancaster Gate Underground Station
 940GZZLULRD Latimer Road Underground Station
 940GZZLULSQ Leicester Square Underground Station
 940GZZLULYN Leyton Underground Station
 940GZZLULYS Leytonstone Underground Station
 940GZZLULVT Liverpool Street Underground Station
 940GZZLULNB London Bridge Underground Station
 940GZZLULGN Loughton Underground Station
 940GZZLUMRH Manor House Underground Station
 940GZZLUMSH Mansion House Underground Station
 940GZZLUMBA Marble Arch Underground Station
 940GZZLUMYB Marylebone Underground Station
 940GZZLUMED Mile End Underground Station
 940GZZLUMHL Mill Hill East Underground Station
 940GZZLUMMT Monument Underground Station
 940GZZLUMPK Moor Park Underground Station
 940GZZLUMGT Moorgate Underground Station
 940GZZLUMDN Morden Underground Station
 940GZZLUMTC Mornington Crescent Underground Station
 940GZZLUNDN Neasden Underground Station
 940GZZLUNBP Newbury Park Underground Station
 940GZZLUNAN North Acton Underground Station
 940GZZLUNEN North Ealing Underground Station
 940GZZLUNGW North Greenwich Underground Station
 940GZZLUNHA North Harrow Underground Station
 940GZZLUNWY North Wembley Underground Station
 940GZZLUNFD Northfields Underground Station
 940GZZLUNHT Northolt Underground Station
 940GZZLUNKP Northwick Park Underground Station
 940GZZLUNWH Northwood Hills Underground Station
 940GZZLUNOW Northwood Underground Station
 940GZZLUNHG Notting Hill Gate Underground Station
 940GZZLUOAK Oakwood Underground Station
 940GZZLUODS Old Street Underground Station
 940GZZLUOSY Osterley Underground Station
 940GZZLUOVL Oval Underground Station
 940GZZLUOXC Oxford Circus Underground Station
 940GZZLUPAH Paddington (H&C Line)-Underground
 940GZZLUPAC Paddington Underground Station
 940GZZLUPKR Park Royal Underground Station
 940GZZLUPSG Parsons Green Underground Station
 940GZZLUPVL Perivale Underground Station
 940GZZLUPCC Piccadilly Circus Underground Station
 940GZZLUPCO Pimlico Underground Station
 940GZZLUPNR Pinner Underground Station
 940GZZLUPLW Plaistow Underground Station
 940GZZLUPRD Preston Road Underground Station
 940GZZLUPYB Putney Bridge Underground Station
 940GZZLUQPS Queen's Park Underground Station
 940GZZLUQBY Queensbury Underground Station
 940GZZLUQWY Queensway Underground Station
 940GZZLURVP Ravenscourt Park Underground Station
 940GZZLURYL Rayners Lane Underground Station
 940GZZLURBG Redbridge Underground Station
 940GZZLURGP Regent's Park Underground Station
 940GZZLURMD Richmond Underground Station
 940GZZLURKW Rickmansworth Underground Station
 940GZZLURVY Roding Valley Underground Station
 940GZZLURYO Royal Oak Underground Station
 940GZZLURSG Ruislip Gardens Underground Station
 940GZZLURSM Ruislip Manor Underground Station
 940GZZLURSP Ruislip Underground Station
 940GZZLURSQ Russell Square Underground Station
 940GZZLUSVS Seven Sisters Underground Station
 940GZZLUSBC Shepherd's Bush (Central) Underground Station
 940GZZLUSBM Shepherd's Bush Market Underground Station
 940GZZLUSSQ Sloane Square Underground Station
 940GZZLUSNB Snaresbrook Underground Station
 940GZZLUSEA South Ealing Underground Station
 940GZZLUSHH South Harrow Underground Station
 940GZZLUSKS South Kensington Underground Station
 940GZZLUSKT South Kenton Underground Station
 940GZZLUSRP South Ruislip Underground Station
 940GZZLUSWN South Wimbledon Underground Station
 940GZZLUSWF South Woodford Underground Station
 940GZZLUSFS Southfields Underground Station
 940GZZLUSGT Southgate Underground Station
 940GZZLUSWK Southwark Underground Station
 940GZZLUSJP St. James's Park Underground Station
 940GZZLUSJW St. John's Wood Underground Station
 940GZZLUSPU St. Paul's Underground Station
 940GZZLUSFB Stamford Brook Underground Station
 940GZZLUSTM Stanmore Underground Station
 940GZZLUSGN Stepney Green Underground Station
 940GZZLUSKW Stockwell Underground Station
 940GZZLUSGP Stonebridge Park Underground Station
 940GZZLUSTD Stratford Underground Station
 940GZZLUSUH Sudbury Hill Underground Station
 940GZZLUSUT Sudbury Town Underground Station
 940GZZLUSWC Swiss Cottage Underground Station
 940GZZLUTMP Temple Underground Station
 940GZZLUTHB Theydon Bois Underground Station
 940GZZLUTBC Tooting Bec Underground Station
 940GZZLUTBY Tooting Broadway Underground Station
 940GZZLUTCR Tottenham Court Road Underground Station
 940GZZLUTMH Tottenham Hale Underground Station
 940GZZLUTAW Totteridge & Whetstone Underground Station
 940GZZLUTWH Tower Hill Underground Station
 940GZZLUTFP Tufnell Park Underground Station
 940GZZLUTNG Turnham Green Underground Station
 940GZZLUTPN Turnpike Lane Underground Station
 940GZZLUUPB Upminster Bridge Underground Station
 940GZZLUUPM Upminster Underground Station
 940GZZLUUPY Upney Underground Station
 940GZZLUUPK Upton Park Underground Station
 940GZZLUUXB Uxbridge Underground Station
 940GZZLUVXL Vauxhall Underground Station
 940GZZLUVIC Victoria Underground Station
 940GZZLUWWL Walthamstow Central Underground Station
 940GZZLUWSD Wanstead Underground Station
 940GZZLUWRR Warren Street Underground Station
 940GZZLUWKA Warwick Avenue Underground Station
 940GZZLUWLO Waterloo Underground Station
 940GZZLUWAF Watford Underground Station
 940GZZLUWYC Wembley Central Underground Station
 940GZZLUWYP Wembley Park Underground Station
 940GZZLUWTA West Acton Underground Station
 940GZZLUWBN West Brompton Underground Station
 940GZZLUWFN West Finchley Underground Station
 940GZZLUWHM West Ham Underground Station
 940GZZLUWHP West Hampstead Underground Station
 940GZZLUWHW West Harrow Underground Station
 940GZZLUWKN West Kensington Underground Station
 940GZZLUWRP West Ruislip Underground Station
 940GZZLUWSP Westbourne Park Underground Station
 940GZZLUWSM Westminster Underground Station
 940GZZLUWCY White City Underground Station
 940GZZLUWPL Whitechapel Underground Station
 940GZZLUWIG Willesden Green Underground Station
 940GZZLUWJN Willesden Junction Underground Station
 940GZZLUWIP Wimbledon Park Underground Station
 940GZZLUWIM Wimbledon Underground Station
 940GZZLUWOG Wood Green Underground Station
 940GZZLUWLA Wood Lane Underground Station
 940GZZLUWOF Woodford Underground Station
 940GZZLUWOP Woodside Park Underground Station

So, working with different modes…

tube : 270
overground : 111
tflrail : 32
dlr : 45

I very have recently done almost exactly this.

There’s a bit of mess in the data (I’ve posted some of the issues on here, but there’s doesn’t seem to be a lot of interest in fixing them), but it’s not too terrible to deal with.

What language are you using? My code is in JavaScript / Node.js - I’d be happy to share if it would help.

I didn’t use the lines but just did stop points by mode, and filtered on stop type, then cleaned up the weird cases.

Hi Brian,

Thanks for your reply. PHP isn’t my strong suit, but by the looks of things you’re keying the collection on the “id” attribute of the StopPoint? Are these unique across all StopPoints or only within a single mode? I follow your method, just thinking about whether I need to be storing different the StopPoints for different modes in different tables in my data store to avoid a duplicate key?

Daniel

Hi Mark,

Thanks for your reply. Did you use “NaptanMetroStation” for your type filter?

I’m writing in C# on .NET Core (I know…) but also considering swapping to Node.js to learn something new! I’m considering releasing my wrapper around the API as a package for other .NET developers - but I guess consuming the API is very different to understanding the results!

Daniel

Yes, it depends which modes you’re looking at, I’m currently only looking at tube, dlr and overground. For tube and dlr you want NaptanMetroStation and for overground you want NaptanRailStation.

I’ve just checked and that part of the code is very simple and probably not worth sharing. I also wanted to know all the lines (including overground and dlr) serving each station and all the entrances, for which you also need to look at the TransportInterchange stop types. That’s where most of the complexity is.

The basic structure is that all of the stop points are at the root level, and where they are logically children of the other stop points they are also included in a nested hierarchy. Issues I’ve seen are:

  1. Stations not necessarily including DLR and/or overground where they’re present in the lineModeGroups (or other equivalent orderings of lines) - you can get them via associated TransportInterchanges though.
  2. Entrances not consistently associated with the relevant metro or rail station - there are a few(?) just missing, but mostly they’re either on the metro station or the rail station, so as long as you just want everything for one station you can merge them (and some are on both so remove duplicates).
  3. Wimbledon has a weird extra NaptanRailStation with no entrances between the TransportInterchange and the actual NaptanRailStation with entrances, so you have to go down an extra level.
  4. If you are merging lines for tube, dlr and overground like I did, what’s included where is not consistent, so you will need to just merge everything and remove duplicates.

Hope that helps,
Mark

@originalarkus

You don’t really need to know the NaptanMetroStation as you don’t need to filter by it. As per the demo code you are looking for tubeStopPoint->modes (tubeStopPoint.modes) having “tube” in it.

I’ve re-written it in synchronous Javascript, perhaps that makes it clearer?

var QGTS = new function () {
this.arrFound = [];
this.execute = function (mode = "tube") {
    var httpRequest = new XMLHttpRequest();
    httpRequest.onreadystatechange = function () {
        QGTS.alertNewLiveData(httpRequest,mode);
    };
    httpRequest.open("GET", "https://api.tfl.gov.uk/line/mode/" + mode + "/status", false);
    httpRequest.send("");
    for (var key in this.arrFound) {
        console.log("key " + key + " has value " + this.arrFound[key]);
    }
}

this.alertNewLiveData = function (httpRequest,mode) {
    if (4 === httpRequest.readyState) {
        if (200 === httpRequest.status) {
            var tubeStatus = JSON.parse(httpRequest.responseText);
            tubeStatus.forEach(element => {
                var httpRequest = new XMLHttpRequest();
                httpRequest.onreadystatechange = function () {
                    QGTS.alertNewLiveDataInner(httpRequest,mode);
                };
                httpRequest.open("GET", "https://api.tfl.gov.uk/line/" + element.id + "/stoppoints", false);
                httpRequest.send("");
            });
        }
    }
}

this.alertNewLiveDataInner = function (httpRequest, mode) {
    if (4 === httpRequest.readyState) {
        if (200 === httpRequest.status) {
            var tubeStopPoints = JSON.parse(httpRequest.responseText);
            tubeStopPoints.forEach(
                tubeStopPoint => {
                    {
                        if (tubeStopPoint.modes.indexOf(mode) > 0)
                            this.arrFound[tubeStopPoint.id] = tubeStopPoint.commonName;
                    }
                });
        }
    }
}
}
QGTS.execute();



QuickGetTubesOnly.js:11 key 940GZZLUMSH has value Mansion House Underground Station
QuickGetTubesOnly.js:11 key 940GZZLURYO has value Royal Oak Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUWSP has value Westbourne Park Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUADE has value Aldgate East Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUBWR has value Bow Road Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUDGE has value Dagenham East Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUDGY has value Dagenham Heathway Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUECM has value Ealing Common Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUECT has value Earl's Court Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUEHM has value East Ham Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUEPY has value East Putney Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUFBY has value Fulham Broadway Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUHCH has value Hornchurch Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUPLW has value Plaistow Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUPYB has value Putney Bridge Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUSFS has value Southfields Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUSGN has value Stepney Green Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUTNG has value Turnham Green Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUUPK has value Upton Park Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUUPY has value Upney Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUGPK has value Green Park Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUQBY has value Queensbury Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUSTM has value Stanmore Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUWYP has value Wembley Park Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUHGD has value Hillingdon Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUICK has value Ickenham Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUNKP has value Northwick Park Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUNWH has value Northwood Hills Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUPNR has value Pinner Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUPRD has value Preston Road Underground Station
QuickGetTubesOnly.js:11 key 940GZZLURSM has value Ruislip Manor Underground Station
QuickGetTubesOnly.js:11 key 940GZZLURSP has value Ruislip Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUUXB has value Uxbridge Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUCPC has value Clapham Common Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUCTN has value Camden Town Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUEFY has value East Finchley Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUGDG has value Goodge Street Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUHBT has value High Barnet Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUHGT has value Highgate Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUHTD has value Hampstead Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUKNG has value Kennington Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUMTC has value Mornington Crescent Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUOVL has value Oval Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUSKW has value Stockwell Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUTFP has value Tufnell Park Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUWOP has value Woodside Park Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUASG has value Arnos Grove Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUBDS has value Bounds Green Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUBOS has value Boston Manor Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUCAR has value Caledonian Road Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUHPC has value Hyde Park Corner Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUHWC has value Hounslow Central Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUHWE has value Hounslow East Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUHWY has value Holloway Road Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUKNB has value Knightsbridge Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUMRH has value Manor House Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUOAK has value Oakwood Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUOSY has value Osterley Underground Station
QuickGetTubesOnly.js:11 key 940GZZLURSQ has value Russell Square Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUSEA has value South Ealing Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUSHH has value South Harrow Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUSUT has value Sudbury Town Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUTPN has value Turnpike Lane Underground Station
QuickGetTubesOnly.js:11 key 940GZZLUWOG has value Wood Green Underground Station

You don’t need to know the station stopType if you’re getting the lines first. However if you get the stop points by mode rather than line, you only need to make the one API call and then filter by the stopType (this is in fancy modern JS and uses a couple of modules to keep your secrets in environment variables and make the http request a bit nicer):

import axios from 'axios';
import dotenv from 'dotenv';

dotenv.config();
const app_id = process.env.APP_ID;
const app_key = process.env.APP_KEY;

const fetchData = async (mode) => {
  let result = await axios.get(`https://api.tfl.gov.uk/StopPoint/Mode/${mode}?app_id=${app_id}&app_key=${app_key}`);
  const stopPoints = result.data.stopPoints;
  const stopType = mode === 'overground' ? 'NaptanRailStation' : 'NaptanMetroStation';
  const stations = stopPoints.filter(sp => sp.stopType === stopType);
  // map through the stations and grab the stuff you want from each and then return it
  // unless you really want the whole thing, which you probably don't, it's enormous
}

const getStations = async () => {
  let stations = await fetchData('tube');
  const dlrStations = await fetchData('dlr');
  const overgroundStations = await fetchData('overground');
  
  // do something with the station data - I merge it and put it in a JSON file in S3
  // you might have something else you need to do here
}

getStations();

@markw @originalarkus

I guess the issue here is, when you have no idea what the poster was trying to use for their code, whether to go for something explanatory like pseudocode, or try to show some actual working code, even though it might be less than clear.

I must admit that I personally find that conditional operators make unreadable code…

const stopType = mode === 'overground' ? 'NaptanRailStation' : 'NaptanMetroStation';

whilst others don’t like language-specific shortcut functions like in_array

 if (in_array($strMode, $tubeStopPoint->modes))  ...

And then there is the Javascript dotted notation vs -> for PHP. Anyway, I’m always interested to see what people use.

Going back to

I’m writing in C# on .NET Core (I know…)

I fired up Visual Studio and I got stuck as you can’t decode JSON in .NET core as far as I can see. This was a far as I got trying with VB.NET

Imports System.Net
Imports System.IO
Module TfLStationNames
Sub Main(Optional mode As String = "tube")
    Dim request As HttpWebRequest = DirectCast(WebRequest.Create("https://api.tfl.gov.uk/line/mode/" + mode + "/status"), HttpWebRequest)
    Dim response As HttpWebResponse = DirectCast(request.GetResponse(), HttpWebResponse)
    Dim reader As StreamReader = New StreamReader(response.GetResponseStream())
    Dim rawresp As String = reader.ReadToEnd()
End Sub
End Module

Thank you both for your comments, each approach has helped me reach a solution in .NET Core.

@markw I was using a method similar to yours to begin with, getting in via the /StopPoint/Mode/{mode} endpoint as it seemed to use fewer API calls. The const stopType = … line was particularly useful for me, as that allowed me to filter down to ‘NaptanMetroStation’ to retrieve just tube lines. Obviously I’ll need a switch to deal with other station types later if I implement London Overground etc…

@briantist Your example worked wonderfully in my head, but required a few more API calls (I’ve already had an email from TfL for hitting 500 requests a minute in an early version of my code!) so I was keen to be lean. Not sure if you plan to do much .NET Core, but there is a library you can import using NuGet called System.Text.Json which will let you work with JSON easily. There’s also a library for consuming REST APIs called RestSharp. Combined together, consuming the TfL API is relatively straight forward but still far more complicated than it is in PHP! By way of example (with some boilerplate code missing), I can get the list of Modes from /Line/Meta/Modes, and return a strongly typed collection from the decoded JSON, using:

	public async Task<List<Mode>> GetModes()
	{
		var restRequest = new RestRequest{Resource = "/Line/Meta/Modes"};

		var result = await _client.ExecuteAsync<List<Mode>>(restRequest);
		return result.Data;
	}

Thanks again both for your help!

2 Likes

@originalarkus

I’m glad you got it sorted, and thanks for your kind comments.

It’s worth reiterating @markw that it’s always worth storing this kind of static data on your own server, as it keeps down the number of API calls. Most of my code for TfL passes through a memcached interface, so that I can correctly cache things for as long as it necessary. I think new tube stations come along every decade or so, so caching the names for a week isn’t going to hurt. Holding the data on S3 is a great idea for Android/iOS app, memcached for my Ajax/PHP web apps.