Rome2Rio APIrome2rio.com ↗
Search train connections between cities worldwide via the Rome2Rio API. Returns carrier, duration, stops, prices by class, and booking links.
What is the Rome2Rio API?
The Rome2Rio Train Routes API exposes 1 endpoint — search_trains — that returns up to multiple train service options between any two city pairs worldwide, including carrier name, journey duration, intermediate stops, indicative ticket prices by class, and direct booking links. It resolves freeform city name inputs like 'Tashkent' or 'Paris' into structured route-level summaries without requiring station codes or timetable lookups.
curl -X GET 'https://api.parse.bot/scraper/bae75b3f-6cd9-4cf9-acf4-140384115708/search_trains?origin=Tashkent¤cy=USD&language=en&destination=Samarkand' \ -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 rome2rio-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.
"""Walkthrough: Rome2Rio SDK — search train connections between cities."""
from parse_apis.rome2rio_com_api import Rome2Rio, InvalidInput
client = Rome2Rio()
# Search trains from Tashkent to Samarkand
for option in client.train_search_results.search(origin="Tashkent", destination="Samarkand", limit=3):
print(option.carrier, option.duration, option.stops)
for price in option.prices:
print(f" {price.class_name}: {price.currency} {price.price}")
# Get the first result for a European route
result = client.train_search_results.search(origin="Paris", destination="Lyon", limit=1).first()
try:
detail = client.train_search_results.search(origin="Tashkent", destination="Samarkand", limit=1).first()
print(detail.carrier, detail.train_names, detail.booking_url)
except InvalidInput as e:
print("invalid input:", e)
print("exercised: train_search_results.search")
Search for train connections between two cities. Returns all available train services with carrier name, line/train identifiers, journey duration, intermediate stops, indicative prices by class, frequency, and a link to book. Results are route-level summaries (not real-time schedules); a single request returns all known services for the city pair.
| Param | Type | Description |
|---|---|---|
| originrequired | string | Departure city name (e.g. 'Paris', 'Tashkent', 'London'). |
| currency | string | ISO 4217 currency code for prices (e.g. 'USD', 'EUR', 'GBP'). |
| language | string | ISO 639-1 language code for response text. |
| destinationrequired | string | Arrival city name (e.g. 'Lyon', 'Samarkand', 'Manchester'). |
{
"type": "object",
"fields": {
"origin": "string — origin city as resolved by the service",
"currency": "string — ISO currency code used for prices",
"destination": "string — destination city as resolved by the service",
"total_options": "integer — number of train options returned",
"train_options": "array of train service objects with carrier, duration, stops, prices, and booking link"
},
"sample": {
"data": {
"origin": "Tashkent",
"currency": "USD",
"destination": "Samarkand",
"total_options": 2,
"train_options": [
{
"stops": [
"Tashkent Central",
"Samarkand"
],
"prices": [
{
"price": 33,
"currency": "USD",
"price_low": 32,
"class_name": "Business class",
"price_high": 35
},
{
"price": 23,
"currency": "USD",
"price_low": null,
"class_name": "Econom class",
"price_high": null
}
],
"carrier": "Uzbekistan Railways (High Speed Trains)",
"duration": "2h 13m",
"booking_url": "https://eticket.railway.uz/en/home",
"train_names": [
"766Ф",
"770Ф",
"768Ф"
],
"duration_seconds": 7980,
"frequency_per_week": 37
},
{
"stops": [
"Tashkent Central",
"Gulistan",
"Djizak",
"Samarkand"
],
"prices": [
{
"price": 12,
"currency": "USD",
"price_low": 11,
"class_name": "Sleeper",
"price_high": 13
},
{
"price": 16,
"currency": "USD",
"price_low": 15,
"class_name": "Coupe",
"price_high": 17
},
{
"price": 28,
"currency": "USD",
"price_low": 26,
"class_name": "SV",
"price_high": 29
}
],
"carrier": "Uzbekistan Railways (OTY)",
"duration": "3h 9m",
"booking_url": "https://eticket.railway.uz/en/home",
"train_names": [
"710F",
"712F",
"712Ф/704Ч"
],
"duration_seconds": 11340,
"frequency_per_week": 26
}
]
},
"status": "success"
}
}About the Rome2Rio API
What the API Returns
The search_trains endpoint accepts two required parameters — origin and destination — as plain city names and returns a structured response with total_options (the count of distinct train services found) and a train_options array. Each element in that array carries the carrier name, train or line identifier, total journey duration, a list of intermediate stops, indicative prices broken down by class, service frequency, and a booking link. The origin and destination fields in the response reflect the city names as resolved by Rome2Rio, which may differ slightly from the raw input strings.
Parameters and Localization
Beyond the required city pair, the endpoint accepts currency (ISO 4217 code, e.g. USD, EUR) to normalize all returned prices into a single currency, and language (ISO 639-1 code, e.g. en, fr) to localize response text such as carrier names and stop labels. This makes it straightforward to build localized travel tools without post-processing the response.
Coverage and Data Shape
Results are route-level summaries rather than real-time schedules. Prices are indicative — sourced from Rome2Rio's aggregated data — and the booking links point to relevant purchase pages. The API covers intercity train services globally, including routes across Europe, Central Asia, and other regions where Rome2Rio indexes rail carriers. City name resolution is handled server-side, so inputs like 'London', 'Samarkand', or 'Lyon' are accepted without additional geocoding steps.
The Rome2Rio API is a managed, monitored endpoint for rome2rio.com — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when rome2rio.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 rome2rio.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?+
- Display train route options with prices and carriers in a multi-modal travel planning app.
- Compare journey durations between competing train services on the same city pair.
- Surface booking links for train tickets inside a trip itinerary builder.
- Build a fare-monitoring tool that tracks indicative price changes between two cities.
- Populate a travel guide with carrier and stop data for intercity rail routes.
- Offer localized train route results in different currencies for international travel platforms.
| 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 Rome2Rio have an official developer API?+
What does each object in the `train_options` array actually contain?+
origin and destination strings and the total_options count.Are prices real-time or live seat availability returned?+
Does the API return bus, flight, or ferry alternatives for the same city pair?+
search_trains endpoint covers train services only. Rome2Rio's underlying data includes other transport modes, but those are not exposed by this API. You can fork it on Parse and revise it to add endpoints for buses, flights, or ferries.Can I search by station code or address instead of city name?+
origin and destination; station codes or street addresses are not supported inputs at this time. The service resolves the city names internally and returns the matched names in the response. You can fork the API on Parse and revise it to add station-level resolution if your use case requires it.