Route planning parameters

calculateRoute takes these options besides its locations. All are optional, with the defaults given below.

Locations

locations is the only required parameter. It holds the ordered waypoints and paths the route passes through. Locations covers every accepted form.

import { calculateRoute } from '@tomtom-org/maps-sdk/services';
const routes = await calculateRoute({
locations: [
[4.9041, 52.3676], // Amsterdam
[2.3522, 48.8566] // Paris
]
});

Alternative routes

maxAlternatives – 0 (default) to 5 alternatives on top of the best route, which always comes first.

  • The service can return fewer alternatives than asked for.
  • Each alternative adds response time.
  • When two or more routes come back, each carries sections.distinct, the stretches no other route drives, and getImportantRoads names the roads on them.
  • On the map, the routing module draws one route as selected. See Route selection.
const routes = await calculateRoute({
locations: [[4.9041, 52.3676], [2.3522, 48.8566]],
maxAlternatives: 2 // up to 3 routes in total
});

Cost model

costModel decides which path wins.

routeType – What the route is optimised for:

  • fast – Travel time (default).
  • short – A compromise between travel time and distance.
  • efficient – A compromise between travel time and fuel or energy consumption.
  • thrilling – Interesting roads and as few motorways as possible, up to 900 km.

traffic – Which traffic the route plans around:

  • live – Live jams and closures on top of historical travel times (default).
  • historical – Historical travel times and long-term closures only. To tell which jams and closures a live route avoids, compare it with a historical one using compareRoutes.

avoid – What the route tries to avoid (nothing by default). If no other route exists, avoidance is not guaranteed:

  • tollRoads – Roads with a toll.
  • motorways – High-speed, limited-access roads.
  • ferries – Ferry crossings.
  • unpavedRoads – Unpaved roads.
  • carpools – Carpool (HOV) lanes.
  • alreadyUsedRoads – The same road twice, as delivery rounds need.
  • borderCrossings – International borders.
  • tunnels – Tunnels.
  • carTrains – Car trains.
  • lowEmissionZones – Zones with emission restrictions.

avoidAreas – Up to 10 rectangles to bypass, each a bounding box [west, south, east, north] or any GeoJSON whose bounding box is the rectangle:

  • At most ~160×160 km each.
  • Not crossing the 180th meridian, and between −80° and +80° latitude.
const routes = await calculateRoute({
locations: [[4.9041, 52.3676], [2.3522, 48.8566]],
costModel: {
routeType: 'efficient',
traffic: 'historical',
avoid: ['motorways', 'ferries'],
avoidAreas: [[2.265938, 48.81851, 2.41115, 48.90309]] // around Paris
}
});

A single leg can override routeType and avoid. See Per-stop options.

Departure and arrival time

when – Depart at, or arrive by, a given time (default: depart now). A past or unreachable time falls back to departing now. The response carries both times as summary.departureTime and summary.arrivalTime.

Give the time in one of two ways:

  • localDateTime - A wall-clock time as YYYY-MM-DDTHH:mm:ss, with seconds and no UTC offset.
  • date - An instant, as a Date. The SDK sends it in UTC.

localDateTime is a wall-clock time without an offset, read in the origin’s time zone. With arriveBy, it’s read in the time zone of the route’s destination instead. So your app needs no time zone table, wherever it runs. To leave Amsterdam at 9am and to reach Paris by 5pm Paris time:

const departing = await calculateRoute({
locations: [[4.9041, 52.3676], [2.3522, 48.8566]],
when: { option: 'departAt', localDateTime: '2026-12-24T09:00:00' }
});
const arriving = await calculateRoute({
locations: [[4.9041, 52.3676], [2.3522, 48.8566]],
when: { option: 'arriveBy', localDateTime: '2026-12-24T17:00:00' }
});

In TypeScript, a localDateTime you build at runtime needs as LocalDateTime, with each field padded to two digits. Request validation still checks the format at the call, and rejects a date that doesn’t exist, such as 2026-02-30.

To depart at a moment you already hold, such as one a user picked in their own time zone, pass it as date instead.

The demo below plans one trip for eight departures across the next weekday, in parallel. Pick a departure to draw its route.

Vehicle configuration

vehicle – Weight, heading and restrictions, all listed in Vehicle configuration.

  • travelMode takes only 'car', and weight is the only dimension. See Truck parameters.
const routes = await calculateRoute({
locations: [[4.9041, 52.3676], [2.3522, 48.8566]],
vehicle: { model: { dimensions: { weightKG: 3500 } } }
});

Turn-by-turn guidance

guidance: { type: 'coded' } adds instructions to each route. See Guidance.

Route sections

sectionTypes – Which sections the response carries. By default, it requests defaultSectionTypes: every type but curve and curvyStretch. A list narrows the response to those types, and [] asks for none.

Section typeRequested
carpool, carTrain, country, ferry, importantRoadStretch, lowEmissionZone, motorway, pedestrian, roadShields, speedLimit, toll, tollRoad, tollVignette, traffic, tunnel, unpaved, urban, vehicleRestrictedThrough sectionTypes
curve, curvyStretchOnly through a sectionTypes list that names them. The SDK finds them in the route’s geometry rather than asking the routing API
lanesOnly with guidance, and through sectionTypes when a list is given
legAlways
distinctAlways, when the response has two or more routes
  • A requested type only appears when the route traverses it (no ferry without a crossing).
  • Type a list you build as InputSectionTypes rather than SectionType[]: it leaves out leg and distinct, which the SDK adds itself.
  • On the map, Route sections covers how each is drawn.
const routes = await calculateRoute({
locations: [[4.9041, 52.3676], [2.3522, 48.8566]],
sectionTypes: ['toll', 'ferry', 'traffic', 'motorway', 'country']
});

To add types to the default rather than narrow it, spread defaultSectionTypes from core into the list:

import { defaultSectionTypes } from '@tomtom-org/maps-sdk/core';
const routes = await calculateRoute({
locations: [[4.9041, 52.3676], [2.3522, 48.8566]],
sectionTypes: [...defaultSectionTypes, 'curve', 'curvyStretch']
});

curveDetection – The thresholds the SDK finds curve and curvyStretch with. See Choose what counts as a curve.

Extended route information

extendedRouteRepresentations – Cumulative distance and travel time at points along the route, in the route’s progress property (default ['distance', 'travelTime']).

  • Any non-empty list returns both. [] leaves the progress out of the response.
  • Route progress utilities read it, for example the progress at a point, or the point at a given progress.
const routes = await calculateRoute({
locations: [[4.9041, 52.3676], [2.3522, 48.8566]],
extendedRouteRepresentations: [] // no progress data
});

Traffic-based travel times

computeTravelTimeFor – 'none' (default), or 'all' for three more travel times in the summary, to show what traffic costs or what leaving now saves:

  • noTrafficTravelTimeInSeconds – Free flow.
  • historicTrafficTravelTimeInSeconds – Historical traffic.
  • liveTrafficIncidentsTravelTimeInSeconds – Live traffic.
const routes = await calculateRoute({
locations: [[4.9041, 52.3676], [2.3522, 48.8566]],
computeTravelTimeFor: 'all'
});

To show the delay against free flow from these times, see the route summary.

Per-stop options

Any waypoint feature carries its own options in properties, typed with RouteStopOptions. They describe the leg arriving at that stop and the wait there, so if you insert an earlier stop, they stay attached to the right place.

  • pauseDurationSeconds – How long the vehicle waits at this stop.
    • It counts into the route’s travelTimeInSeconds, not only its arrival time.
    • It is rejected on the destination. On the origin, which no leg arrives at, the routing service never gets it, though the origin’s pin still shows it.
    • It is a core waypoint property, so RoutingModule.showWaypoints labels the stop’s pin with it.
  • legCostModel – routeType and avoid for the arriving leg only, falling back to the route-wide cost model. The origin, which has no arriving leg, ignores it.
  • candidateEntryPoints – Approach points for the routing engine to choose between, with an optional preferredEntryPointIndex. It takes precedence over useEntryPoints for this stop. The origin, which has no arriving leg, ignores both and follows useEntryPoints.
const routes = await calculateRoute({
locations: [
[2.1734, 41.3851],
{
type: 'Feature',
geometry: { type: 'Point', coordinates: [2.4467, 41.5381] },
properties: {
pauseDurationSeconds: 1800,
legCostModel: { routeType: 'short', avoid: ['motorways'] }
}
},
[2.8214, 41.9794]
]
});
const legs = routes.features[0].properties.sections.leg;
legs[0].summary.stopTimeInSeconds; // the whole time at the first stop
legs[0].summary.travelTimeInSeconds; // driving only

The wait comes back as the arriving leg’s stopTimeInSeconds. Leg travel times are driving only, while the route’s travel time includes every stop. What the routing SDK adds explains both.

In the demo below, each leg of a four-stop route takes its own route type and avoid list, and the panel shows the distance, driving time and wait each leg comes back with.

Arrival side

arrivalSide – Which side of the road to arrive on, at the destination and every intermediate stop, as one of the importable arrivalSides:

  • any – Either side, whichever is faster (default).
  • curb – The curb side for the country’s driving direction, so passengers or deliveries need not cross the road.
const routes = await calculateRoute({
locations: [[4.9041, 52.3676], [2.3522, 48.8566]],
arrivalSide: 'curb'
});

Entry points

useEntryPoints – Where a place waypoint with entry points is routed to:

  • main-when-available – Its main entrance, otherwise its first untyped entry point, as reverse geocoding returns them. A place with neither is routed to its geometry.
  • ignore – Its geometry, as when you leave it unset.
const routes = await calculateRoute({
locations: [origin, destinationPlace],
useEntryPoints: 'main-when-available'
});

For a stop with several usable entrances, candidateEntryPoints hands the alternatives to the routing engine instead of resolving one position client-side.

A parameter the endpoint cannot accept

calculateRoute() and calculateReachableRange() call two endpoints that do not accept the same parameters. The SDK never drops one silently. It either:

  • Narrows the type, so you can’t express the parameter. See the reachable range’s unsupported options.

  • Rejects the call at validation, with a message naming the parameter and what to do instead:

    vehicle.state.heading: calculateReachableRange has no vehicle heading parameter.
    Remove it, or use calculateRoute, which accepts it.

A request that dropped an input would still return a route with plausible numbers, computed from something other than what you asked for.

API reference