Data structures
Headcode responses are designed around a small set of stable resource types. Each resource combines identifiers from upstream rail systems with normalised fields that are easier to use in applications.
Core concepts
Section titled “Core concepts”| Concept | What it represents | Common endpoints |
|---|---|---|
| Station | A passenger station or stop area, with all known rail and geography identifiers. | GET /v1/stations/{id}, GET /v1/stations |
| Station board | A station-centric list of upcoming departures or arrivals. | GET /v1/stations/{id}/departures, GET /v1/stations/{id}/arrivals |
| Combined board | Interleaved arrivals and departures for a station in a single response. | GET /v1/stations/{id}/board |
| Next departures | The next service(s) from an origin to one or more destination stations. | GET /v1/stations/{id}/next |
| Footfall | Historical entry and exit counts for a station. | GET /v1/stations/{id}/footfall |
| Service | A train running on a specific day, including schedule, live status, formation and associations. | GET /v1/services/{service_id} |
| Calling point | One scheduled location in a service’s journey. | Returned inside station boards and services |
| Train order | The order in which trains are expected to occupy or depart from a platform. | GET /v1/train-orders/{station_id} |
| Location | A non-station operational rail location such as a junction, siding or depot. | GET /v1/locations/{tiploc}, GET /v1/locations |
| Disruption | Customer-facing messages, train alerts and service disruption metadata. | GET /v1/disruptions, GET /v1/disruptions/{id} |
| Operator | A Train Operating Company (TOC) with its code and name. | GET /v1/operators, GET /v1/operators/{code} |
| Reason code | A delay or cancellation reason code with its human-readable description. | GET /v1/reference/reason-codes |
Station records
Section titled “Station records”A Station is the canonical identity object for a location. It includes the human-facing name and slug, plus the identifier systems used by different upstream datasets.
Important fields include:
crs: the three-letter customer-facing station code, such asKGX.slug: a stable, URL-friendly Headcode identifier, such aslondon-kings-cross.name: display name using British rail naming conventions.nlc,uic,atco: optional external location identifiers when known.tiplocs: one or more timetable locations associated with the station.stannox: Network Rail location identifiers associated with the station.platforms: known platform labels and details, such as length and power supply.links: transport links to other nearby stations.
Stations often have more than one TIPLOC or STANOX because operational systems model locations differently from passenger information systems. Headcode preserves these mappings so clients do not need to maintain their own lookup tables.
Station boards
Section titled “Station boards”A station board is a station-centric projection of service data. It answers questions like “what is leaving King’s Cross next?” rather than “what is the complete state of this train?”.
Board rows usually include:
- the service identifier, normally a Darwin RID;
- the scheduled public time at the requested station;
- the estimated or actual time when available;
- destination or origin summaries;
- platform information;
- cancellation or delay state;
- links to the full service resource.
Use station boards for departure screens, journey-planning entry points and lightweight live running views. Fetch the linked service when you need the full calling pattern, train formation or delay reasons.
Service records
Section titled “Service records”A Service represents one train on one scheduled operating date. The Darwin RID is the best identifier for live service lookup because it identifies a particular run, not just a repeating timetable pattern.
Important top-level fields include:
rid: Darwin Run ID for this day’s service.uid: CIF timetable UID.train_id: four-character headcode/signalling identity when available.rsid: Retail Service ID when available.ssd: scheduled start date.toc_code: train operating company code.is_passenger_service: whether the service is passenger carrying.is_active: whether the service is currently active in Darwin.calling_points: ordered journey locations with schedule and live status.associations: joins, splits and other relationships to services.formation: coach-level formation information when available.
Calling points and times
Section titled “Calling points and times”Calling points are ordered by sequence. Each point contains a TIPLOC and schedule information, with separate public and working times where the upstream data provides both.
Time fields are intentionally split by meaning:
public_arrivalandpublic_departure: advertised passenger times, usuallyHH:MM.working_arrival,working_departureandworking_pass: operational timetable times, usuallyHH:MM:SS.arrival,departureandpass: live status objects containing estimated, actual and delayed states.
The live TimeStatus object can contain:
estimated: customer-facing forecast time.working_estimated: operational forecast time.actual: actual time once reported.delayed:truewhen the service is delayed but no reliable time is available.
Prefer actual times over estimated times when both are present. If delayed is true and no estimate is present, show a delay message rather than inventing a time.
Platform information
Section titled “Platform information”Platform data is returned as a structured object so clients can distinguish the platform value from its confidence and display status.
platform: platform number or label.confirmed: whether the platform has been confirmed.suppressed: whether the platform should be hidden from public displays.source: upstream source type, for example planned, automatic or manual.
If suppressed is true, avoid showing the platform to passengers unless your use case is operational.
Associations
Section titled “Associations”Associations describe relationships between services. Common association categories include joins, splits and linked services. A service can have multiple associations, and each association may point to another RID or timetable UID.
Use associations to explain through services, portion working and cases where one train becomes or combines with another.
Formations and coaches
Section titled “Formations and coaches”Formation data describes the physical make-up of a train when available. It can include coach identifiers, class information and toilet details.
Formation availability varies by operator and upstream feed quality. Treat the formation object as optional and design passenger-facing experiences to degrade gracefully when it is missing.
Nullability and missing data
Section titled “Nullability and missing data”Rail data is assembled from systems with different coverage, refresh rates and data quality. Headcode uses explicit null values for optional fields that are known but unavailable in a response.
General guidance:
- Do not assume every station has every identifier.
- Do not assume every service has a headcode, RSID or formation.
- Do not assume every calling point has both public and working times.
- Treat arrays as empty when there are no known related records.
- Use the OpenAPI schemas as the source of truth for required fields.
Combined board
Section titled “Combined board”The combined board returns both arrivals and departures for a station in a single response. The response contains separate departures and arrivals arrays, each containing the same BoardService objects as the individual board endpoints.
Use the combined board when you need a unified view of station activity without making two separate requests.
Next departures
Section titled “Next departures”The next departures endpoint returns the soonest service(s) from an origin station to each of one or more destination stations. The response is a map keyed by the destination identifier you provided, where each value is an array of matching BoardService objects.
This is useful for “next train to…” displays, multi-destination information screens, or journey comparison views.
Footfall
Section titled “Footfall”Station footfall data provides historical entry and exit counts. The response contains an array of date-keyed records, each with count_in and count_out values.
Location records
Section titled “Location records”A Location represents a non-station operational rail location — junctions, sidings, depots, signal boxes and timing points that appear in movement data and service calling patterns but are not passenger stations.
Important fields include:
tiploc: the TIPLOC code identifying this location.name: display name.location_type: the kind of location, such asjunction,siding,depot,signal_boxortiming_point.latitudeandlongitude: geographic coordinates when known.
Locations explain calling points in a service journey that are not passenger stations. If a service’s calling pattern includes a TIPLOC that is not a station, the Locations API provides context for it.
Operator records
Section titled “Operator records”An Operator represents a Train Operating Company. The toc_code field returned in service and board data maps to an operator’s two-character code. Use the Operators API to resolve codes to full operator names.
Reason codes
Section titled “Reason codes”Reason codes provide human-readable descriptions for delay and cancellation reasons. When a service includes a cancel_reason or late_reason, the numeric code can be resolved via the Reason Codes API to explain the cause to passengers.
Choosing the right structure
Section titled “Choosing the right structure”- Use
Stationwhen you need identity, search, geography or identifier resolution. - Use
StationBoardwhen you need the next trains at a location. - Use the combined board when you need both arrivals and departures in one request.
- Use next departures when you need the soonest train(s) to specific destinations.
- Use
Servicewhen you need the full journey and live running state for one train. - Use train order when display order at a platform matters more than full journey detail.
- Use disruptions when you need customer-facing incidents, messages and alerts.
- Use locations when you need context for non-station TIPLOCs in calling patterns.
- Use operators and reason codes to enrich service data with human-readable names and explanations.