Google Maps Directions & Routes API | Multi-Stop Navigation avatar

Google Maps Directions & Routes API | Multi-Stop Navigation

Pricing

from $1.49 / 1,000 directions

Go to Apify Store
Google Maps Directions & Routes API | Multi-Stop Navigation

Google Maps Directions & Routes API | Multi-Stop Navigation

Extract driving, walking, cycling, and transit directions from Google Maps as structured data. Get multi-stop routes (2-10 stops), turn-by-turn instructions, distance, duration, traffic estimates, and Street View thumbnails. No API key needed. Supports departure/arrival times and route preferences.

Pricing

from $1.49 / 1,000 directions

Rating

5.0

(1)

Developer

Zen Studio

Zen Studio

Maintained by Community

Actor stats

1

Bookmarked

156

Total users

28

Monthly active users

6 days ago

Last modified

Share

Google Maps Directions Scraper | Multi-Stop Routes as Structured Data (2026)

GET DIRECTIONS IN ~2 SECONDS. UP TO 10 STOPS. LIVE TRAFFIC. TURN-BY-TURN.

From Zen Studio, creators of Google Maps Scraper, Apple Maps Directions and AMap Directions. Maps and routing tools for business data and travel planning.

Why choose this actor?

Get route data in seconds. Enter place names or addresses and receive structured directions with distance, travel time and route alternatives. Choose driving, walking, cycling or public transit.

Plan up to 10 stops. Keep your stops in the order you need and get a separate leg for each part of the journey. Compare the alternatives Google returns, with travel times and traffic estimates where available.

Keep the navigation detail. Export turn-by-turn instructions, route and leg distances, traffic estimates and Street View thumbnails where available. Full detail is included by default; choose overview mode for a smaller response.

Get your directions

Quick start

Try a three-stop driving route from Berlin through Prague to Vienna. Replace the stops with your own locations.

{
"stops": [
"Berlin, Germany",
"Prague, Czech Republic",
"Vienna, Austria"
],
"travelMode": "driving",
"detailLevel": "full"
}

Open actor input to choose your stops and travel mode. Export JSON, CSV or Excel; JSON preserves route alternatives, legs and navigation steps.

Traffic, route alternatives and Street View availability depend on the route and travel mode. Processing time varies with the request.

Zen Studio · Maps Suite
  Google Routes
You are here
  Google Maps
Find businesses
  Google Reviews
Review histories
  Apple Routes
Routes & travel times
  AMap Routes
China directions

Copy to your AI assistant

Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.

zen-studio/google-maps-directions-api on Apify. Call: ApifyClient("TOKEN").actor("zen-studio/google-maps-directions-api").call(run_input={...}), then client.dataset(run["defaultDatasetId"]).list_items().items for results. Key inputs: stops: string[] (required, 2-10 locations), travelMode: string (driving|transit|walking|cycling), language: string. Full actor spec (input schema with all params/enums/defaults, output dataset fields, README): GET https://api.apify.com/v2/acts/zen-studio~google-maps-directions-api/builds/default (Bearer TOKEN) → inputSchema, actorDefinition.storages.dataset, readme. Pricing: $0.00299/direction, $0.00699/actor start, $0.00001/dataset item. Get token: https://console.apify.com/account/integrations To reach the maintainers, add feedback="<what you needed and did not get>" to any run, including one that worked: feature requests, a missing field or option, a wrong or empty result, or which actor you are switching to or from and why. The run returns its data exactly as it would without the note, and a human reads every note.

How to Scrape Google Maps Directions

Enter your stops (2-10 locations), pick a travel mode, and run. The Actor geocodes place names via Google Maps autocomplete, fetches directions, and returns structured route data.

Two-Stop Route (Simple)

{
"stops": ["Berlin, Germany", "Munich, Germany"],
"travelMode": "driving"
}

Multi-Stop Route

{
"stops": [
"Berlin, Germany",
"Prague, Czech Republic",
"Vienna, Austria",
"Budapest, Hungary"
],
"travelMode": "driving"
}

Each pair of consecutive stops becomes a leg. A 4-stop route returns 3 legs per route alternative.

Walking with Wheelchair Access

{
"stops": ["Central Park, New York", "Times Square, New York"],
"travelMode": "walking",
"wheelchairAccessible": true
}

Public Transit with Preferred Types

{
"stops": ["Alexanderplatz, Berlin", "Brandenburg Gate, Berlin"],
"travelMode": "transit",
"transitTypes": ["subway", "tram"],
"transitRoutePreference": "fewer_transfers"
}

transitTypes is a preference, not a hard filter. When no route uses only the types you pick, the best available route is still returned, so a bus-only preference can come back with a subway leg. Each transit segment carries a vehicle_category (bus, subway, train, tram) so you can drop the routes you do not want.

Depart at a Specific Time

{
"stops": ["Vienna Opera", "Schoenbrunn Palace"],
"travelMode": "driving",
"timeOption": "depart_at",
"date": "2026-03-15",
"time": "09:00"
}

Date and time are interpreted in the timezone of the first stop. Use arrive_by to plan backwards from an arrival time (driving and transit only).

Overview Mode (Smaller Output)

{
"stops": ["Berlin, Germany", "Munich, Germany"],
"travelMode": "driving",
"detailLevel": "overview"
}

Returns all stops, legs, and segment instructions without turn-by-turn substeps, Street View, or polyline tokens. Transit stops and departure times are kept. Same routes, much smaller response.

What Data You Get from Google Maps Directions

Each run returns one dataset item containing:

  • Multiple route alternatives -- Google typically returns 2-3 different routes per query
  • Turn-by-turn instructions -- every maneuver with human-readable text and emphasis markers
  • Distance and duration -- at route, leg, segment, and substep level (meters + formatted text)
  • Traffic estimates -- current, typical, and no-traffic durations with congestion level
  • Street View thumbnails -- per navigation step with panorama IDs
  • Transit detail -- line and vehicle type, boarding and alighting stops with departure and arrival times, intermediate stops, operators, and service alerts
  • Waypoint data -- geocoded place names, coordinates, and place IDs for each stop
  • 30+ languages -- localized street names and instructions (en, de, fr, es, ja, zh, ar, and more)

Pricing

Pay-per-event pricing. You only pay for directions successfully fetched.

EventPrice
Actor start$0.00699
Direction result$0.00299

Cost Examples

RunsCost
10$0.10
100$1.00
1,000$9.99

Try it free -- new Apify users get $5 in platform credits. That's ~1,600 routes at no cost.

Budget controls are built in. The Actor stops automatically when your spending limit is reached.

Input Parameters

ParameterTypeDefaultDescription
stopsstring[]required2-10 locations in order. First is origin, last is destination, rest are intermediate stops.
travelModestringdrivingdriving, transit, walking, or cycling.
timeOptionstringnownow, depart_at, or arrive_by. Arrive by supports driving and transit only.
datestring—Travel date in YYYY-MM-DD format. Required when timeOption is not now.
timestring—Travel time in 24h HH:MM format. Required when timeOption is not now.
avoidHighwaysbooleanfalseAvoid highways. Driving mode.
avoidTollsbooleanfalseAvoid toll roads. Driving mode.
avoidFerriesbooleanfalseAvoid ferries. Driving mode.
wheelchairAccessiblebooleanfalsePrefer accessible routes. Walking mode.
transitTypesstring[]allTypes to prefer: bus, subway, train, tram. A preference, not a hard filter. Transit mode.
transitRoutePreferencestringbest_routebest_route, fewer_transfers, or less_walking. Transit mode.
detailLevelstringfullfull (turn-by-turn substeps, Street View, polyline) or overview (all stops and segments, without substeps or Street View).
distanceUnitstringautoauto (regional default), km, or miles.
languagestringenLanguage code for instructions. en, de, fr, es, ja, etc.

Output Example (Full)

Default detailLevel: "full" — includes turn-by-turn substeps, Street View thumbnails, emphasis markers, and polyline tokens.

{
"query": {
"stops": [
"Berlin, Germany",
"Munich, Germany"
],
"travel_mode": "driving",
"language": "en",
"avoid_highways": false,
"avoid_tolls": false,
"avoid_ferries": false,
"distance_unit": "auto"
},
"waypoints": [
{
"name": "Berlin, Germany",
"coords": {
"lat": 52.520006599999995,
"lng": 13.404954
},
"encoded_id": "ChIJAVkDPzdOqEcRcDteW0YgIQQ",
"display_name": "Berlin",
"display_names": [
"Berlin",
"Germany"
]
},
{
"name": "Munich, Germany",
"coords": {
"lat": 48.1351253,
"lng": 11.5819805
},
"encoded_id": "ChIJ2V-Mo_l1nkcRfZixfUq4DAE",
"display_name": "Munich",
"display_names": [
"Munich",
"Germany"
]
}
],
"routes": [
{
"index": 0,
"travel_mode": "driving",
"via": "A9",
"distance": {
"meters": 584762,
"text": "585 km"
},
"duration": {
"seconds": 22494,
"text": "6 hr 15 min"
},
"departure_time": null,
"arrival_time": null,
"country": [
"DE"
],
"polyline_token": "CAEi0QEKUBXWsBwVF9Yc/6T7HFYpJh...",
"eta_messages": [
[
"You're on the fastest route."
],
[
"You should arrive around 11:34 AM.",
1
]
],
"traffic": {
"traffic_level": 3,
"congestion_zones": [
[
[
1,
974,
226
]
]
]
},
"legs": [
{
"distance": {
"meters": 584762,
"text": "585 km"
},
"duration": {
"seconds": 22496,
"text": "6 hr 15 min"
},
"traffic": {
"no_traffic": {
"seconds": 21285,
"text": "5 hr 55 min"
},
"traffic_level": 3,
"typical": {
"seconds": 19713,
"text": "5 hr 29 min"
},
"range": {
"min_seconds": 18781,
"max_seconds": 28035,
"text": "5 hr 13 min to 7 hr 47 min"
}
},
"destination": {
"name": "Munich",
"names": [
"Munich",
"Germany"
],
"end_point": {
"lat": 48.1351253,
"lng": 11.5819805
},
"timezone": "Europe/Berlin",
"timezone_abbr": "GMT+1"
},
"segments": [
{
"mode": "driving",
"distance": {
"meters": 9292,
"text": "9.3 km"
},
"duration": {
"seconds": 1355,
"text": "23 min"
},
"instruction": "Get on A100 in Bezirk Charlottenburg-Wilmersdorf from B2",
"instruction_parts": [
{
"text": "Get on ",
"emphasized": false
},
{
"text": "A100",
"emphasized": true
},
{
"text": " in ",
"emphasized": false
},
{
"text": "Bezirk Charlottenburg-Wilmersdorf",
"emphasized": false
},
{
"text": " from ",
"emphasized": false
},
{
"text": "B2",
"emphasized": true
}
],
"substeps": [
{
"maneuver_type": 0,
"distance": {
"meters": 1749,
"text": "1.7 km"
},
"duration": {
"seconds": 314,
"text": "5 min"
},
"instruction": "Head toward Spandauer Str.",
"instruction_parts": [
{
"text": "Head toward ",
"emphasized": false
},
{
"text": "Spandauer Str.",
"emphasized": true
}
],
"start_point": {
"lat": 52.519947955056686,
"lng": 13.404969798377866
},
"end_point": {
"lat": 52.5200143,
"lng": 13.4049447
}
},
{
"maneuver_type": 0,
"distance": {
"meters": 166,
"text": "170 m"
},
"duration": {
"seconds": 39,
"text": "39 sec"
},
"instruction": "Turn right onto Wilhelmstraße/B2/B5",
"instruction_parts": [
{
"text": "Turn ",
"emphasized": false
},
{
"text": "right",
"emphasized": true
},
{
"text": " onto ",
"emphasized": false
},
{
"text": "Wilhelmstraße",
"emphasized": true
},
{
"text": "/",
"emphasized": false
},
{
"text": "B2",
"emphasized": true
},
{
"text": "/",
"emphasized": false
},
{
"text": "B5",
"emphasized": true
}
],
"start_point": {
"lat": 52.5166258988976,
"lng": 13.38102620691614
},
"end_point": {
"lat": 52.5166058,
"lng": 13.380732300000002
},
"streetview": {
"pano_id": "TP4jMtqDWaafVBfo0YwWrQ",
"thumbnail_url": "https://streetviewpixels-pa.googleapis.com/v1/thumbnail?panoid=TP4jMtqDWaafVBfo0YwWrQ&cb_client=maps_sv.tactile.gps&w=203&h=100&yaw=83.50145&pitch=0&thumbfov=100",
"thumbnail_size": [
203,
100
]
}
}
]
},
{
"mode": "driving",
"distance": {
"meters": 569245,
"text": "569 km"
},
"duration": {
"seconds": 20474,
"text": "5 hr 41 min"
},
"instruction": "Get on Schenkendorfstraße/B2R in Schwabing-Freimann, München from A9",
"instruction_parts": [
{
"text": "Get on ",
"emphasized": false
},
{
"text": "Schenkendorfstraße",
"emphasized": true
},
{
"text": "/",
"emphasized": false
},
{
"text": "B2R",
"emphasized": true
},
{
"text": " in ",
"emphasized": false
},
{
"text": "Schwabing-Freimann, München",
"emphasized": false
},
{
"text": " from ",
"emphasized": false
},
{
"text": "A9",
"emphasized": true
}
],
"substeps": [
{
"maneuver_type": 0,
"distance": {
"meters": 438,
"text": "450 m"
},
"duration": {
"seconds": 29,
"text": "29 sec"
},
"instruction": "Merge onto A100",
"instruction_parts": [
{
"text": "Merge onto ",
"emphasized": false
},
{
"text": "A100",
"emphasized": true
}
],
"start_point": {
"lat": 52.50693146195627,
"lng": 13.282207707594479
},
"end_point": {
"lat": 52.5067585,
"lng": 13.282255399999999
},
"streetview": {
"pano_id": "mlwx1qTPlfcP8mPatY_yTg",
"thumbnail_url": "https://streetviewpixels-pa.googleapis.com/v1/thumbnail?panoid=mlwx1qTPlfcP8mPatY_yTg&cb_client=maps_sv.tactile.gps&w=203&h=100&yaw=10.174609&pitch=0&thumbfov=100",
"thumbnail_size": [
203,
100
]
}
},
{
"maneuver_type": 0,
"distance": {
"meters": 640,
"text": "650 m"
},
"duration": {
"seconds": 47,
"text": "47 sec"
},
"instruction": "At the interchange 10-Dreieck Funkturm, Use the right lane to follow signs for A115/E51 toward Magdeburg/Leipzig/Potsdam",
"instruction_parts": [
{
"text": "At the interchange ",
"emphasized": false
},
{
"text": "10-Dreieck Funkturm",
"emphasized": true
},
{
"text": ", Use the right lane to follow signs for ",
"emphasized": false
},
{
"text": "A115",
"emphasized": true
},
{
"text": "/",
"emphasized": false
},
{
"text": "E51",
"emphasized": true
},
{
"text": " toward ",
"emphasized": false
},
{
"text": "Magdeburg",
"emphasized": true
},
{
"text": "/",
"emphasized": false
},
{
"text": "Leipzig",
"emphasized": true
},
{
"text": "/",
"emphasized": false
},
{
"text": "Potsdam",
"emphasized": true
}
],
"start_point": {
"lat": 52.5030939232209,
"lng": 13.280960733910394
},
"end_point": {
"lat": 52.502926900000006,
"lng": 13.280850599999999
},
"streetview": {
"pano_id": "AKxz0C8zQWeULgyiZL9wRw",
"thumbnail_url": "https://streetviewpixels-pa.googleapis.com/v1/thumbnail?panoid=AKxz0C8zQWeULgyiZL9wRw&cb_client=maps_sv.tactile.gps&w=203&h=100&yaw=201.45728&pitch=0&thumbfov=100",
"thumbnail_size": [
203,
100
]
}
}
]
}
]
}
]
}
]
}

Output Example (Overview)

detailLevel: "overview" — all stops, legs, and segment instructions, but without turn-by-turn substeps, Street View, or polyline tokens. Same routes at a fraction of the size.

{
"query": {
"stops": [
"Berlin, Germany",
"Munich, Germany"
],
"travel_mode": "driving",
"language": "en",
"avoid_highways": false,
"avoid_tolls": false,
"avoid_ferries": false,
"distance_unit": "auto"
},
"waypoints": [
{
"name": "Berlin, Germany",
"coords": {
"lat": 52.520006599999995,
"lng": 13.404954
},
"encoded_id": "ChIJAVkDPzdOqEcRcDteW0YgIQQ",
"display_name": "Berlin",
"display_names": [
"Berlin",
"Germany"
]
},
{
"name": "Munich, Germany",
"coords": {
"lat": 48.1351253,
"lng": 11.5819805
},
"encoded_id": "ChIJ2V-Mo_l1nkcRfZixfUq4DAE",
"display_name": "Munich",
"display_names": [
"Munich",
"Germany"
]
}
],
"routes": [
{
"index": 0,
"travel_mode": "driving",
"via": "A9",
"distance": {
"meters": 584762,
"text": "585 km"
},
"duration": {
"seconds": 22494,
"text": "6 hr 15 min"
},
"departure_time": null,
"arrival_time": null,
"country": [
"DE"
],
"legs": [
{
"distance": {
"meters": 584762,
"text": "585 km"
},
"duration": {
"seconds": 22496,
"text": "6 hr 15 min"
},
"traffic": {
"no_traffic": {
"seconds": 21287,
"text": "5 hr 55 min"
},
"traffic_level": 3,
"typical": {
"seconds": 19713,
"text": "5 hr 29 min"
},
"range": {
"min_seconds": 18715,
"max_seconds": 28232,
"text": "5 hr 12 min to 7 hr 51 min"
}
},
"destination": {
"name": "Munich",
"names": [
"Munich",
"Germany"
],
"end_point": {
"lat": 48.1351253,
"lng": 11.5819805
},
"timezone": "Europe/Berlin",
"timezone_abbr": "GMT+1"
},
"segments": [
{
"mode": "driving",
"distance": {
"meters": 9292,
"text": "9.3 km"
},
"duration": {
"seconds": 1355,
"text": "23 min"
},
"instruction": "Get on A100 in Bezirk Charlottenburg-Wilmersdorf from B2"
},
{
"mode": "driving",
"distance": {
"meters": 569245,
"text": "569 km"
},
"duration": {
"seconds": 20474,
"text": "5 hr 41 min"
},
"instruction": "Get on Schenkendorfstraße/B2R in Schwabing-Freimann, München from A9"
},
{
"mode": "driving",
"distance": {
"meters": 6225,
"text": "6.2 km"
},
"duration": {
"seconds": 667,
"text": "11 min"
},
"instruction": "Continue on B2R. Take Ifflandstraße and Prinzregentenstraße to Tal in Altstadt-Lehel"
}
]
}
]
},
{
"index": 1,
"travel_mode": "driving",
"via": "A93 and A9",
"distance": {
"meters": 616271,
"text": "616 km"
},
"duration": {
"seconds": 23539,
"text": "6 hr 32 min"
},
"departure_time": null,
"arrival_time": null,
"country": [
"DE"
],
"legs": [
{
"distance": {
"meters": 616271,
"text": "616 km"
},
"duration": {
"seconds": 23541,
"text": "6 hr 32 min"
},
"traffic": {
"no_traffic": {
"seconds": 22370,
"text": "6 hr 13 min"
},
"traffic_level": 3,
"typical": {
"seconds": 20527,
"text": "5 hr 42 min"
},
"range": {
"min_seconds": 19769,
"max_seconds": 29580,
"text": "5 hr 29 min to 8 hr 13 min"
}
},
"destination": {
"name": "Munich",
"names": [
"Munich",
"Germany"
],
"end_point": {
"lat": 48.1351253,
"lng": 11.5819805
},
"timezone": "Europe/Berlin",
"timezone_abbr": "GMT+1"
},
"segments": [
{
"mode": "driving",
"distance": {
"meters": 9292,
"text": "9.3 km"
},
"duration": {
"seconds": 1355,
"text": "23 min"
},
"instruction": "Get on A100 in Bezirk Charlottenburg-Wilmersdorf from B2"
},
{
"mode": "driving",
"distance": {
"meters": 600754,
"text": "601 km"
},
"duration": {
"seconds": 21519,
"text": "5 hr 59 min"
},
"instruction": "Get on Schenkendorfstraße/B2R in Schwabing-Freimann, München from A9 and A93"
},
{
"mode": "driving",
"distance": {
"meters": 6225,
"text": "6.2 km"
},
"duration": {
"seconds": 667,
"text": "11 min"
},
"instruction": "Continue on B2R. Take Ifflandstraße and Prinzregentenstraße to Tal in Altstadt-Lehel"
}
]
}
]
},
{
"index": 2,
"travel_mode": "driving",
"via": "A13 and A9",
"distance": {
"meters": 642658,
"text": "643 km"
},
"duration": {
"seconds": 24544,
"text": "6 hr 49 min"
},
"departure_time": null,
"arrival_time": null,
"country": [
"DE"
],
"legs": [
{
"distance": {
"meters": 642658,
"text": "643 km"
},
"duration": {
"seconds": 24547,
"text": "6 hr 49 min"
},
"traffic": {
"no_traffic": {
"seconds": 23811,
"text": "6 hr 37 min"
},
"traffic_level": 3,
"typical": {
"seconds": 21747,
"text": "6 hr 2 min"
},
"range": {
"min_seconds": 20883,
"max_seconds": 30841,
"text": "5 hr 48 min to 8 hr 34 min"
}
},
"destination": {
"name": "Munich",
"names": [
"Munich",
"Germany"
],
"end_point": {
"lat": 48.1351253,
"lng": 11.5819805
},
"timezone": "Europe/Berlin",
"timezone_abbr": "GMT+1"
},
"segments": [
{
"mode": "driving",
"distance": {
"meters": 5962,
"text": "6.0 km"
},
"duration": {
"seconds": 1085,
"text": "18 min"
},
"instruction": "Take Karl-Liebknecht-Str./B2/B5, Alexanderstraße, Holzmarktstraße, Köpenicker Str. and Schlesische Str. to A100 in Bezirk Treptow-Köpenick"
},
{
"mode": "driving",
"distance": {
"meters": 630471,
"text": "630 km"
},
"duration": {
"seconds": 22795,
"text": "6 hr 20 min"
},
"instruction": "Get on Schenkendorfstraße/B2R in Schwabing-Freimann, München from A13, A4, A72 and A9"
},
{
"mode": "driving",
"distance": {
"meters": 6225,
"text": "6.2 km"
},
"duration": {
"seconds": 667,
"text": "11 min"
},
"instruction": "Continue on B2R. Take Ifflandstraße and Prinzregentenstraße to Tal in Altstadt-Lehel"
}
]
}
]
}
]
}

Transit Output

In transit mode each segment is either a walk or one ride on a line. A ride carries the line, the vehicle type, the stops you board and leave at with their times, every stop in between, the operators, and any service alerts. This detail is present at both detail levels.

{
"mode": "transit",
"distance": null,
"duration": {
"seconds": 5400,
"text": "1 hr 30 min"
},
"instruction": "Train RJX 69 → Wien Hbf",
"transit": {
"line": "RJX 69",
"line_color": "#f01414",
"line_text_color": "#ffffff",
"headsign": "Wien Hbf",
"vehicle_type": "Train",
"vehicle_category": "train",
"departure_stop": {
"name": "Munich Central Station",
"platform": "München Hbf - Gleis 11",
"platform_code": null,
"coords": {
"lat": 48.1402037,
"lng": 11.5539314
},
"hex_id": "0x479e75fec5b151b9:0x43ec2bf2c2451cc2",
"arrival_time": null,
"departure_time": {
"text": "3:28 PM",
"timestamp": 1772375280,
"timezone": "Europe/Berlin",
"utc_offset_seconds": 3600,
"scheduled_timestamp": 1772375280
},
"address": null
},
"arrival_stop": {
"name": "Salzburg Hbf",
"platform": "Salzburg Hbf - Gleis 4",
"platform_code": "4",
"coords": {
"lat": 47.8128793,
"lng": 13.0457216
},
"hex_id": "0x47769078f3c7634f:0xfb02fe56aad5409c",
"arrival_time": {
"text": "4:58 PM",
"timestamp": 1772380680,
"timezone": "Europe/Vienna",
"utc_offset_seconds": 3600,
"scheduled_timestamp": 1772380680
},
"departure_time": null,
"address": null
},
"departure_time": {
"text": "3:28 PM",
"timestamp": 1772375280,
"timezone": "Europe/Berlin",
"utc_offset_seconds": 3600,
"scheduled_timestamp": 1772375280
},
"arrival_time": {
"text": "4:58 PM",
"timestamp": 1772380680,
"timezone": "Europe/Vienna",
"utc_offset_seconds": 3600,
"scheduled_timestamp": 1772380680
},
"num_stops": 1,
"intermediate_stops": [],
"agencies": [
{
"name": "DB Fernverkehr AG",
"phone": null,
"website": "https://www.bahn.de/",
"ticket_url": null,
"ticket_label": null
},
{
"name": "ÖBB",
"phone": null,
"website": "http://www.oebb.at/",
"ticket_url": null,
"ticket_label": null
}
],
"alerts": []
}
}
FieldDescription
modetransit for a ride, walking for a walk between stops.
transit.lineLine as shown on the vehicle, e.g. 56, M1, RJX 69.
transit.line_color / line_text_colorLine colours as hex, for rendering a badge.
transit.headsignDirection shown on the vehicle.
transit.vehicle_typeVehicle name in your chosen language, e.g. Autobus, Metropolitana.
transit.vehicle_categoryNormalised and language-independent: bus, subway, train, tram, or ferry. Use this to filter.
transit.departure_stop / arrival_stopStop name, platform, coordinates, place ID, and time.
transit.departure_time / arrival_timeTime for this ride, with text, Unix timestamp, timezone, and the scheduled time.
transit.num_stopsNumber of stops travelled on this line.
transit.intermediate_stopsEvery stop between boarding and alighting, each with its own times.
transit.agenciesOperators, with phone, website, and ticket link where published.
transit.alertsService alerts: strikes, reduced service, engineering work, with validity window and a link.

Routes also carry departure_time and arrival_time for the whole journey.

Use Cases

Logistics and Fleet Management

  • Route planning -- calculate distances and durations between warehouses, stops, and customers
  • Multi-stop optimization -- compare route alternatives for delivery sequences
  • Toll and highway avoidance -- estimate costs for routes that skip toll roads

Travel and Tourism

  • Itinerary building -- get walking times between attractions in a city
  • Transit planning -- find public transport connections with transfer counts
  • Accessibility -- plan wheelchair-accessible walking routes

Real Estate and Location Intelligence

  • Commute analysis -- measure driving/transit times from properties to offices
  • Location scoring -- compare accessibility across neighborhoods
  • Distance matrix -- build origin-destination tables for site selection

Research and Data Science

  • Transportation studies -- collect route data across cities and travel modes
  • Traffic analysis -- extract congestion levels and typical vs current travel times
  • Urban planning -- analyze pedestrian and cycling route availability

API Integration

Python

from apify_client import ApifyClient
client = ApifyClient("your_token")
run = client.actor("zen-studio~google-maps-directions").call(run_input={
"stops": ["Berlin, Germany", "Prague, Czech Republic", "Vienna, Austria"],
"travelMode": "driving",
"language": "en",
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
for route in item["routes"]:
print(f"Route {route['index']}: {route['via']} — {route['distance']['text']}, {route['duration']['text']}")

JavaScript / Node.js

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'your_token' });
const run = await client.actor('zen-studio~google-maps-directions').call({
stops: ['Berlin, Germany', 'Prague, Czech Republic', 'Vienna, Austria'],
travelMode: 'driving',
language: 'en',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const item of items) {
item.routes.forEach(r => console.log(`${r.via} — ${r.distance.text}, ${r.duration.text}`));
}

Advanced Usage

Avoid Tolls and Highways

{
"stops": ["Zurich, Switzerland", "Milan, Italy"],
"travelMode": "driving",
"avoidHighways": true,
"avoidTolls": true,
"distanceUnit": "km"
}

Transit with Specific Types

Prefer trains and subways, and prefer fewer transfers:

{
"stops": ["Heathrow Airport, London", "Kings Cross, London"],
"travelMode": "transit",
"transitTypes": ["train", "subway"],
"transitRoutePreference": "fewer_transfers"
}

Distance in Miles

{
"stops": ["New York, NY", "Boston, MA"],
"travelMode": "driving",
"distanceUnit": "miles",
"language": "en"
}

Multi-Stop Road Trip

{
"stops": [
"Amsterdam, Netherlands",
"Brussels, Belgium",
"Luxembourg City, Luxembourg",
"Strasbourg, France",
"Zurich, Switzerland"
],
"travelMode": "driving",
"avoidTolls": true,
"distanceUnit": "km",
"language": "en"
}

Returns 4 legs (Amsterdam-Brussels, Brussels-Luxembourg, Luxembourg-Strasbourg, Strasbourg-Zurich) with 2-3 route alternatives.

Arrive by a Specific Time (Transit)

{
"stops": ["Basel, Switzerland", "Barcelona, Spain"],
"travelMode": "transit",
"timeOption": "arrive_by",
"date": "2026-03-15",
"time": "18:00"
}

Depart at a Specific Time (Driving)

{
"stops": ["Vienna Opera", "Schoenbrunn Palace"],
"travelMode": "driving",
"timeOption": "depart_at",
"date": "2026-03-15",
"time": "09:00"
}

The timezone is automatically determined from the first stop's location. arrive_by is available for driving and transit modes only.

Data Export

Export results from the Apify Console in:

  • JSON -- full nested structure with all route detail
  • CSV -- flattened for spreadsheet analysis
  • Excel -- reporting and pivot tables

FAQ

How many route alternatives does it return? Google Maps typically returns 2-3 alternative routes per query. Each has its own distance, duration, and turn-by-turn instructions.

What's the maximum number of stops? 10 stops per run. The first stop is the origin, the last is the destination, everything in between are intermediate waypoints.

Do I need a Google account or API key? No. No login, no API key, no cookies.

How accurate are the travel times? Same data as Google Maps. Driving routes include real-time traffic estimates with typical and no-traffic durations.

Does it support all countries and languages? Yes. Any location that Google Maps can resolve, in 30+ languages. Set language to get localized street names and instructions — English, German, French, Spanish, Japanese, Chinese, Arabic, Korean, and many more.

Can I schedule a departure or arrival time? Yes. Set timeOption to depart_at or arrive_by, then provide date (YYYY-MM-DD) and time (HH:MM, 24-hour). The timezone is auto-detected from the first stop's location. arrive_by works with driving and transit only.

What travel modes are available? Driving, public transit, walking, and cycling. Each mode has its own route options (e.g., avoid highways for driving, wheelchair access for walking, preferred transit types for public transit).

Is there traffic data? Yes, for driving routes. Includes current duration, typical duration, no-traffic duration, congestion level, and a min/max time range.

What's in the Street View data? Each navigation substep includes a Street View panorama ID, thumbnail URL, and camera angle. Useful for visual route previews.

Is there a free trial? New Apify users get $5 in platform credits, enough for ~1,600 routes at no cost.

More Zen Studio scrapers for maps & local data

Disclaimer

Data is collected from publicly available sources and provided "as is" for informational purposes. Users are responsible for compliance with Google's terms of service and applicable regulations in their jurisdiction.


Start Scraping Google Maps Directions Now