Integration Guide

How to work with the Trackser Live API

Access status: Trackser Live currently serves the Trackser app exclusively. API keys are not issued publicly at this time. If you have a project that would benefit from this data, get in touch — if there's sufficient demand, external access is something we'd consider.

Authentication

All API requests require an API key. Pass it as a header or a query parameter:

# As a header (preferred)
GET /live/central/line/latest.json
X-API-Key: YOUR_API_KEY

# As a query parameter
GET /live/central/line/latest.json?key=YOUR_API_KEY

Keep your key out of source control. Use environment variables.

Making requests

Live data endpoints serve pre-built snapshots from Cloudflare R2. Responses are typically returned in under 100ms. All responses include Access-Control-Allow-Origin: * — you can call these endpoints from a browser without a proxy.

JavaScript / Node.js

const API_KEY = process.env.TRACKSER_API_KEY;
const LINE_ID = 'central';

const response = await fetch(
  `${BASEURL}/live/${LINE_ID}/line/latest.json`,
  { headers: { 'X-API-Key': API_KEY } }
);
const data = await response.json();

console.log(`${data.trains.length} trains on the ${LINE_ID} line`);
console.log(`Data as of: ${data.as_of}`);

// Find stalled trains
const stalled = data.trains.filter(t => t.isMaybeStalled);
console.log(`Potentially stalled: ${stalled.length}`);

Python

import requests
import os

API_KEY = os.environ['TRACKSER_API_KEY']
LINE_ID = 'northern'

response = requests.get(
    f'{BASEURL}/live/{LINE_ID}/line/latest.json',
    headers={'X-API-Key': API_KEY}
)
data = response.json()

print(f"Data as of: {data['as_of']}")
print(f"Total trains: {len(data['trains'])}")

# Find trains heading northbound
northbound = [t for t in data['trains'] if t.get('direction') == 'Northbound']
print(f"Northbound: {len(northbound)}")

cURL

# Train count on the Jubilee line
curl -s "${BASEURL}/live/jubilee/line/latest.json" \
  -H "X-API-Key: YOUR_KEY" | jq '.trains | length'

# Stats-only (lightweight health check)
curl -s "${BASEURL}/live/metropolitan/line/latest-stats.json" \
  -H "X-API-Key: YOUR_KEY" | jq '{trainCount: .stats.trainCount, as_of: .as_of}'

Handling gzip

The /latest.json endpoints serve gzip-compressed responses. Most HTTP clients decompress automatically when you send Accept-Encoding: gzip — the Fetch API, requests, and curl all do this by default.

If your client can't handle gzip, use the /latest-plain.json variants. These are identical in content but served uncompressed.

Data freshness

Each response includes an as_of ISO 8601 timestamp. Snapshots are built every minute. Under normal conditions, data will be 0–90 seconds old when you receive it.

Always check as_of before acting on data. If it's more than two minutes in the past, check the status page — TfL's upstream feed may be degraded.

Line IDs

metropolitan  chiltern  bakerloo  central  circle  district
hammersmith-city  jubilee  northern  piccadilly  victoria  waterloo-city

Response structure

{
  "as_of": "2026-03-22T09:43:00.000Z",
  "status": "ok",
  "sources": {
    "unified": "ok",
    "trackernet": "ok"
  },
  "stats": {
    "buildTimeMs": 1240,
    "trainCount": 38,
    "trkReceived": 42,
    "trkExpected": 42
  },
  "trains": [ ... ]
}

Error responses

Status Meaning Action
401 Unauthorized — missing or invalid API key Check your key and how you're sending it
404 Not found — invalid line ID or endpoint path Check the API reference for valid paths
429 Rate limit exceeded Back off and retry with exponential backoff
503 Service unavailable TfL upstream issue. Check status and retry.

Best practices

  • Poll, don't hammer. Data is updated once per minute — polling more frequently wastes requests without gaining freshness.
  • Use stats endpoints for health checks. /latest-stats.json is a fraction of the size of the full snapshot.
  • Verify as_of. A 200 response doesn't guarantee the data is current — check the timestamp.
  • Implement exponential backoff. On 429 or 503, wait and retry with increasing delays.
  • Never hardcode API keys. Use environment variables or secrets management.
  • Prefer the X-API-Key header over the query parameter — it won't appear in server logs or browser history.

Support

For technical questions, integration queries, or to discuss data access: support@curiosity175.co.uk