Find an API

Search public APIs with auth details & Postman guides

← All APIs

Transport for London Unified API

tfl · Data

Data No Auth Free & Open transport open_data

Our unified API brings together data across all modes of transport into a single RESTful API. This API provides access to the most highly requested realtime and status infomation across all the modes of transport, in a single and consistent way. Access to the developer documentation is available at https://api.tfl.gov.uk

Authentication

No authentication requiredFree to use with no key needed.

Sample Requests

GET Gets the places that lie within a geographic region. The geographic region of interest can either be specified by using a lat/lon geo-point and a radius in metres to return places within the locus defined by the lat/lon of its centre or alternatively, by the use of a bounding box defined by the lat/lon of its north-west and south-east corners. Optionally filters on type and can strip properties for a smaller payload.

Gets the places that lie within a geographic region. The geographic region of interest can either be specified by using a lat/lon geo-point and a radius in metres to return places within the locus defined by the lat/lon of its centre or alternatively, by the use of a boundi

https://api.apis.guru/v2/specs/tfl.gov.uk/v1/Place?type=json&radius=1&activeOnly=true&categories=example&placeGeo.lat=1&placeGeo.lon=1&placeGeo.neLat=1&placeGeo.neLon=1&placeGeo.swLat=1&placeGeo.swLon=1&includeChildren=true&numberOfPlacesToReturn=1

Hover any highlighted part to learn what it does

curl -X GET "https://api.apis.guru/v2/specs/tfl.gov.uk/v1/Place?type=json&radius=1&activeOnly=true&categories=example&placeGeo.lat=1&placeGeo.lon=1&placeGeo.neLat=1&placeGeo.neLon=1&placeGeo.swLat=1&placeGeo.swLon=1&includeChildren=true&numberOfPlacesToReturn=1"
import requests
params = {
    "type": "json",
    "radius": "1",
    "activeOnly": "true",
    "categories": "example",
    "placeGeo.lat": "1",
    "placeGeo.lon": "1",
    "placeGeo.neLat": "1",
    "placeGeo.neLon": "1",
    "placeGeo.swLat": "1",
    "placeGeo.swLon": "1",
    "includeChildren": "true",
    "numberOfPlacesToReturn": "1"
}
response = requests.get(
    "https://api.apis.guru/v2/specs/tfl.gov.uk/v1/Place",
    params=params,
)
print(response.json())
const url = new URL('https://api.apis.guru/v2/specs/tfl.gov.uk/v1/Place');
url.searchParams.set('type', 'json');
url.searchParams.set('radius', '1');
url.searchParams.set('activeOnly', 'true');
url.searchParams.set('categories', 'example');
url.searchParams.set('placeGeo.lat', '1');
url.searchParams.set('placeGeo.lon', '1');
url.searchParams.set('placeGeo.neLat', '1');
url.searchParams.set('placeGeo.neLon', '1');
url.searchParams.set('placeGeo.swLat', '1');
url.searchParams.set('placeGeo.swLon', '1');
url.searchParams.set('includeChildren', 'true');
url.searchParams.set('numberOfPlacesToReturn', '1');

const response = await fetch(url); 
const data = await response.json();
console.log(data);
package main

import (
	"fmt"
	"io"
	"net/http"
	"net/url"
)

func main() {
	baseURL, _ := url.Parse("https://api.apis.guru/v2/specs/tfl.gov.uk/v1/Place")
	q := baseURL.Query()
	q.Set("type", "json")
	q.Set("radius", "1")
	q.Set("activeOnly", "true")
	q.Set("categories", "example")
	q.Set("placeGeo.lat", "1")
	q.Set("placeGeo.lon", "1")
	q.Set("placeGeo.neLat", "1")
	q.Set("placeGeo.neLon", "1")
	q.Set("placeGeo.swLat", "1")
	q.Set("placeGeo.swLon", "1")
	q.Set("includeChildren", "true")
	q.Set("numberOfPlacesToReturn", "1")
	baseURL.RawQuery = q.Encode()
	targetURL := baseURL.String()
	req, _ := http.NewRequest("GET", targetURL, nil)

	client := &http.Client{}
	resp, _ := client.Do(req)
	defer resp.Body.Close()
	body, _ := io.ReadAll(resp.Body)
	fmt.Println(string(body))
}
require "net/http"
require "json"

uri = URI("https://api.apis.guru/v2/specs/tfl.gov.uk/v1/Place")
uri.query = URI.encode_www_form({
  "type" => "json",
  "radius" => "1",
  "activeOnly" => "true",
  "categories" => "example",
  "placeGeo.lat" => "1",
  "placeGeo.lon" => "1",
  "placeGeo.neLat" => "1",
  "placeGeo.neLon" => "1",
  "placeGeo.swLat" => "1",
  "placeGeo.swLon" => "1",
  "includeChildren" => "true",
  "numberOfPlacesToReturn" => "1"
})

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == "https"

req = Net::HTTP::Get.new(uri)

res = http.request(req)
puts JSON.parse(res.body)
<?php
$url = "https://api.apis.guru/v2/specs/tfl.gov.uk/v1/Place?" . http_build_query([
    "type" => "json",
    "radius" => "1",
    "activeOnly" => "true",
    "categories" => "example",
    "placeGeo.lat" => "1",
    "placeGeo.lon" => "1",
    "placeGeo.neLat" => "1",
    "placeGeo.neLon" => "1",
    "placeGeo.swLat" => "1",
    "placeGeo.swLon" => "1",
    "includeChildren" => "true",
    "numberOfPlacesToReturn" => "1"
]);
$opts = ["http" => [
    "method" => "GET",
]];
$ctx = stream_context_create($opts);
$res = file_get_contents($url, false, $ctx);
print_r(json_decode($res, true));
GET Search the site for occurrences of the query string. The maximum number of results returned is equal to the maximum page size of 100. To return subsequent pages, use the paginated overload.

Search the site for occurrences of the query string. The maximum number of results returned is equal to the maximum page size of 100. To return subsequent pages, use the paginated overload.

https://api.apis.guru/v2/specs/tfl.gov.uk/v1/Search?query=test

Hover any highlighted part to learn what it does

curl -X GET "https://api.apis.guru/v2/specs/tfl.gov.uk/v1/Search?query=test"
import requests
params = {
    "query": "test"
}
response = requests.get(
    "https://api.apis.guru/v2/specs/tfl.gov.uk/v1/Search",
    params=params,
)
print(response.json())
const url = new URL('https://api.apis.guru/v2/specs/tfl.gov.uk/v1/Search');
url.searchParams.set('query', 'test');

const response = await fetch(url); 
const data = await response.json();
console.log(data);
package main

import (
	"fmt"
	"io"
	"net/http"
	"net/url"
)

func main() {
	baseURL, _ := url.Parse("https://api.apis.guru/v2/specs/tfl.gov.uk/v1/Search")
	q := baseURL.Query()
	q.Set("query", "test")
	baseURL.RawQuery = q.Encode()
	targetURL := baseURL.String()
	req, _ := http.NewRequest("GET", targetURL, nil)

	client := &http.Client{}
	resp, _ := client.Do(req)
	defer resp.Body.Close()
	body, _ := io.ReadAll(resp.Body)
	fmt.Println(string(body))
}
require "net/http"
require "json"

uri = URI("https://api.apis.guru/v2/specs/tfl.gov.uk/v1/Search")
uri.query = URI.encode_www_form({
  "query" => "test"
})

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == "https"

req = Net::HTTP::Get.new(uri)

res = http.request(req)
puts JSON.parse(res.body)
<?php
$url = "https://api.apis.guru/v2/specs/tfl.gov.uk/v1/Search?" . http_build_query([
    "query" => "test"
]);
$opts = ["http" => [
    "method" => "GET",
]];
$ctx = stream_context_create($opts);
$res = file_get_contents($url, false, $ctx);
print_r(json_decode($res, true));
GET Gets a list of StopPoints within {radius} by the specified criteria

Gets a list of StopPoints within {radius} by the specified criteria

https://api.apis.guru/v2/specs/tfl.gov.uk/v1/StopPoint?modes=example&radius=1&stopTypes=example&categories=example&returnLines=true&location.lat=1&location.lon=1&useStopPointHierarchy=true

Hover any highlighted part to learn what it does

curl -X GET "https://api.apis.guru/v2/specs/tfl.gov.uk/v1/StopPoint?modes=example&radius=1&stopTypes=example&categories=example&returnLines=true&location.lat=1&location.lon=1&useStopPointHierarchy=true"
import requests
params = {
    "modes": "example",
    "radius": "1",
    "stopTypes": "example",
    "categories": "example",
    "returnLines": "true",
    "location.lat": "1",
    "location.lon": "1",
    "useStopPointHierarchy": "true"
}
response = requests.get(
    "https://api.apis.guru/v2/specs/tfl.gov.uk/v1/StopPoint",
    params=params,
)
print(response.json())
const url = new URL('https://api.apis.guru/v2/specs/tfl.gov.uk/v1/StopPoint');
url.searchParams.set('modes', 'example');
url.searchParams.set('radius', '1');
url.searchParams.set('stopTypes', 'example');
url.searchParams.set('categories', 'example');
url.searchParams.set('returnLines', 'true');
url.searchParams.set('location.lat', '1');
url.searchParams.set('location.lon', '1');
url.searchParams.set('useStopPointHierarchy', 'true');

const response = await fetch(url); 
const data = await response.json();
console.log(data);
package main

import (
	"fmt"
	"io"
	"net/http"
	"net/url"
)

func main() {
	baseURL, _ := url.Parse("https://api.apis.guru/v2/specs/tfl.gov.uk/v1/StopPoint")
	q := baseURL.Query()
	q.Set("modes", "example")
	q.Set("radius", "1")
	q.Set("stopTypes", "example")
	q.Set("categories", "example")
	q.Set("returnLines", "true")
	q.Set("location.lat", "1")
	q.Set("location.lon", "1")
	q.Set("useStopPointHierarchy", "true")
	baseURL.RawQuery = q.Encode()
	targetURL := baseURL.String()
	req, _ := http.NewRequest("GET", targetURL, nil)

	client := &http.Client{}
	resp, _ := client.Do(req)
	defer resp.Body.Close()
	body, _ := io.ReadAll(resp.Body)
	fmt.Println(string(body))
}
require "net/http"
require "json"

uri = URI("https://api.apis.guru/v2/specs/tfl.gov.uk/v1/StopPoint")
uri.query = URI.encode_www_form({
  "modes" => "example",
  "radius" => "1",
  "stopTypes" => "example",
  "categories" => "example",
  "returnLines" => "true",
  "location.lat" => "1",
  "location.lon" => "1",
  "useStopPointHierarchy" => "true"
})

http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == "https"

req = Net::HTTP::Get.new(uri)

res = http.request(req)
puts JSON.parse(res.body)
<?php
$url = "https://api.apis.guru/v2/specs/tfl.gov.uk/v1/StopPoint?" . http_build_query([
    "modes" => "example",
    "radius" => "1",
    "stopTypes" => "example",
    "categories" => "example",
    "returnLines" => "true",
    "location.lat" => "1",
    "location.lon" => "1",
    "useStopPointHierarchy" => "true"
]);
$opts = ["http" => [
    "method" => "GET",
]];
$ctx = stream_context_create($opts);
$res = file_get_contents($url, false, $ctx);
print_r(json_decode($res, true));

Postman Setup Guide

Get Postman ↗
  1. See official documentation for authentication and setup.

What can you build with Transport for London Unified API?

Transport for London Unified API is a Data API. Developers commonly use data APIs for:

  • enriching your app with third-party datasets
  • building data pipelines and ETL workflows
  • querying and searching large datasets
  • powering research, analysis, and reporting tools
  • syncing reference data into your own systems

No authentication required. This API is open — no signup or key needed. Ideal for quick prototypes and public-facing features. Transport for London Unified API is free to use, making it a low-risk choice to experiment with.

New to APIs? Read our beginner's guide · Learn about API keys · What is REST?

Open documentation ↗