TLS 1.1 or higher is required to access the API. If you’re developing an application, and SSL handshake errors occur, you need to use a newer security protocol. HTTPS is supported over TLS1.1 and higher. SSL, SSL2, SSL3 and TLS1.0 are disabled as those protocols are considered unsafe.

If you build an application on top of the iRail api, be sure to do at least one of the following things:

If possible, set the user-agent header string. Include the name of your application, and a way to contact you in case something would go wrong. An example user agent string format is <application name>/<application version> (<website>; <mail>), which could result in the following string: irail/1.2.0 (irail.be; hello@irail.be). The use of a user agent string like this isn’t obligated or enforced, but allows for better communication.

If you can’t set the user agent string, at least be sure to follow us on github, website or gitter.

You can make up to 3 requests per second per source IP address. Every IP address also has 5 burst requests, meaning you can either have 8 requests
in 1 second or 15 requests in 3 seconds, but you will need to drop below 3 requests per second in order for these burst requests to refill.

Exceeding the request limit will cause the server to return 503 responses.

Request limits are set so everyone can enjoy open transport data with high availability and fast response times. Please don’t use excessive polling: always optimise your application, even when you’re not reaching our request limitations (yet). We include HTTP headers to signal how long our data is valid, please refrain from making the same request again before this period has elapsed.

Are you limited by our request limits? Get in touch to see if we can work out a better request strategy together.

Always undertake action when your application receives frequent “503 Too Many Requests” responses!
When your application causes too much requests, one of the following actions will happen

When the user agent is set, we will contact the developers at the provided e-mail address or website. In case of excessive requests for a long period of time (e.g. multiple 503 responses per second for more than 3 hours), your application might be blocked before we receive a response. We will still contact you to assist with resolving the issue and increasing the efficiency of your requests.

When no user agent is set, the source IP address will be blocked without prior warnings. If your IP address is blocked, please contact the iRail team to resolve this.

The iRail API uses URIs (Uniform Resource Identifications) to identify departures, stations, trains and occupancies. This way, there can be no misinterpretations. While there might be multiple meanings or interpretations possible for “Brussels South” (for example, the railway station, the airport, maybe the region south of Brussels), the URI http://irail.be/stations/NMBS/008814001 means the railway station Brussels south, and nothing else. The meaning of this URI doesn’t change on other websites, APIs, or datasets. URIs don’t change often, and don’t have to be human readable. They can change however, therefore they shouldn’t be composed by the user, but should be retrieved from a previous response.

URI’s are ids, just like numeric ids. While in this case they represent a URL, these URLs do not make part of the API! All API requests go to https://api.irail.be! Ids can be used on any domain, but if the id is the same url, you know that the objects represent the same thing, even if they are in different APIs or applications.

The API supports caching and conditional get requests. Conditional get requests allow you to tell the server which version of the data you have. If there is newer data available, the server will return an HTTP 200 status code along with the new data. If no new data is available, the server will return an HTTP 304 Not Modified status code, along with an empty body.
The benefits of caching are less data transfer, and faster responses in case of a 304 response.

Trying to query data way in the past, or way in the future, might result in error 500 responses. If you’re not sure what causes an error 500 response, be sure to check if your query works for the current day, or if the NMBS website has the data for the date you want to look up.

Retrieve a liveboard

A liveboard for a specified station. This includes departures or arrivals, along with their delays, train ids, occupancy, …

URI Parameters

HideShow

station

string(required)Example: Gent-Sint-Pieters

The name of the station to query.

id

string(optional)Example: BE.NMBS.008892007

If you know the id of a station, this might be used instead of a name. Do not use an id and a name at the same time.

arrdep

string(optional)Default: departureExample: departure

Whether the results should show arrivals departures in the station.

Choices: departurearrival

alerts

boolean(optional)Example: false

Wether or not to include alerts about a train in the response. This could be railworks etc, announced on the NMBS website.

fast

boolean(optional)Default: falseExample: false

(Deprecated) Whether or not you want stations in the result to be matched with an id and name according to iRail/Stations.
By enabling the fast feature, there won’t be any matching between station names returned by the NMBS and our database. This results in responses which are a little bit faster. Note: due to server-side optimizations this performance difference is now insignificant. This means there might be differences between the station name in the response and any station name your software knows. Fast is disabled by default, to ensure all stations in the response are matched with an id and a consistent name.

Left and Arrived attributes for resp. connection departures and arrivals

Alerts are now available in the following ways:

connection: These are all alerts for this connection object. Each alert is unique.

departure, via departure: These are the alerts for the train which departed
Even though this might duplicate data, this allows anyone to process it easily. Thanks to gzip compression this won’t affect the transferred data size.

Trying to query data way in the past, or way in the future, might result in error 500 responses. If you’re not sure what causes an error 500 response, be sure to check if your query works for the current day, or if the NMBS website has the data for the date you want to look up.

In some cases, there might be a walking part in a route. This happens for example when a user arrives in Haren-Zuid and has a next train in Haren, only a few hundred meters further.

For walking parts, don’t attempt to parse train ids or destinations.

Don’t exclude routes which contain walking parts by default, but feel free to give users the option to do so. For example the route Aarschot-Meiser has a small walking part, whereas avoiding that walking part will cause the user to arrive significantly earlier or later.

Walking parts won’t be the first or last part of a route. They can only occur between vias.

Headers

Headers

Body

<connectionsversion="1.1"timestamp="1506352987"><connectionid="0"><departuredelay="0"canceled="0"walking="0"left="0"><stationid="BE.NMBS.008892007"locationX="3.710675"locationY="51.035896"URI="http://irail.be/stations/NMBS/008892007"standardname="Gent-Sint-Pieters">Ghent-Sint-Pieters</station><timeformatted="2017-09-25T13:40:00">1506339600</time><vehicle>BE.NMBS.IC1512</vehicle><platformnormal="1">11</platform><direction>Genk</direction><departureConnection>http://irail.be/connections/8892007/20170925/IC1512</departureConnection><occupancyURI="http://api.irail.be/terms/unknown">unknown</occupancy><alertsnumber="1"><alertid="0"><header><![CDATA[L 50: We are conducting work for you between Aalst and Aalst.]]></header><description><![CDATA[We are conducting work for you between Aalst and Aalst. Detailed information only available in French (FR) and in Dutch (NL).]]></description><lead>We are conducting work for you between Aalst and Aalst.</lead><link><![CDATA[http%3A%2F%2Fwww.belgianrail.be%2Fjp%2Fdownload%2Fbrail_him%2F1509444366969_NL-11015.pdf]]></link><startTimeformatted="2017-10-31T10:17:00">1509441420</startTime><endTimeformatted="2017-11-12T23:59:00">1510527540</endTime></alert></alerts></departure><arrivaldelay="420"canceled="0"walking="0"arrived="0"><stationid="BE.NMBS.008832375"locationX="5.350226"locationY="50.954841"URI="http://irail.be/stations/NMBS/008832375"standardname="Kiewit">Kiewit</station><timeformatted="2017-09-25T15:42:00">1506346920</time><vehicle>BE.NMBS.IC1512</vehicle><platformnormal="1">2</platform><direction>Genk</direction></arrival><alertsnumber="1"><alertid="0"><header><![CDATA[L 50: We are conducting work for you between Aalst and Aalst.]]></header><description><![CDATA[We are conducting work for you between Aalst and Aalst. Detailed information only available in French (FR) and in Dutch (NL).]]></description><lead>We are conducting work for you between Aalst and Aalst.</lead><link><![CDATA[http%3A%2F%2Fwww.belgianrail.be%2Fjp%2Fdownload%2Fbrail_him%2F1509444366969_NL-11015.pdf]]></link><startTimeformatted="2017-10-31T10:17:00">1509441420</startTime><endTimeformatted="2017-11-12T23:59:00">1510527540</endTime></alert></alerts><duration>7320</duration><occupancyURI="http://api.irail.be/terms/unknown">unknown</occupancy></connection><connectionid="1"><departuredelay="60"canceled="0"walking="0"left="0"><stationid="BE.NMBS.008892007"locationX="3.710675"locationY="51.035896"URI="http://irail.be/stations/NMBS/008892007"standardname="Gent-Sint-Pieters">Ghent-Sint-Pieters</station><timeformatted="2017-09-25T13:40:00">1506339600</time><vehicle>BE.NMBS.IC2213</vehicle><platformnormal="1">6</platform><direction>Tongeren</direction><departureConnection>http://irail.be/connections/8892007/20170925/IC2213</departureConnection><occupancyURI="http://api.irail.be/terms/unknown">unknown</occupancy></departure><arrivaldelay="0"canceled="0"walking="0"arrived="0"><stationid="BE.NMBS.008832375"locationX="5.350226"locationY="50.954841"URI="http://irail.be/stations/NMBS/008832375"standardname="Kiewit">Kiewit</station><timeformatted="2017-09-25T16:24:00">1506349440</time><vehicle>BE.NMBS.P2366</vehicle><platformnormal="1">2</platform><direction>Genk</direction></arrival><duration>9840</duration><viasnumber="1"><viaid="0"><arrivaldelay="120"canceled="0"walking="0"arrived="0"><timeformatted="2017-09-25T15:49:00">1506347340</time><platformnormal="1">2</platform><direction>Tongeren</direction><vehicle>BE.NMBS.IC2213</vehicle><departureConnection>http://irail.be/connections/8831005/20170925/IC2213</departureConnection></arrival><departuredelay="60"canceled="0"walking="0"left="0"><timeformatted="2017-09-25T16:16:00">1506348960</time><platformnormal="1">8</platform><direction>Genk</direction><vehicle>BE.NMBS.P2366</vehicle><departureConnection>http://irail.be/connections/8831005/20170925/P2366</departureConnection><occupancyURI="http://api.irail.be/terms/unknown">unknown</occupancy></departure><timeBetween>1620</timeBetween><stationid="BE.NMBS.008831005"locationX="5.327627"locationY="50.930822"URI="http://irail.be/stations/NMBS/008831005"standardname="Hasselt">Hasselt</station><vehicle>BE.NMBS.IC2213</vehicle><direction>Tongeren</direction></via></vias><occupancyURI="http://api.irail.be/terms/unknown">unknown</occupancy></connection></connections>

Headers

Content-Type: application/xml

Body

<error code="404">Could not match "samplestation"with a station id in iRail. Please report this issue at https://github.com/irail/stations/issues/new if you think we should support your query.</error>

(Deprecated) Wether or not to include alerts about a route in the response. This could be railworks etc, announced on the NMBS website. Note: alerts are now always included

results

number(optional)Example: 6

(Deprecated) The number of results to return. Default value is 6. This might be used as a guideline for the server, but there is no guarantee the server will return this exact amount of results!

time

string(optional)Default: current time in BelgiumExample: 1230

The time to query.

The time is formatted as hhmm.

date

string(optional)Default: current date in BelgiumExample: 300917

The date to query.

The date is formatted as ddmmyy.

fast

boolean(optional)Default: falseExample: false

(Deprecated) Whether or not you want stations in the result to be matched with an id and name according to iRail/Stations.
By enabling the fast feature, there won’t be any matching between station names returned by the NMBS and our database. This results in responses which are a little bit faster. Note: due to server-side optimizations this performance difference is now insignificant. This means there might be differences between the station name in the response and any station name your software knows. Fast is disabled by default, to ensure all stations in the response are matched with an id and a consistent name.

Trying to query data way in the past, or way in the future, might result in error 500 responses. If you’re not sure what causes an error 500 response, be sure to check if your query works for the current day, or if the NMBS website has the data for the date you want to look up.

Headers

Body

Retrieve a vehicle

Retrieve information about a vehicle (train), including stops, occupancy, current location and delays.

URI Parameters

HideShow

id

string(required)Example: BE.NMBS.IC1832

date

string(optional)Default: current date in BelgiumExample: 300917

The date to query.

The date is formatted as ddmmyy.

alerts

boolean(optional)Example: false

Wether or not to include alerts about a train in the response. This could be railworks etc, announced on the NMBS website.

format

string(optional)Default: xmlExample: json

The response format

Choices: xmljsonjsonp

lang

string(optional)Default: enExample: en

The language of any text or names in the response.

Choices: nlfrende

fast

boolean(optional)Default: falseExample: false

(Deprecated) Whether or not you want stations in the result to be matched with an id and name according to iRail/Stations.
By enabling the fast feature, there won’t be any matching between station names returned by the NMBS and our database. This results in responses which are a little bit faster. Note: due to server-side optimizations this performance difference is now insignificant. This means there might be differences between the station name in the response and any station name your software knows. Fast is disabled by default, to ensure all stations in the response are matched with an id and a consistent name.

Headers

Headers

Body

<disturbancesversion="1.1"timestamp="1509444584"><disturbanceid="0"><title>Kalmthout: Freight train broken down.</title><description><![CDATA[Situation back to normal.]]></description><link><![CDATA[http://www.belgianrail.be/jp/sncb-nmbs-routeplanner/help.exe/en?tpl=showmap_external&tplParamHimMsgInfoGroup=trouble&message ID=23851&channelFilter=custom2,livemap,rss_line_10,twitter,custom1,timetable&]]></link><timestamp>1509443931</timestamp></disturbance><disturbanceid="1"><title>Balegem-Dorp: Intervention emergency services (112).</title><description><![CDATA[Situation back to normal.]]></description><link><![CDATA[http://www.belgianrail.be/jp/sncb-nmbs-routeplanner/help.exe/en?tpl=showmap_external&tplParamHimMsgInfoGroup=trouble&message ID=23854&channelFilter=custom2,livemap,rss_line_10,twitter,custom1,timetable&]]></link><timestamp>1509443873</timestamp></disturbance><disturbanceid="2"><title>Landen - Waremme: Signal failure.</title><description><![CDATA[Delayed train traffic. Disruption for an undetermined amount of time. Listen to the announcements in the train station.]]></description><link><![CDATA[http://www.belgianrail.be/jp/sncb-nmbs-routeplanner/help.exe/en?tpl=showmap_external&tplParamHimMsgInfoGroup=trouble&message ID=23853&channelFilter=custom2,livemap,rss_line_10,twitter,custom1,timetable&]]></link><timestamp>1509442854</timestamp></disturbance><disturbanceid="3"><title>Arlon - Luxembourg (l): Signal failure.</title><description><![CDATA[Delayed train traffic. Disruption for an undetermined amount of time. Listen to the announcements in the train station.]]></description><link><![CDATA[http://www.belgianrail.be/jp/sncb-nmbs-routeplanner/help.exe/en?tpl=showmap_external&tplParamHimMsgInfoGroup=trouble&message ID=23852&channelFilter=custom2,livemap,rss_line_10,twitter,custom1,timetable&]]></link><timestamp>1509442716</timestamp></disturbance><disturbanceid="4"><title>Louvain - Liege-Guillemins: IT problem</title><description><![CDATA[Due to an IT problem it isn't possible to get real time train information via the real time information search engine.Please listen to the announcements made in the train or in the train station.]]></description><link><![CDATA[http://www.belgianrail.be/jp/sncb-nmbs-routeplanner/help.exe/en?tpl=showmap_external&tplParamHimMsgInfoGroup=trouble&message ID=23798&channelFilter=custom2,livemap,rss_line_10,twitter,custom1,timetable&]]></link><timestamp>1509439215</timestamp></disturbance></disturbances>

Retrieve the current disturbances

As of November 2017, additional measures have been taken to improve reliability of this endpoint, even if the original NMBS RSS feed is not available. During short RSS or NMBS website outages, this endpoint should keep providing the last known status.

Retrieve information about the current disturbances on the rail network. This data is sourced from the NMBS RSS feed, cleaned up and properly formatted.

Schema

{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"connection": {
"type": "string",
"description": "The connection id for which feedback is posted. **Never** calculate or compose this id, but copy it from an API response."},
"from": {
"type": "string",
"description": "The station id for which station feedback is posted. **It is discouraged** to calculate or compose this id, but copy it from an API response or stations.csv instead."},
"date": {
"type": "string",
"description": "The date for which feedback is posted in yyyymmdd format"},
"vehicle": {
"type": "string",
"description": "The connection id for which feedback is posted. **Never** calculate or compose this id, but copy it from an API response."},
"occupancy": {
"type": "string",
"enum": [
"http://api.irail.be/terms/low",
"http://api.irail.be/terms/medium",
"http://api.irail.be/terms/high"
],
"description": "The occupancy term which defines the reported occupancy in this train."}
},
"required": [
"connection",
"from",
"date",
"vehicle",
"occupancy"
]
}

At this moment, there definitely is data duplication in the post parameters. However, since the connection id can change at any moment, we cannot retrieve any information out of it - it is only used as an id. Therefore all parameters are required.

This endpoint is only meant for applications which require realtime data, for example visualisations.
If you don’t need realtime data, please use our daily data dumps for logs and feedback, documented below.

Retrieve the last logs

Feedback about train occupancy, as well as information on which requests were made to the iRail API, are publicly available.
Every night around 3:00, this information is uploaded to the following folders: