Huxley is a CORS enabled JSON REST proxy for the UK National Rail Enquires Live Departure Board SOAP API (Darwin).
If you want to be informed of updates when they are released then watch the project on GitHub and/or follow me on Twitter. You can also read about this and other projects on my blog.
SOAP is a pain to use (you have to POST specially crafted XML) so this proxy allows you to GET nicely formatted JSON instead (REST). It also adds CORS headers so you can access it with JavaScript from a different domain.
Huxley also has a built in CRS code lookup API so you can search for station names from your app. You can also use station names directly in any query. The codes are automatically kept up to date from the official sources.
In addition it has a function for calculating delays which allows you to build useful IoT devices like this LED strip delay indicator. You can specify specific trains and it even knows about London Terminals.
You can also use it to build mobile web apps such as InstaBail, which generates excuses based on real transport disruptions.
There is an example deployment set up here. (DO NOT USE THIS FOR ANYTHING SERIOUS!)
Paste this into your web console F12:
var r = new XMLHttpRequest();
r.open("GET", "https://huxley.apphb.com/all/stp/from/bxs/1?accessToken=DA1C7740-9DA0-11E4-80E6-A920340000B1", true);
r.onreadystatechange = function () {
if (r.readyState != 4 || r.status != 200) return;
var resp = JSON.parse(r.response);
if (resp.trainServices && resp.trainServices.length > 0) {
alert("The next train to arrive at " + resp.locationName + " from " + resp.filterLocationName + " will get in at " + resp.trainServices[0].sta);
} else {
alert("Sorry, no trains from " + resp.filterLocationName + " arriving soon");
}
};
r.send();
If you want to use this proxy then you should deploy the code to your own App Harbor or Azure account. If you deploy to the App Harbor Europe AWS region then this will run very close to the NRE servers.
SDKs in 9 languages (including Java, PHP, Python and Ruby) for this endpoint (generated with Swagger) are available here. If you use these make sure to change the endpoint for production.
There is an additional Python (v2) example for a Raspberry Pi and Blinky Tape RGB LED strip.
You will need to add your access token to the URL. You can register to obtain one here.
Append the accessToken={Your GUID token}
parameter to the query string for every request.
There is optional support for configuring the access token server side. So you don't need to worry about revealing it.
You can set DarwinAccessToken
to your NRE access token. If you leave ClientAccessToken
as an empty GUID then no token is required in the Huxley URL. If you set ClientAccessToken
to a random GUID and it matches the token in the URL then the DarwinAccessToken
will be used instead in the SOAP call. Otherwise the URL token is passed straight through. Look in the Web.config
file for more details.
N.B. You should set up these tokens in your deployment platform and not in your source code repository. You'll notice that the values are empty GUIDs by default. The example token used above will only work on the demo server and not directly against the SOAP API.
The URL format is {board}/{CRS|StationName}/{filterType}/{filterCRS|StationName}/{numRows}
or {board}/{CRS|StationName}/{numRows}
(arrivals/departures only) where only board and CRS (or a station name) are required. The filter type can be either to
or from
(case is not important).
A station name can be used in place of CRS codes if the name matches only one station (or matches one exactly) but case is not important. See the CRS section below for more information.
For all boards you can add an expand=true
parameter to embed all service details into the board response.
/all/{CRS|StationName}?accessToken={token}&expand=true
Examples:
- 10 (default value) Arrivals and Departures at Clapham Junction:
/all/clj
- 15 Arrivals and Departures at Clapham Junction:
/all/clj/15
- 10 (default value) Departures at Clapham Junction to Waterloo:
/departures/clj/to/wat
- 15 Arrivals at Clapham Junction from Waterloo:
/arrivals/clj/from/wat/15
- 10 (default value) Arrivals and Departures at Wandsworth Common to Clapham Junction:
/all/wandsworth common/to/clapham junction
- 20 Departures at East Croydon to London Victoria:
/departures/east croydon/to/london victoria/20
/departures/{CRS|StationName}/{filterType}/{filterCRS|StationName}
/arrivals/{CRS|StationName}/{filterType}/{filterCRS|StationName}
/all/{CRS|StationName}/{filterType}/{filterCRS|StationName}
/next/{CRS|StationName}/{filterType}/{filterCRSs|StationNames}
Filter stations can be a comma separated list. Filter type and number of rows are ignored.
/fastest/{CRS|StationName}/{filterType}/{filterCRSs|StationNames}
Filter stations can be a comma separated list. Filter type and number of rows are ignored.
/service/{Service ID}?accessToken={Your GUID token}
The service ID can be found for each service inside the departures and arrivals response.
This endpoint also accepts the GUID representation of the ID as /
, +
and case sensitivity can cause trouble if you're not careful.
More information on the wiki.
The delays action performs calculations server side to easily let you know if there are problems on a particular route.
[/delays/{CRS|StationName}/{filterType}/{filterCRS|StationName}/{numRows}?accessToken={Your GUID token}
](https://huxley.apphb.com/delays/clapham junction/from/london/20?accessToken=)
Sample Response:
{
"generatedAt": "2015-05-08T11:28:33.7187169+01:00",
"locationName": "Clapham Junction",
"crs": "CLJ",
"filterLocationName": "London",
"filtercrs": "LON",
"delays": true,
"totalTrainsDelayed": 1,
"totalDelayMinutes": 16,
"totalTrains": 12,
"delayedTrains": [
{
"origin": [
{
"locationName": "London Waterloo",
"crs": "WAT",
"via": null,
"futureChangeTo": null,
"assocIsCancelled": false
}
],
"destination": [
{
"locationName": "London Waterloo",
"crs": "WAT",
"via": null,
"futureChangeTo": null,
"assocIsCancelled": false
}
],
"currentOrigins": null,
"currentDestinations": null,
"sta": null,
"eta": null,
"std": "11:20",
"etd": "11:28",
"platform": "3",
"operator": "South West Trains",
"operatorCode": "SW",
"isCircularRoute": false,
"serviceID": "F4GbTDZuLjb4VlXEYDuakg==",
"adhocAlerts": null
}
]
}
This action will accept lon
or London
as a filter CRS to find trains going to or coming from any London terminal.
You can also pass in a comma separated list of 24 hour train times to filter on (e.g. /btn/to/lon/50/0729,0744,0748
).
CRS (Computer Reservation System) station codes are available from the following endpoint:
If query
is omitted then all CRS codes are returned along with their respective station names. If query
is provided then only station names matching it will be returned along with their CRS codes.
Example response for /crs/oswald
:
[
{
"stationName": "Church & Oswaldtwistle",
"crsCode": "CTW"
},
{
"stationName": "Lazonby & Kirkoswald",
"crsCode": "LZB"
}
]
To get your own instance of Huxley (on App Harbor or Azure) follow the instructions on the wiki.
Made by James Singleton
© 2016 James Singleton
This program is licensed under the terms of the GNU Affero General Public License. This means that you need to share any changes (even if only running on a public server).
If you would like another license (such as a commercial license with an invoice) then this can be provided. Please get in touch (send an email to jpsingleton at gmail dot com).
Contains public sector information licensed under the Open Government Licence v3.0.