The fastest route and the cheapest route are rarely the same line on the map. In Europe the difference is usually tolls — and they come in two flavours that a passenger-car estimate gets wrong in opposite directions: distance-based tolls on the French autoroutes and Italian autostrade, and time-based vignette or Go-Box charges across the DACH region and Central Europe. For a 5-axle, 40-tonne truck, neither one looks like a car’s rate.
NAPSPAN’s routing endpoint returns the toll cost computed for the truck you’re actually moving. Opt in on a route request and you get back two things: a per-currency total for the whole trip, and a per-section breakdown naming each toll system and the fare that applies to your vehicle class.
Opt In With include
Toll pricing is opt-in, because computing it has an upstream cost — you only pay for it when you ask. Add "tolls" to the include array on POST /api/v1/routing/route:
curl -X POST "https://api.napspan.com/api/v1/routing/route" \
-H "X-API-Key: your_key" \
-H "Content-Type: application/json" \
-d '{
"origin": { "lat": 48.1351, "lng": 11.5820 },
"destination": { "lat": 45.4642, "lng": 9.1900 },
"currency": "EUR",
"truck": {
"profile": "tractor",
"weight_t": 40.0,
"height_m": 4.0,
"axle_count": 5
},
"include": ["tolls"]
}'
That’s Munich→Milan over the Brenner for a 5-axle, 40-tonne tractor — a trip that crosses an Austrian distance-toll section and the Italian autostrada network. The currency field (ISO 4217) controls what fares are reported in; the truck profile you already send is what makes the price the truck’s price.
The Response
Two places carry toll data. The route summary gets a toll_costs array — one entry per distinct currency, because a single trip can cross systems billed in different currencies (a route through Switzerland mixes EUR and CHF). Each route section gets a tolls array naming the systems charged on that stretch and the fares within them.
{
"routes": [
{
"summary": {
"distance_m": 492000,
"duration_s": 21600,
"toll_costs": [
{ "currency": "EUR", "value": 96.40 }
]
},
"sections": [
{
"distance_m": 184000,
"duration_s": 8100,
"summary": "A13 Brenner Autobahn (AT)",
"tolls": [
{
"system": "ASFINAG / Brenner",
"fares": [
{ "name": "Category 4+ (4+ axles)",
"price": { "currency": "EUR", "value": 49.10 },
"counted": true }
]
}
]
},
{
"distance_m": 308000,
"duration_s": 13500,
"summary": "A22 / A1 autostrada (IT)",
"tolls": [
{
"system": "Autostrade per l'Italia",
"fares": [
{ "name": "Class 5",
"price": { "currency": "EUR", "value": 47.30 },
"counted": true }
]
}
]
}
],
"geometry": { "type": "LineString", "coordinates": [ /* ... */ ] }
}
],
"route_id": "rt_9c40f2ab"
}
When one toll system lists several fares, they are alternatives, not line items — don’t add them up. Each is the same charge under a different payment method (payment_methods) or time window (applicable_times), and the driver pays exactly one of them. summary.toll_costs has already picked one fare per system — the electronic (on-board unit) tariff where one exists, otherwise the cheapest payment group — and marks it counted: true. That total is the number you’d quote a customer or drop into a lane-cost model; the sections[].tolls[] detail is where you see which operator charges what, so you can explain the bill.
Priced for the Vehicle, Not a Car
This is the whole point. The fare you get back is keyed to the truck profile on the request — axle count, gross weight, height, and the hazmat flag all factor into the toll category the engine prices against. A 5-axle combination doesn’t get a car’s rate; a heavy load doesn’t get a light-vehicle rate. The fares[].name echoes the category that was applied (e.g. “Category 4+”) so you can confirm the truck was rated the way you expected.
Routing Around Tolls
Sometimes the answer is to skip the toll road entirely. That’s a different field: put "toll_road" in the avoid array and the engine routes around toll facilities where it can. The avoidance applies to every route in the response, so on its own it only shows you the detour.
To see the trade-off, ask for it instead: add "toll_alternative" to include (it implies "tolls"). You get the fast tolled route as usual, plus a second, toll-free route on toll_alternative with its extra distance and time set against the toll it saves — the decision made explicit instead of a guess.
{ "origin": { /* ... */ }, "destination": { /* ... */ },
"truck": { /* ... */ },
"include": ["toll_alternative"] }
It computes two routes, so it is billed as two routing calls. Full shape in the API docs.
What to Expect From the Data
A few honest notes so the numbers behave the way you expect:
- Distance-toll motorways price well — French autoroutes, Italian and Spanish autostrade/autopistas, Austrian sectional tolls, and similar network operators return per-category truck fares reliably.
- Vignette and box systems are time- or registration-based. Where a country charges by vignette or an on-board unit rather than per trip, a route may surface the system without a clean per-trip fare — treat a missing
priceas “not priced here,” not “free,” and account for the periodic vignette separately. - Send
departure_timefor an exact figure. Some tolls change by time of day. Without a departure time the engine can’t resolve which window applies, and the total is the worst case for the chosen payment method rather than an optimistic one. - It’s a planning estimate. Toll pricing is computed at request time for the route and vehicle class; it’s built for dispatch and quoting, not for reconciling an operator statement to the cent.
- No tolls, no array. A toll-free route, or a request that didn’t opt in, simply omits
toll_costsand sectiontolls— the response shape stays stable.
One Call, the Whole Trip
Toll pricing rides the same POST /api/v1/routing/route as the corridor hazard warnings[] and the driving-time break planning. A single cross-border request (DE → AT → IT in one query) can hand back a drivable truck route, the closures and restrictions on it, where the driver must legally stop, and what the trip costs in tolls — the operational picture a dispatcher actually needs before the truck rolls. Routing is a paid-plan feature with a free 14-day trial.
Try It
- API docs — full request and response reference for
POST /api/v1/routing/route - Live map — explore the underlying data across European NAPs
- Free API key — no card, 14-day trial
Know the toll bill before you dispatch
Add one word to your route request and get the truck’s real toll cost across Europe — total and per-section, priced for its weight, axles, and category. Free 14-day trial. No card.
Get Free API Key Explore the Map