Internal API
This API is designed for internal use within Network Rail. It uses a simple authentication mechanism that does not link to a specific "user" within the system. It was created in response to a request to report into Power BI.
Base URL
https://nrsdb.uk/api/v1
Authentication
Registered users of the API will be issued with a key - all requests (other than this help URL) must pass this key as a Bearer token
Sample Code
Sample GET request
const params = new URLSearchParams();
params.append('property', value);
const response = await fetch(`${url}?${params}`, {
'credentials': 'same-origin',
'headers': {
'Authorization': `Bearer ${token}`
'Accept': 'application/json',
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
},
'method': 'GET'
});
Sample POST from a form element
const response = await fetch(url, {
'body': formData,
'credentials': 'same-origin',
'headers': {
'Authorization': `Bearer ${token}`
},
'method': 'POST'
});
NOTE: in my experience it is best not to set the 'Content-Type' header here
Endpoints
Routes
E.g. Anglia, North-West, Wales
/routes - return all Routes
/route/{routeId} - detail of a specific route
Delivery Units
/dus - return all Delivery Units
/dus/route/{routeId} - return Delivery Units on a given route
/du/1 - get details for a specific DU
Sample Return JSON
{
"data": {
"id": 1,
"name": "Ipswich",
"routeId": 2,
"active": true
}
}
ELRs
/elrs - returns all of the ELRs known to the system
/elr/{elrId} - returns the details for a specific ELR
Locations
/locations/{elrId}
Returns the significant locations along a given ELR, with Miles + Yards location and a GeoJSON marker if available
NOTE: data set is too large to return for the entire railway
NOTE: this is different to the Autumn Inspection locations (see below)
Autumn Inspections
/autumn/locations/{routeId} - return all Locations to be inspected on the given route
/autumn/inspections - returns all of the inspections
/autumn/inspections/route/{routeId} - returns all inspections for a given route
Inspection Example Data
{
"id": 33,
"inspectionDate": "2025-06-09T23:55:39+01:00",
"locationId": 236,
"location": {
"id": 236,
"location": "Falconwood",
"locationClass": "Platform",
"routeId": 8,
"ownerId": 33,
"elrId": 81,
"trackId": 1100,
"track": "",
"start": 827,
"end": 827,
"frequency": 1,
"active": true,
"inspections": []
},
"inspectorId": 3,
"inspector": null,
"weather": {
"precipitation": 3,
"wind": 2,
"overhead": 2,
"ground": 2
},
"rail_condition": "dry",
"evaluation": 0,
"action_taken": "",
"comments": "",
"images": []
}
ESRs
/esrs - returns all known ESRs
/esrs/route/{routeId} - returns ESRs for a given route
NOTE: check this!
ESR Data Structure
- refnum (string) - this is made up of a route specific prefix, a three digit incremental counter, plus the two digit year
- original_refnumspeed (string)object) - this"Freight givesSpeed / Passenger Speed" - single number if both are same, units and unrestricted line speed
- route (object) - all properties of the - routenamedu (string)object) - long name for the Route
- elrcodeelr (string)object) - ELR of track segment impacted e.g. LTN1
- elrdescriptionlor (string)object) - full description of the ELR e.g. "LIVERPOOL STREET - TROWSE LOWER JN"
- location (string) - description of where the restriction is applied
- reason (string)object) - describes reason the ESR is imposed
- withdrawn (bool) - 0 = active, 1 = withdrawn
- whenimposed (string) - W3C format date time stringstring, updated during amendment
- etc (null|string) - if set this is a W3C format date time string
- whenwithdrawn (null|string) - if withdrawn === 1, W3C format date time string
- linelines (array) - detailsobject for each "line". A "line" is the combination of theELR Primary+ LineTrackID
- elrIdelr (object) - internal ID, not useful - Primary Line is always on the ELR as given above
- trackId (int) - e.g. 1100 = Up Main
- direction (string) - "Up Direction" | "Down Direction" (yuk)
- linedescription (string) - can be driven by trackId or overridden by Controller
- routeheader (string) - "Primary Line" | "Additional Line"
- boards (array)
- type (string) - short name (no spaces)
- description (string) - long name
- elrId (int) - copied from line
- trackId (int) - copied from line
- miles (int) -
- chains (int) - 0 >= X < 80
- serialNumber (string) - not currently used
- marker (GeoJSON)
- references (object)
- updated_at - time of last database change
Example
{
"id": 5,
"refnum": "AICC 008A.22"001.26",
"original_refnum"speed": {
"value": "AICC40",
008.22""unit": "mph",
"linespeed": "120"
},
"route": {
"id": 2,
"routecode": "EA",
"routename": "Anglia",
"deliveryunit"shortname": "AICC",
"active": true
},
"du": {
"id": 1,
"name": "Ipswich",
"elr"routeId": 255,2,
"elrcode"active": "COC"true
},
"elrdescription": "Colchester to Clacton",
"lorId": 1
"location": "Between here and there",
"reason": "Track - Cyclic Top",
"speed": "30/60",
"withdrawn": 0,
"whenimposed": "2022-09-02 13:53:09",
"etr": null,
"whenwithdrawn": null,
"line"elr": {
"elrId": 255,668,
"elrcode": "LTN1",
"elrdescription": "LIVERPOOL STREET - TROWSE LOWER JN",
"active": true
},
"lor": {
"id": 2,
"lorcode": "EA1011",
"lordescription": "SEVEN KINGS TO IPSWICH",
"active": true
},
"location": "At Colchester South Jn",
"reason": {
"id": 18,
"reason": "Structural - Station",
"active": true
},
"lines": [
{
"elr": {
"elrId": 668,
"elrcode": "LTN1",
"elrdescription": "LIVERPOOL STREET - TROWSE LOWER JN",
"active": true
},
"trackId": 1100,
"routeheader": "Primary Line",
"direction": "Up Direction",
"linedescription": "Up Main",
"routeheader"newStyleBoards": "Primary Line",true,
"boards": [
{
"type": "commencement",
"description": "CommencementSpeed Board"Indicator (Commencement)",
"elrId": 255,668,
"trackId": 1100,
"miles": 1,50,
"chains": 42,75,
"serialNumber": null,
"marker": {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
0.876876605,
51.90208042
]
},
"properties": {
"type": "commencement",
"description": "Speed Indicator (Commencement)",
"elrId": 668,
"trackId": 1100,
"miles": 50,
"chains": 75,
"serialNumber": null
}
}
},
{
"type": "termination",
"description": "Termination"Termination Indicator",
"elrId": 255,668,
"trackId": 1100,
"miles": 0,49,
"chains": 37,75,
"serialNumber": null,
"marker": {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [
0.85427535,
51.89894058
]
},
"properties": {
"type": "termination",
"description": "Termination Indicator",
"elrId": 668,
"trackId": 1100,
"miles": 49,
"chains": 75,
"serialNumber": null
}
}
}
]
}
],
"speed"whenimposed": "30/60"2026-03-18 11:42:06",
"etr": null,
"withdrawn": false,
"whenwithdrawn": null,
"references": {
"fmsnumber": "123",
"ccilnumber": "23645657",
"tsrreference": "",
"tdanumber": "",
"wo": "",
"rdms": "",
"trustcode": "",
"owner": ""
},
"updated_at": "2026-03-18 11:42:06"
}
ErrorsError Handling
We return appropriate HTTP response codes whenever an error is encountered
400 Bad Request
If the URL parameter "r" is missing
This is returned if the given signature is invalid or lapsed. A signature is valid for only 5 mins so should be generated for each request
501 Not Implemented
This is returned if "r" is supplied but is not a valid endpoint
Others
Internal errors, for example unable to contact the database or failure to encode JSON will return "400 Bad Request" unless there's a specific HTTP response associated with the error
Help
This help filedocumentation can also be found at https://nrsdb.uk/api/v1/help -- no authentication is required
Power BI
To access this data using Power BI;
- click Get Data / Blank Query
- enter something like = Json.Document(Web.Contents("https://training.nrsdb.uk" & "/api/v1" & "/dus/1", [Headers=[Authorization="Bearer YOUR_KEY"]]))