Alpha — Headcode is currently in alpha. APIs and data may change without notice.

Twelve raw feeds.
One station identity.
One call.

Headcode reconciles, normalises and enriches the open UK rail feeds — Darwin, Network Rail Open Data, NaPTAN, ORR, the Rail Data Marketplace and the rest — so you integrate once. Start with whatever station code you have, get back all of them, plus live running data a single feed never carries.

The problem

The integration tax nobody quotes you for

The raw data is free. That is the trap. CRS for the fares system, TIPLOC for the timetable, STANOX for movements, plus NLC, ATCO and UIC — every feed names the same station differently, and a big terminus like London Bridge answers to a whole cluster of TIPLOCs across its platforms. Darwin arrives as a push port; reference data from the Rail Data Marketplace, Network Rail and NaPTAN turns up on its own cadence in its own shape. Before you render a single departure board you have written a reconciliation layer, a code-mapping table and a normaliser — and you now own all of it. Headcode is that layer, run as a service, with British English schemas and metric units throughout.

Without Headcode

Rail Data MarketplaceDarwin push portNetwork Rail Open DataNaPTANORRCIF schedulesTIPLOC / STANOX maps
KGXKNGX543116121009100KNGX

With Headcode

GET /v1/stations/KGX

One station object, every known identifier resolved, live and planned data already joined. The reconciliation layer becomes a field you read.

  • No code-mapping table to maintain
  • No feed cadences to babysit
  • No bespoke normaliser to debug at 07:00

One request

Every identifier, plus the live running data

Ask King's Cross for the next departures to York and Edinburgh in a single call. Send the CRS code you already have; Headcode resolves the station across every code system and answers grouped by destination, with scheduled and live-estimated times blended from the timetable and Darwin. No second call to a different feed to find out the train is two minutes down.

curl https://api.headcode.dev/v1/stations/KGX/next?destinations=YRK,EDB \
  -H "Authorization: Bearer hc_…"
{
  "destinations": {
    "YRK": [
      {
        "rid": "202605141A45",
        "uid": "C12345",
        "toc_code": "GR",
        "scheduled_public": "10:03",
        "estimated": "10:05"
      }
    ],
    "EDB": [  ]
  }
}

GET /v1/stations/{id}/next — requires the boards:read scope, on every plan including Free.

  • rid + uid

    Look the full service up via /v1/services/{service_id} — calling points, formation, live status.

  • toc_code

    Resolves to the operating company through /v1/operators reference data.

  • estimated vs scheduled_public

    Estimated is live from Darwin; the scheduled public time stays put. Both arrive in one response.

Identifier resolution

Bring any code. Get every code back.

Identifiers are forgiving by design. Pass a CRS, TIPLOC, STANOX, NLC, ATCO, UIC or a Headcode slug — any of them resolves the same station, and the response hands back every known identifier for it, so the mapping table you used to maintain becomes a field you read. Operational points that are not stations — junctions, sidings and depots — are reachable too, via Locations.

Send any one of these:

GET /v1/stations/KGX the same station, every time.

London King's Cross
CRSKGX
TIPLOCKNGX
STANOX54311
NLC612100
ATCO9100KNGX
UIC61210
sluglondon-kings-cross

Single-station lookup: GET /v1/stations/{id}. Fuzzy text and lat/lng radius search on GET /v1/stations. Identifiers shown are King's Cross's real reference codes.

What you can build on day one

Live in the API today, documented with OpenAPI

A raw feed answers one narrow question; a Headcode response answers the question you actually had — already joined, already normalised. Built for passenger-info, journey, logistics, proptech and analytics teams. Every product ships a downloadable spec; access is enforced per scope on your key.

Live and historic

The same shape, today or last spring

Today's 10:03 to York and the same departure from a Tuesday last year come back in the same shape. From Pro, a 13-month lookback serves the board, departures and arrivals for any past day through dedicated history endpoints — same fields, same identifiers — so a backfill and a live view share code. Two analytics products sit alongside as add-ons.

Historical data

Board, departures and arrivals for a past day, on dedicated history endpoints — not a date param bolted onto the live board.

GET /v1/stations/{id}/history/board · /departures · /arrivals scope: history:read · Pro and up

Analytics add-ons

Performance reads aggregate punctuality from pre-computed daily rollups. Footfall is station passenger-flow data. Each grants a scope without changing your request limits.

Performance +£49/mo · Footfall +£69/mo scopes: performance:read · footfall:read · Pro and up

Plans

Start free, and stay legible

Free is a real working tier for evaluation and small projects. Starter covers most production apps on live data and adds Darwin operations. Pro adds the 13-month history and production volume, and is where Performance and Footfall become available. Limits are per account — every key shares the same daily and burst budget.

Free
Free
  • 100 requests/day
  • 2 req/s burst
  • 2 API keys
  • Boards, services, train order, disruptions, reference
Request access
Most production apps
Starter
£29/month
  • 10,000 requests/day
  • 10 req/s burst
  • 5 API keys
  • Everything in Free, plus Darwin operations
Request access
History + analytics
Pro
£149/month
  • 100,000 requests/day
  • 50 req/s burst
  • 25 API keys
  • Adds 13-month history; Performance + Footfall available
Request access
Enterprise
Custom
  • Reserved throughput above 50 req/s
  • Contractual SLA
  • Custom keys & volume
  • Bespoke data arrangements
Talk to us
What each plan unlocks
CapabilityScopeFreeStarterProEnt.
Live station boardsboards:read
Reference data (stations, operators, reason codes, locations)reference:read
Service lookupservices:read
Train ordertrain-order:read
Disruptionsdisruptions:read
Darwin operations (heartbeat, alarms)operations:read
Historical data (13-month lookback)history:read
Performance analyticsperformance:readAdd-on
Footfallfootfall:readAdd-on
Throughput M
Raise burst to 25 req/s
+£15/month
Throughput L
Raise burst to 50 req/s
+£35/month
Volume M
+25,000 requests/day
+£10/month
Volume L
+50,000 requests/day
+£18/month
Performance analytics
Aggregate punctuality metrics
+£49/month
Footfall
Station passenger-flow data
+£69/month

Self-serve purchasing isn't live yet — to add a pack or enable analytics while billing is being built, email [email protected] and access can be adjusted on your key. Add-on prices are indicative and may change before launch.

OpenAPI-first

Your tooling already knows the shape

Every product ships a versioned, downloadable specification you can point a client generator, mock server or contract tests at — the schema is the contract, in British English. Eight products are live today; the guides explain the concepts behind them, this page is the short version.

Base URLhttps://api.headcode.dev
AuthAuthorization: Bearer hc_…

Browse the full API reference →

Request access

Tell us what you're building

Headcode is in active development and there is no self-serve signup yet, so access is by request — which also means you can ask for exactly the scopes and headroom your build needs. A Free key is enough to integrate against. Email us with your use-case and the station codes you're starting from, and we'll send a token.

No card to start Free tier is genuinely useful British English · metric · OpenAPI-first