Thetrainline APIthetrainline.com ↗
Search UK train stations, find cheapest fares across date ranges, look up live journeys, and generate Trainline booking URLs via a simple REST API.
What is the Thetrainline API?
The Trainline API covers 4 endpoints for working with UK rail data: search stations by name, look up journeys between two stations on a given date, find the cheapest fare per day across a 30-day window, and generate pre-filled booking URLs. The search_stations endpoint returns Trainline URN codes required as inputs to every other endpoint, making it the natural starting point for any integration.
curl -X GET 'https://api.parse.bot/scraper/6ece94aa-46a7-4f0f-916f-e4855ba2a3fd/search_stations?limit=10&query=Manchester' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace thetrainline-com-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
from parse_apis.trainline_uk_train_search_api import Trainline, JourneyType, Currency
trainline = Trainline()
# Search for stations by name
for station in trainline.stations.search(query="Manchester"):
print(station.name, station.code, station.country_code)
# Use a route to find cheapest fares across dates
route = trainline.route(origin="urn:trainline:generic:loc:MAN2968gb")
for fare in route.get_cheapest_fares(
destination="urn:trainline:generic:loc:EUS1444gb",
currency=Currency.GBP,
):
print(fare.date, fare.price_amount, fare.price_currency)
# Search journeys on a specific date
for journey in route.search_journeys(
destination="urn:trainline:generic:loc:EUS1444gb",
date="2026-07-01T09:00",
journey_type=JourneyType.SINGLE,
currency=Currency.GBP,
):
print(journey.depart_at, journey.arrive_at, journey.duration, journey.changes, journey.co2_grams)
# Generate a booking URL
booking = route.get_booking_url(
destination="urn:trainline:generic:loc:EUS1444gb",
date="2026-07-01T09:00",
journey_type=JourneyType.SINGLE,
)
print(booking.booking_url, booking.passengers)
Search for train stations by name. Returns matching stations with their Trainline URN codes (needed as origin/destination inputs for other endpoints), coordinates, country, timezone, and optional parent station group. Supports partial name matching across UK and European networks.
| Param | Type | Description |
|---|---|---|
| limit | integer | Maximum number of results to return |
| queryrequired | string | Station name or partial name to search for |
{
"type": "object",
"fields": {
"query": "string — the search term used",
"stations": "array of station objects with name, code, short_name, country_code, location_type, latitude, longitude, timezone, and optional parent_name",
"total_results": "integer — number of stations returned"
},
"sample": {
"data": {
"query": "London",
"stations": [
{
"code": "urn:trainline:generic:loc:EUS1444gb",
"name": "London Euston",
"latitude": 51.5284,
"timezone": "Europe/London",
"longitude": -0.1346,
"short_name": "EUS",
"parent_name": "London",
"country_code": "GB",
"location_type": "station"
}
],
"total_results": 5
},
"status": "success"
}
}About the Thetrainline API
Station Search and URN Codes
The search_stations endpoint accepts a full or partial station name and returns up to a configurable limit of matches. Each result includes the station's name, short_name, code, country_code, location_type, latitude, longitude, and timezone. The urn field from these results is the identifier you pass to origin and destination parameters in every other endpoint — without it, journey and fare lookups are not possible.
Journey Search
The search_journeys endpoint takes an origin URN, a destination URN, an optional date (ISO 8601 format), optional passengers count, currency (GBP, USD, or EUR), and a journey_type of single or return. Each journey object in the response includes depart_at, arrive_at, duration, changes, distance_km, co2_grams, a legs array, and a fares array. Note that this endpoint may be intermittently unavailable due to site protection on the source.
Cheapest Fares Calendar
The get_cheapest_fares endpoint scans a date range (defaulting to the next 30 days) and returns a daily_fares array with one price_amount and price_currency per day. A cheapest_fare object at the top level identifies the single lowest-priced day in the range — useful for flexible-date travel planning without iterating through individual journey searches.
Booking URL Generation
The get_booking_url endpoint produces a booking_url string that deep-links directly into Trainline's fare selection screen. Inputs include origin, destination, date, optional return_date, passengers, passenger_ages (comma-separated, e.g. 30,25), and journey_type. The URL is ready to hand off to a user who wants to complete the booking on Trainline's own site.
The Thetrainline API is a managed, monitored endpoint for thetrainline.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when thetrainline.com changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official thetrainline.com API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Find the cheapest day to travel between two cities using
get_cheapest_faresdaily_fares data - Build a price-alert tool that monitors a route's
cheapest_fareover time and notifies users when it drops - Auto-complete station name inputs in a booking widget using
search_stationsresults - Display journey options with
changes,duration, andco2_gramsto help users compare routes - Generate affiliate or deep-link booking URLs via
get_booking_urlwith pre-filled passenger ages - Compare outbound fares across a date window to identify travel patterns for a specific route
- Embed a rail fare calendar in a travel itinerary app using date-indexed
daily_faresobjects
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 100 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
One credit = one API call regardless of which marketplace API you call. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does Trainline have an official public developer API?+
What does `search_journeys` return beyond just prices?+
depart_at, arrive_at, duration in minutes, changes count, distance_km, co2_grams, a legs array breaking down individual train segments, and a fares array with pricing options. The currency field in the request controls whether prices come back in GBP, USD, or EUR.Is `search_journeys` always available?+
get_cheapest_fares is a more stable alternative.