Guides
- UK bus times in Python
- Live UK train departures
- Journey planning that knows about hills
- Where can I get to in 30 minutes?
- How do I get to the airport?
- How reliable is my bus?
Docs
How do I get to the airport?
"How do I get to the airport?" is one of the most-asked travel questions, and the answer is spread across rail, tram, bus and coach operators. This guide takes what someone types ("Manchester airport", "LHR"), finds the airport, and lists everything that serves it, with live train departures and any disruption nearby. It covers all 50 airports in England, Scotland and Wales with scheduled flights.
What you need
- Python 3.9 or later, and
pip install requests - A TransCAPI key: sign up free,
then
export TRANSCAPI_KEY=your_key
The code
import os
from datetime import datetime
from zoneinfo import ZoneInfo
import requests
API = "https://api.transcapi.com/v1"
HEADERS = {"X-Api-Key": os.environ["TRANSCAPI_KEY"]}
UK = ZoneInfo("Europe/London")
def uk_time(iso):
return datetime.fromisoformat(iso).astimezone(UK).strftime("%H:%M") if iso else "--:--"
# 1. Find the airport from what someone types
place = requests.get(f"{API}/places.json", headers=HEADERS,
params={"query": "Manchester airport", "type": "airport"}).json()["member"][0]
# 2. Everything that serves it
airport = requests.get(f"{API}/airports/{place['iata']}.json", headers=HEADERS).json()
print(f"{airport['name']} ({airport['iata']})\n")
print("Trains")
for station in airport["rail_stations"][:2]:
board = requests.get(f"{API}/rail/station_timetables/{station['crs_code']}.json",
headers=HEADERS).json()
print(f" {station['name']} ({station['distance']} m from the terminal)")
for d in board["departures"][:4]:
print(f" {uk_time(d['aimed_departure_time'])} exp {uk_time(d['expected_departure_time'])}"
f" {d['destination']:<24} {d['status']}")
print("\nTrams, metro, buses and coaches at the terminals")
for stop in airport["stops"][:6]:
lines = ", ".join(sorted({l["line"] for l in stop["lines"]}))
where = f"{stop['name']} ({stop['indicator']})" if stop.get("indicator") else stop["name"]
print(f" {stop['mode']:<6} {where[:56]:<56} {lines}")
if airport["disruptions"]:
print("\nDisruptions nearby")
for d in airport["disruptions"][:3]:
print(f" [{d['severity']}] {d['summary']}")
Run it:
$ python airport_transport.py
Manchester Airport (MAN)
Trains
Manchester Airport (259 m from the terminal)
12:04 exp 12:04 Edinburgh on_time
12:07 exp 12:07 Manchester Piccadilly on_time
12:17 exp 12:17 Blackpool North on_time
12:25 exp 12:25 Holyhead on_time
Styal (2394 m from the terminal)
12:05 exp 12:05 Crewe on_time
12:45 exp 12:45 Manchester Piccadilly on_time
Trams, metro, buses and coaches at the terminals
tram Manchester Airport (Manchester Metrolink) (To Manchester Navy Line
bus Manchester Airport The Station (Stand A) 120, 121, 181, 422, 424, 541, 819, 828, 829, G4, UK072, UK074, UK076, UK930, UK980, UKN23
bus Manchester Airport The Station (Stand B) 120, 121, 170, 172, 181, 421, 422, 424, 541, 811, 819, G4
bus Manchester Airport The Station (Arrivals) 103, 248, 368, 43
bus Manchester Airport The Station (Stand C) 170, 172, 177, 811, 829
bus Manchester Airport The Station (Stand D) 103
Disruptions nearby
[minor] Lines reopened: major disruption between York and Newcastle / Middlesbrough / Sunderland expected until 13:00
[minor] Amended late night / early morning service in the Manchester area from Monday 5 to Friday 9 October
Real output, 7 October 2026. The disruption appears because TransPennine trains from Manchester Airport run to Newcastle.
How it works
1. Finding the airport
/v1/places.json with type=airport matches airport
names, towns and codes, so "Heathrow", "LHR" and "Leeds airport" all work.
Without the filter, a search that's plainly about an airport puts it first,
and a city search ("Manchester") puts the city first and its airport after.
2. Everything that serves it
/v1/airports/{iata}.json returns the airport's terminal
entrances and, measured from them:
rail_stationswithin 3 km, nearest first, so Heathrow lists its four stations and Edinburgh lists Edinburgh Gateway, a tram ride away;stops: tram, metro, bus and coach stops within 500 m, each with the lines that call there;disruptionsin force within 3 km: bus, tram, National Rail engineering works and incidents, and TfL.
3. Live departures
Each station's crs_code goes to
/v1/rail/station_timetables for live times, platforms and delays
from National Rail; each stop's atcocode goes to
/v1/bus/stop_timetables. To plan the whole trip, pass a
terminal's position to /v1/journey.json, which also tells you the
chance of making each change, worth knowing when there's a flight to catch.
What isn't here
Flights. There's no open UK flight schedule or departures data, so TransCAPI covers getting to and from the airport, not the flight itself. Northern Ireland's airports aren't included, in line with the rest of the API.
All the fields are in the airports docs.
Try it. A free key gives you 1,000 requests a day with no card. Every endpoint covers Great Britain: see coverage for the parts that are regional.