# Rome2Rio Multi-Modal Route Scraper (`crawlerbros/rome2rio-scraper`) Actor

Scrape Rome2Rio trip-planning results - compare flight, train, bus, car, ferry, and rideshare options between any two cities or airports, with durations, price ranges, and operators.

- **URL**: https://apify.com/crawlerbros/rome2rio-scraper.md
- **Developed by:** [Crawler Bros](https://apify.com/crawlerbros) (community)
- **Categories:** Travel, Automation, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

## Rome2Rio Multi-Modal Route Scraper

Scrape **Rome2Rio** trip-planning results — compare every reliable way to get from one place to another: flight, train, bus, car, ferry, rideshare, and walking. Get durations, price ranges, operators, and distances for every route option Rome2Rio surfaces for a city, town, or airport pair. HTTP-only, no login, no cookies required.

### What this actor does

- **Single-route or batch search** — look up one origin/destination pair, or supply an array of pairs to scrape many routes in one run
- **Every transport mode Rome2Rio returns:** flight, train, bus, car/drive, ferry, rideshare, walk — including multi-leg combinations (e.g. "train to the airport, then fly")
- **Filters:** transport mode, max duration, max price
- **Sort:** recommended (site order), cheapest first, fastest first
- **Operators surfaced where shown** (e.g. Amtrak, Eurostar, Flixbus, Greyhound)
- **Empty fields are omitted** — a field only appears on a record when real data was found for it

### Output per route option

- `origin`, `destination` — canonicalized place names for the route
- `mode` — primary transport mode for this option (`flight` / `train` / `bus` / `car` / `ferry` / `rideshare` / `walk`)
- `modes` — every mode involved for multi-leg options (e.g. `["car", "ferry"]`)
- `title` — Rome2Rio's own label for the option (e.g. `Train (Amtrak)`, `Drive 337.4 km`)
- `operators[]` — named carrier(s), when shown (e.g. `Amtrak`, `Flixbus`)
- `durationMinutes`, `durationText` — total travel time
- `priceMin`, `priceMax`, `currency` — quoted fare range
- `distanceKm` — driving distance, for car-only options
- `straightLineDistanceKm` — general point-to-point distance between origin and destination, present on every option regardless of mode
- `position` — Rome2Rio's own rank/order for this option (1 = top result)
- `deepLink` — link to the full Rome2Rio itinerary/schedule page for this option
- `sourceUrl` — the Rome2Rio search page this was scraped from
- `recordType: "routeOption"`, `scrapedAt`

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `origin` | string | `New York` | Starting city, town, address, or airport. Ignored if `routePairs` is set. |
| `destination` | string | `Boston` | Ending city, town, address, or airport. Ignored if `routePairs` is set. |
| `routePairs` | array | – | Batch mode: `[{"origin": "...", "destination": "..."}, ...]` — scrapes multiple routes in one run |
| `transportMode` | string | `any` | Keep only options using this mode: `any` / `flight` / `train` / `bus` / `car` / `ferry` / `rideshare` / `walk` |
| `maxDurationMinutes` | int | – | Drop options longer than this many minutes |
| `maxPrice` | number | – | Drop options whose cheapest quoted price exceeds this |
| `sortBy` | string | `recommended` | `recommended` / `cheapest` / `fastest` |
| `maxItems` | int | `50` | Hard cap on emitted route options (1–1000) |
| `proxyConfiguration` | object | AUTO | Apify proxy (free AUTO datacenter group); not strictly required |

### Examples

#### Example: simple city-to-city search

```json
{
  "origin": "New York",
  "destination": "Boston",
  "maxItems": 20
}
````

#### Example: only flights, cheapest first

```json
{
  "origin": "Paris",
  "destination": "London",
  "transportMode": "flight",
  "sortBy": "cheapest"
}
```

#### Example: batch multiple routes in one run

```json
{
  "routePairs": [
    { "origin": "Berlin", "destination": "Prague" },
    { "origin": "Munich", "destination": "Zurich" }
  ],
  "maxItems": 100
}
```

#### Example: fast options only, budget capped

```json
{
  "origin": "Los Angeles",
  "destination": "San Francisco",
  "maxDurationMinutes": 180,
  "maxPrice": 100,
  "sortBy": "fastest"
}
```

### Use cases

- **Travel planning tools** — pull live multi-modal options into a trip-comparison UI
- **Fare-tracking dashboards** — snapshot price ranges across modes for a route over time
- **Travel content/SEO** — power "how to get from X to Y" articles with real operator and fare data
- **Corporate travel booking** — compare cost/time tradeoffs across transport modes for a route
- **Market research** — see which operators and modes Rome2Rio surfaces as viable for a given city pair

### Data Source / Limitations

Data comes from Rome2Rio's public trip-summary pages (`rome2rio.com/s/<origin>/<destination>`), which render duration and price ranges without requiring login. Rome2Rio determines the actual origin/destination match when a place name is ambiguous (e.g. multiple cities sharing a name) — the actor reports back whichever place Rome2Rio resolved to. Prices are indicative ranges as shown on the summary page, not live booking quotes; for exact schedules and booking, follow the `deepLink` for an option. If no viable route exists between two places, or all results are excluded by filters, the actor returns 0 records with a clear status message rather than failing.

Rome2Rio protects its pages with Cloudflare bot-management for all visitors, including real browsers (a one-time JS challenge that resolves automatically in a browser tab). This means `deepLink` and `sourceUrl` values open normally when clicked in a browser, but a bare command-line request (e.g. plain `curl`) to those URLs may receive a challenge page instead of the itinerary — this is Rome2Rio's own site-wide protection, not a broken or mistyped link.

### FAQ

**Is this affiliated with Rome2Rio?**
No — this is an independent, third-party actor that reads Rome2Rio's public search-results pages.

**Why do some options have no `operators` field?**
Rome2Rio only names a specific carrier for some options (e.g. "Train (Amtrak)"); others are generic (e.g. "Bus") because the site doesn't attribute a single operator on the summary page.

**Why is `distanceKm` only present on some records?**
Rome2Rio only shows an explicit driving distance for car/drive options on the summary page — other modes don't include a comparable figure. `straightLineDistanceKm` (point-to-point distance) is present on every option regardless of mode.

**What currency are prices in?**
Prices are consistently shown in USD by Rome2Rio's summary page regardless of route location, locale, or currency query parameters — the `currency` field reflects whatever symbol/code is actually found on the page.

**Does `transportMode` filter change what Rome2Rio itself returns?**
No — Rome2Rio always returns its full set of route options; the `transportMode` filter is applied by the actor after fetching so you only receive the modes you asked for.

**What happens if the two places can't be matched to a real route?**
The actor returns 0 records and sets a status message explaining that no route was found — this is treated as a clean, valid result, not an error.

# Actor input Schema

## `origin` (type: `string`):

Starting city, town, address, or airport name. Ignored if `routePairs` is provided.

## `destination` (type: `string`):

Ending city, town, address, or airport name. Ignored if `routePairs` is provided.

## `routePairs` (type: `array`):

Provide multiple {"origin": "...", "destination": "..."} pairs to scrape several routes in one run. When non-empty, this overrides the single `origin`/`destination` fields above.

## `transportMode` (type: `string`):

Only keep route options that use this mode (as any leg of a multi-leg journey). `any` keeps every mode Rome2Rio returns.

## `maxDurationMinutes` (type: `integer`):

Drop route options whose total travel time exceeds this many minutes.

## `maxPrice` (type: `number`):

Drop route options whose cheapest quoted price exceeds this amount.

## `sortBy` (type: `string`):

How to order the emitted route options.

## `maxItems` (type: `integer`):

Hard cap on total route options emitted across all requested routes.

## `proxyConfiguration` (type: `object`):

Uses Apify's free AUTO proxy group to reduce the chance of rate-limiting. Not strictly required.

## Actor input object example

```json
{
  "origin": "New York",
  "destination": "Boston",
  "routePairs": [],
  "transportMode": "any",
  "sortBy": "recommended",
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `routes` (type: `string`):

Dataset containing all scraped Rome2Rio route options.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "origin": "New York",
    "destination": "Boston",
    "routePairs": [],
    "transportMode": "any",
    "sortBy": "recommended",
    "maxItems": 50,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("crawlerbros/rome2rio-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "origin": "New York",
    "destination": "Boston",
    "routePairs": [],
    "transportMode": "any",
    "sortBy": "recommended",
    "maxItems": 50,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("crawlerbros/rome2rio-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "origin": "New York",
  "destination": "Boston",
  "routePairs": [],
  "transportMode": "any",
  "sortBy": "recommended",
  "maxItems": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call crawlerbros/rome2rio-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=crawlerbros/rome2rio-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Rome2Rio Multi-Modal Route Scraper",
        "description": "Scrape Rome2Rio trip-planning results - compare flight, train, bus, car, ferry, and rideshare options between any two cities or airports, with durations, price ranges, and operators.",
        "version": "1.0",
        "x-build-id": "oPLms66OWDANEhsxM"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/crawlerbros~rome2rio-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-crawlerbros-rome2rio-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/crawlerbros~rome2rio-scraper/runs": {
            "post": {
                "operationId": "runs-sync-crawlerbros-rome2rio-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/crawlerbros~rome2rio-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-crawlerbros-rome2rio-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "origin",
                    "destination"
                ],
                "properties": {
                    "origin": {
                        "title": "Origin",
                        "type": "string",
                        "description": "Starting city, town, address, or airport name. Ignored if `routePairs` is provided.",
                        "default": "New York"
                    },
                    "destination": {
                        "title": "Destination",
                        "type": "string",
                        "description": "Ending city, town, address, or airport name. Ignored if `routePairs` is provided.",
                        "default": "Boston"
                    },
                    "routePairs": {
                        "title": "Batch route pairs (optional)",
                        "type": "array",
                        "description": "Provide multiple {\"origin\": \"...\", \"destination\": \"...\"} pairs to scrape several routes in one run. When non-empty, this overrides the single `origin`/`destination` fields above.",
                        "default": []
                    },
                    "transportMode": {
                        "title": "Transport mode filter",
                        "enum": [
                            "any",
                            "flight",
                            "train",
                            "bus",
                            "car",
                            "ferry",
                            "rideshare",
                            "walk"
                        ],
                        "type": "string",
                        "description": "Only keep route options that use this mode (as any leg of a multi-leg journey). `any` keeps every mode Rome2Rio returns.",
                        "default": "any"
                    },
                    "maxDurationMinutes": {
                        "title": "Max duration (minutes)",
                        "minimum": 1,
                        "maximum": 10080,
                        "type": "integer",
                        "description": "Drop route options whose total travel time exceeds this many minutes."
                    },
                    "maxPrice": {
                        "title": "Max price (lower bound, USD)",
                        "minimum": 0,
                        "maximum": 100000,
                        "type": "number",
                        "description": "Drop route options whose cheapest quoted price exceeds this amount."
                    },
                    "sortBy": {
                        "title": "Sort order",
                        "enum": [
                            "recommended",
                            "cheapest",
                            "fastest"
                        ],
                        "type": "string",
                        "description": "How to order the emitted route options.",
                        "default": "recommended"
                    },
                    "maxItems": {
                        "title": "Max items",
                        "minimum": 1,
                        "maximum": 1000,
                        "type": "integer",
                        "description": "Hard cap on total route options emitted across all requested routes.",
                        "default": 50
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Uses Apify's free AUTO proxy group to reduce the chance of rate-limiting. Not strictly required.",
                        "default": {
                            "useApifyProxy": true
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
