BYTETOOLS

Transport for London API

Free Transport for London API: live tube line status, arrivals, journey planning, bike hire and stop points across London. No key for light use. Tested example.

No API key requiredCORS enabledHTTPSFree tier

Endpoint tested and returned HTTP 200 on 2026-08-19

What is the Transport for London API?

The Transport for London Unified API provides free real-time data for London's transport network — tube and rail line status, live arrival predictions, journey planning, cycle hire availability and stop point information.

TfL's Unified API is one of the best transport APIs published by any city. It covers the tube, buses, Overground, Elizabeth line, DLR, trams, river services and Santander Cycles through a consistent interface, with real-time arrival predictions rather than just timetables.

Light use works with no credentials at all, which is what the example here demonstrates. Registering for a free app key raises your rate limit substantially and is worth doing before you ship anything that polls regularly.

Quick facts

Base URL
https://api.tfl.gov.uk
Authentication
Works without credentials at a low rate. A free app_key raises the limit to 500 requests per minute.
Rate limit
About 50 requests per minute unregistered; 500 per minute with a free key.
Pricing
Free under the TfL open data terms, which require attribution.
CORS
Enabled — callable directly from browser JavaScript
Official docs
Read the docs

How to use the Transport for London API

Every request below was executed against the live API on 2026-08-19, and the response shown is the real body it returned — not an illustration.

1. Live status for all tube lines

GET https://api.tfl.gov.uk/Line/Mode/tube/Status

curl
curl 'https://api.tfl.gov.uk/Line/Mode/tube/Status'
JavaScript (fetch)
const res = await fetch("https://api.tfl.gov.uk/Line/Mode/tube/Status");
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
const data = await res.json();
console.log(data);
Python (requests)
import requests

res = requests.get("https://api.tfl.gov.uk/Line/Mode/tube/Status", timeout=20)
res.raise_for_status()
print(res.json())
Response — HTTP 200 (truncated)
[
  {
    "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities",
    "id": "bakerloo",
    "name": "Bakerloo",
    "modeName": "tube",
    "disruptions": [],
    "created": "2026-08-17T17:06:09.307Z",
    "modified": "2026-08-17T17:06:09.307Z",
    "lineStatuses": [
      {
        "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities",
        "id": 0,
        "statusSeverity": 10,
        "statusSeverityDescription": "Good Service",
        "created": "0001-01-01T00:00:00",
        "validityPeriods": []
      }
    ],
    "routeSections": [],
    "serviceTypes": [
      {
        "$type": "Tfl.Api.Presentation.Entities.LineServiceTypeInfo, Tfl.Api.Presentation.Entities",
        "name": "Regular",
        "uri": "/Line/Route?ids=Bakerloo&serviceTypes=Regular"
      }
    ],
    "crowding": {
      "$type": "Tfl.Api.Presentation.Entities.Crowding, Tfl.Api.Presentation.Entities"
    }
  },
  {
    "$type": "Tfl.Api.Presentation.Entities.Line, Tfl.Api.Presentation.Entities",
    "id": "central",
    "name": "Central",
    "modeName": "tube",
    "disruptions": [],
    "created": "2026-08-17T17:06:09.307Z",
    "modified": "2026-08-17T17:06:09.307Z",
    "lineStatuses": [
      {
        "$type": "Tfl.Api.Presentation.Entities.LineStatus, Tfl.Api.Presentation.Entities",
        "id": 0,
        "statusSeverity": 10,
        "statusSeverityDescription": "Good Service",
        "created": "0001-01-01T00:00:00",
        "validityPeriods": []
      }
    ],
    "routeSections": [],
    "serviceTypes": [
      {
        "$type": "

Parameters

ParameterTypeRequiredDescription
<mode>pathOptionalTransport mode: tube, bus, dlr, overground, tram. tube
app_keystringOptionalFree API key to raise the rate limit. your-key
StopPoint/<id>/ArrivalspathOptionalLive arrival predictions for a stop. 940GZZLUOXC
Journey/JourneyResults/<from>/to/<to>pathOptionalPlan a journey between two points. SW1A1AA/to/E1

Response fields

idstring
Line identifier, e.g. bakerloo.
namestring
Display name of the line.
modeNamestring
Transport mode.
lineStatuses[].statusSeverityDescriptionstring
Good Service, Minor Delays, Part Closure and so on.
lineStatuses[].reasonstring
Explanation when there is disruption.
disruptionsarray
Active disruptions affecting the line.

What you can build with the Transport for London API

  • Show live tube status on a dashboard or office display
  • Build arrival boards for a specific station or bus stop
  • Add journey planning to a London-focused app
  • Track Santander Cycles dock availability

Common errors and how to fix them

429

Unregistered rate limit exceeded.

Fix: Register for a free app key and pass it as app_key — it raises the limit tenfold.

404 on StopPoint

Unknown stop point identifier.

Fix: Use the /StopPoint/Search endpoint to resolve a station name to its NaPTAN id.

Empty lineStatuses

The line is running normally with no reported status.

Fix: Treat an empty or Good Service status as normal operation.

Transport for London API — frequently asked questions

Is the TfL API free?

Yes, free under TfL's open data terms, which require attribution. Light use needs no credentials; a free app key raises the rate limit substantially.

Does it provide real-time arrivals?

Yes. The StopPoint Arrivals endpoints return live predictions rather than scheduled times, which is what makes it useful for departure boards.

Which transport modes are covered?

Tube, bus, DLR, Overground, Elizabeth line, tram, river services, National Rail within London, and Santander Cycles docking stations.

How do I find a station's id?

Use /StopPoint/Search?query=Oxford+Circus to resolve a name to its NaPTAN identifier, then use that id with the arrivals endpoints.

Tools that pair with this API

Transport for London is an independent third-party service and is not affiliated with ByteTools or ByteVancer. Details on this page were verified on 2026-08-19; always check the official documentation before relying on this API in production, as terms and limits can change.