# Transport for London API

> Transport for London returns London line status and journey options through a workflow and API.

Transport for London (TfL) Get line status returns current or future-day service status; date and line are optional. Plan journey returns London journey options, leg directions, times and available adult fares; origin and destination are required.

- Page: https://fous.com/workflows/transport-for-london
- Handle: `@transport-for-london`
- Category: [Travel](https://fous.com/workflows/category/travel)
- Source website: https://tfl.gov.uk
- Last verified: Sep 30, 2026
- Fous is not affiliated with Transport for London.

## Methods

### Get line status

Operation `get_line_status`, version 1. 1 credit per call.

Get current or future-day service status for London Tube, Elizabeth line, DLR, Overground, tram or a named bus route. For multiple notices on one line, shows the most disruptive status, combines its reasons and spans its validity times; future-day information reflects currently published plans.

**Input**

| Field | Type | Required | Example | Description |
|---|---|---|---|---|
| `date` | string | no | `"2026-10-03"` | Future service date in YYYY-MM-DD, such as 2026-10-03. Omit for the current live status. |
| `line` | string | no | `"73"` | Line name or bus route number, such as Northern, Elizabeth line, Mildmay, Overground or 73. Omit for all rail and tram lines. |

**Input schema**

```json
{
  "type": "object",
  "properties": {
    "date": {
      "type": "string",
      "format": "date",
      "description": "Future service date in YYYY-MM-DD, such as 2026-10-03. Omit for the current live status.",
      "examples": [
        "2026-10-03"
      ]
    },
    "line": {
      "type": "string",
      "default": "",
      "description": "Line name or bus route number, such as Northern, Elizabeth line, Mildmay, Overground or 73. Omit for all rail and tram lines.",
      "examples": [
        "73",
        "Overground",
        "Jubilee"
      ]
    }
  },
  "additionalProperties": false,
  "examples": [
    {},
    {
      "line": "73"
    },
    {
      "line": "Overground"
    }
  ]
}
```

**Output**

| Field | Type | Example | Description |
|---|---|---|---|
| `lines` | array |  | Service status in TfL line order. |
| `lines[].type` | string | `"Tube"` | Transport type. |
| `lines[].reason` | string or null | `"Bakerloo Line: Service will resume later this morning."` | Explanation when service is not good, or null. |
| `lines[].status` | string | `"Service closed"` | Service status in words. |
| `lines[].line_id` | string | `"bakerloo"` | TfL line identifier. |
| `lines[].valid_to` | string or null | `"2026-09-29T05:58:27+01:00"` | End of the reported status in London local time, or null. |
| `lines[].line_name` | string | `"Bakerloo"` | Line or bus route name. |
| `lines[].page_link` | string | `"https://tfl.gov.uk/tube-bus-river/status/"` | TfL service status page for this line. |
| `lines[].valid_from` | string or null | `"2026-09-29T01:16:15+01:00"` | Beginning of the reported status in London local time, or null. |
| `lines[].severity_number` | integer | `20` | TfL status severity number. |

**Example input**

```json
{}
```

**Example output**

```json
{
  "lines": [
    {
      "type": "Tube",
      "reason": "Bakerloo Line: Service will resume later this morning.",
      "status": "Service closed",
      "line_id": "bakerloo",
      "valid_to": "2026-09-29T05:58:27+01:00",
      "line_name": "Bakerloo",
      "page_link": "https://tfl.gov.uk/tube-bus-river/status/",
      "valid_from": "2026-09-29T01:16:15+01:00",
      "severity_number": 20
    },
    {
      "type": "Tube",
      "reason": "Central Line: Service will resume later this morning.",
      "status": "Service closed",
      "line_id": "central",
      "valid_to": "2026-09-29T05:58:27+01:00",
      "line_name": "Central",
      "page_link": "https://tfl.gov.uk/tube-bus-river/status/",
      "valid_from": "2026-09-29T01:16:28+01:00",
      "severity_number": 20
    },
    {
      "type": "Tube",
      "reason": "Circle Line: Service will resume later this morning.",
      "status": "Service closed",
      "line_id": "circle",
      "valid_to": "2026-09-29T05:58:27+01:00",
      "line_name": "Circle",
      "page_link": "https://tfl.gov.uk/tube-bus-river/status/",
      "valid_from": "2026-09-29T01:16:41+01:00",
      "severity_number": 20
    }
  ]
}
```

### Plan journey

Operation `plan_journey`, version 1. 1 credit per call.

Plan a London public transport journey from a place, station, address or postcode. Returns journey options in TfL order, with leg directions and an adult pay-as-you-go fare when available.

**Input**

| Field | Type | Required | Example | Description |
|---|---|---|---|---|
| `modes` | array | no |  | Transport modes to include; omit for all public transport. Example: ["tube", "bus"]. |
| `origin` | string | yes | `"SW1A 1AA"` | London address, station, place or postcode. Example: King's Cross. |
| `time_is` | string | no | `"arriving"` | Whether the specified time is when you leave or arrive. Example: departing. |
| `date_time` | string | no | `"2026-09-30T12:00:00+01:00"` | London local departure or arrival date and time as ISO 8601, or now. Example: 2026-09-30T12:00:00+01:00. |
| `destination` | string | yes | `"SE1 7PB"` | London address, station, place or postcode. Example: Brixton. |
| `max_results` | integer | no | `2` | Most journey options to show, in TfL order. Example: 3. |

**Input schema**

```json
{
  "type": "object",
  "required": [
    "origin",
    "destination"
  ],
  "properties": {
    "modes": {
      "type": "array",
      "items": {
        "enum": [
          "tube",
          "bus",
          "overground",
          "elizabeth_line",
          "dlr",
          "national_rail"
        ],
        "type": "string",
        "examples": [
          "bus"
        ],
        "description": "Use the same format as these example values: \"bus\"."
      },
      "description": "Transport modes to include; omit for all public transport. Example: [\"tube\", \"bus\"].",
      "uniqueItems": true,
      "examples": [
        [
          "bus"
        ]
      ]
    },
    "origin": {
      "type": "string",
      "title": "From",
      "description": "London address, station, place or postcode. Example: King's Cross.",
      "examples": [
        "SW1A 1AA",
        "King's Cross"
      ]
    },
    "time_is": {
      "enum": [
        "departing",
        "arriving"
      ],
      "type": "string",
      "default": "departing",
      "description": "Whether the specified time is when you leave or arrive. Example: departing.",
      "examples": [
        "arriving"
      ]
    },
    "date_time": {
      "type": "string",
      "default": "now",
      "description": "London local departure or arrival date and time as ISO 8601, or now. Example: 2026-09-30T12:00:00+01:00.",
      "examples": [
        "2026-09-30T12:00:00+01:00"
      ]
    },
    "destination": {
      "type": "string",
      "title": "To",
      "description": "London address, station, place or postcode. Example: Brixton.",
      "examples": [
        "SE1 7PB",
        "Brixton"
      ]
    },
    "max_results": {
      "type": "integer",
      "default": 3,
      "maximum": 10,
      "minimum": 1,
      "description": "Most journey options to show, in TfL order. Example: 3.",
      "x-fous-developer": true,
      "examples": [
        2,
        3
      ]
    }
  },
  "additionalProperties": false,
  "examples": [
    {
      "modes": [
        "bus"
      ],
      "origin": "SW1A 1AA",
      "time_is": "arriving",
      "date_time": "2026-09-30T12:00:00+01:00",
      "destination": "SE1 7PB",
      "max_results": 2
    },
    {
      "origin": "King's Cross",
      "date_time": "2026-09-30T12:00:00+01:00",
      "destination": "Brixton",
      "max_results": 3
    }
  ]
}
```

**Output**

| Field | Type | Example | Description |
|---|---|---|---|
| `journeys` | array |  |  |
| `journeys[].legs` | array |  |  |
| `journeys[].page_link` | string | `"https://tfl.gov.uk/plan-a-journey/results?InputFrom=SW1A+1AA&InputTo=SE1+7PB&Date=20260930&Time=1200&TimeIs=arriving"` |  |
| `journeys[].total_time` | string | `"15 min"` |  |
| `journeys[].arrival_time` | string | `"2026-09-30T11:40:00+01:00"` |  |
| `journeys[].time_minutes` | integer | `15` |  |
| `journeys[].fare_currency` | string | `"GBP"` |  |
| `journeys[].departure_time` | string | `"2026-09-30T11:25:00+01:00"` |  |
| `journeys[].adult_pay_as_you_go_fare_gbp` | number or null | `1.75` |  |

**Example input**

```json
{
  "modes": [
    "bus"
  ],
  "origin": "SW1A 1AA",
  "time_is": "arriving",
  "date_time": "2026-09-30T12:00:00+01:00",
  "destination": "SE1 7PB",
  "max_results": 2
}
```

**Example output**

```json
{
  "journeys": [
    {
      "legs": [
        {
          "mode": "walking",
          "to_stop": "St James's Park Station",
          "leg_time": "10 min",
          "from_stop": "SW1A 1AA",
          "line_name": null,
          "instruction": "Walk to St James's Park Station",
          "time_minutes": 10
        }
      ],
      "page_link": "https://tfl.gov.uk/plan-a-journey/results?InputFrom=SW1A+1AA&InputTo=SE1+7PB&Date=20260930&Time=1200&TimeIs=arriving",
      "total_time": "15 min",
      "arrival_time": "2026-09-30T11:40:00+01:00",
      "time_minutes": 15,
      "fare_currency": "GBP",
      "departure_time": "2026-09-30T11:25:00+01:00",
      "adult_pay_as_you_go_fare_gbp": 1.75
    }
  ]
}
```

## Quick start

Call the API with a Fous API key (`FOUS_API_KEY`). To create one, turn on Developer mode in Fous Studio, then open Keys & connections → API keys (https://app.fous.com/keys).

```bash
# First set your key: export FOUS_API_KEY='YOUR_FOUS_API_KEY'
: "${FOUS_API_KEY:?Set FOUS_API_KEY before running this example}"

curl 'https://api.fous.com/v1/query' \
  --fail-with-body --silent --show-error --max-time 120 \
  -H "Authorization: Bearer $FOUS_API_KEY" \
  -H 'Content-Type: application/json' \
  --data-raw '{
  "api": "@transport-for-london",
  "visibility": "public",
  "operation": "get_line_status",
  "version": 1,
  "input": {},
  "response": {
    "format": "json"
  }
}'
```

```python
# Save as fous.py and run with python3 fous.py. No packages needed.
# First set your key: export FOUS_API_KEY='YOUR_FOUS_API_KEY'
import json
import os
import urllib.error
import urllib.request

api_key = os.environ.get("FOUS_API_KEY")
if not api_key:
    raise RuntimeError("Set FOUS_API_KEY before running this example")

body = json.loads("{\n  \"api\": \"@transport-for-london\",\n  \"visibility\": \"public\",\n  \"operation\": \"get_line_status\",\n  \"version\": 1,\n  \"input\": {},\n  \"response\": {\n    \"format\": \"json\"\n  }\n}")
request = urllib.request.Request(
    "https://api.fous.com/v1/query",
    data=json.dumps(body).encode("utf-8"),
    headers={
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
    },
    method="POST",
)
try:
    with urllib.request.urlopen(request, timeout=120) as response:
        result = json.load(response)
except urllib.error.HTTPError as error:
    raise RuntimeError(f"HTTP {error.code}: {error.read().decode('utf-8', errors='replace')}") from error
if result.get("success") is False:
    raise RuntimeError(result.get("error", {}).get("message", "Request failed"))
print(json.dumps(result["data"]["output"], indent=2))
```

```typescript
// Save as fous.mts and run with npx tsx fous.mts.
// First set your key: export FOUS_API_KEY='YOUR_FOUS_API_KEY'
const apiKey = process.env.FOUS_API_KEY;
if (!apiKey) throw new Error("Set FOUS_API_KEY before running this example");

const response = await fetch("https://api.fous.com/v1/query", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${apiKey}`,
    "Content-Type": "application/json",
  },
  signal: AbortSignal.timeout(120_000),
  body: JSON.stringify({
  "api": "@transport-for-london",
  "visibility": "public",
  "operation": "get_line_status",
  "version": 1,
  "input": {},
  "response": {
    "format": "json"
  }
}),
});
type ApiResult = { success: boolean; data?: { output: unknown }; error?: { message: string } };
const result: ApiResult = await response.json();
if (!response.ok || result.success === false) {
  throw new Error(result.error?.message ?? `HTTP ${response.status}`);
}
if (!result.data) throw new Error("Missing API response data");
console.log(result.data.output);
```

Or describe the data in plain language: send `{"api":"@transport-for-london","prompt":"Describe the data you need, with every detail"}` to the same URL. Fous fills in the input, runs the method that fits and returns only the fields you asked for; `data.route.calls[].request` is the exact call it made. Routing is free; the run costs the same.

## Use cases

- Check line or bus route status before travelling
- Review published service plans for a future date
- Compare public transport journeys between London locations
- Estimate journey times and available adult pay-as-you-go fares

## FAQ

### Is Fous affiliated with Transport for London?

No. Fous is not affiliated with Transport for London. This workflow reads the public tfl.gov.uk website and returns its data.

### How much does it cost?

Each run costs 1 credit. With pay-as-you-go, a credit costs 1¢; monthly plans cost less per credit.

### Do I need a Transport for London account?

No. You only need a Fous account.

### How current is the data?

Fous gets the data from tfl.gov.uk when you run it; repeating the same request within a day may return the saved result. Fous checks this workflow automatically; it last passed a check on Sep 30, 2026.

### What is the service status for a London line?

Use Get line status with a line name or bus route number, or omit the line to see all rail and tram lines.

### What service status is planned for a future date?

Use Get line status with a future date. Results reflect currently published plans.

### What journeys can I take between two London locations?

Use Plan journey with an origin and destination to get journey options, leg directions, times and an adult pay-as-you-go fare when available.

## Related

- [All Travel workflows](https://fous.com/workflows/category/travel)
