This is an implementation of the OSDM API spec's Places endpoint, backed by Trainline EU's stations dataset.
The easiest way to use reStations is as a Docker container using the image that we published including the dataset:
docker run -p 3000:3000 --rm mainmatter/restations
curl localhost:3000/places
New versions of the image are published regularly as the dataset is updated.
Request all places:
curl localhost:3000/places
Example: fetch Lisboa Santa Apolónia station with its UIC:
curl localhost:3000/places/8721428
Example: search stations with Lisboa
in its name.
Works with both Portuguese and English versions, and in other languages as well. See Trainline's data repository for the complete list of supported languages.
curl -X POST -H "Content-Type: application/json" \
-d '{"placeInput": {"name": "Lisboa"}}' \
localhost:3000/places
Example: search stations near Lisboa Santa Apolónia station:
curl -X POST -H "Content-Type: application/json" \
-d '{"placeInput": {"geoPosition": {"latitude": 38.71387, "longitude": -9.122271}}}' \
localhost:3000/places
We currently support requesting the number of results to be returned.
curl -X POST -H "Content-Type: application/json" \
-d '{"placeInput": {"name": "London"}, "restrictions": {"numberOfResults": 3}}' \
localhost:3000/places
This will return St Pancras, Liverpool Street and Blackfriars stations:
{
"places": [
{
"id": "urn:uic:stn:7015400",
"objectType": "StopPlace",
"name": "London St Pancras International",
"alternativeIds": [],
"geoPosition": {
"latitude": 51.531921,
"longitude": -0.126361
},
"countryCode": "GB",
"links": []
},
{
"id": "urn:uic:stn:7069650",
"objectType": "StopPlace",
"name": "London Liverpool Street",
"alternativeIds": [],
"geoPosition": {
"latitude": 51.517551,
"longitude": -0.08021
},
"countryCode": "GB",
"links": []
},
{
"id": "urn:uic:stn:7051120",
"objectType": "StopPlace",
"name": "London Blackfriars",
"alternativeIds": [],
"geoPosition": {
"latitude": 51.510735,
"longitude": -0.103554
},
"countryCode": "GB",
"links": []
}
]
}
Support for other restrictions
request fields for POST /places is in the works.
reStations
can also be used directly as a Rust project. To run the project, prepare the database first:
cargo db create
This is important since reStations uses sqlx which does compile-time checks on the database schema and needs the DATABASE_URL
environment variable to be able to connect to the database.
To synchronize the data into the local database from the Trainline EU station dataset, run
cargo db sync
Then run the applications from the project root:
cargo run
Distinct parts of the project are separated into separate crates:
.
├── cli // CLI tools for generating project files
├── config // Defines the `Config` struct and handles building the configuration from environment-specific TOML files and environment variables
├── macros // Contains macros for application tests
└── web // The web interface as well as tests for it
The project uses .env
and .env.test
files to store configuration settings for the development and test environments respectively. Those files are read automatically by the parts of the application that require configuration settings to be present.
Running the application in development mode:
cargo run
Running the application tests:
cargo db create -e test
cargo test
Generating project files like entities, controllers, tests, etc. (see the CLI create for detailed documentation):
cargo generate
Building the project's docs:
Build the project's documentation with:
cargo doc --workspace --all-features
Copyright © 2025- Mainmatter GmbH (https://mainmatter.com), released under the MIT and Apache licenses.
Trainline EU's stations dataset is released under the Open Data Commons Open Database License v1.0 license which allows private and commercial use.