Regulation (EC) 561/2006 is arithmetic. Four and a half hours of driving, then a 45-minute break. Nine hours a day, eleven twice a week, a daily rest of at least eleven hours. Every planning tool worth the name can compute where the clock runs out, and ours does it too.
The regulation says nothing about whether there is anywhere to put the truck.
That is the part dispatchers actually lose sleep over, because the failure mode is not a fine — it is a driver at 21:30 standing in the entrance of a full lorry park, choosing between the hard shoulder and driving on illegally. And it is a genuinely hard problem to plan around, because the map is misleading in a very specific way: the lot does not disappear when it fills up. Every static inventory keeps showing it, at full size, all night.
“Is There a Lorry Park?” Is the Wrong Question
Take Austria, where we have bay-level truth to check the map against.
The static inventory says the ASFINAG motorway and expressway network carries 241 truck-parking sites with 9,135 truck bays. That is the number a coverage map shows, and it is correct. It is also useless after dark, because it describes the concrete, not the availability.
Of those, 86 sites — 5,851 truck bays — publish live occupancy, which we poll every 60 seconds. We have been recording every change for those sites since 30 June 2026: roughly 119,000 observations over thirty days. Bucketing that history by hour of day produces the curve that the static map cannot show you.
| Local time (Austria, CEST) | Bays occupied | Avg. free bays per site |
|---|---|---|
| 08:00 – 14:00 | ~40% | ~43 |
| 17:00 | 55.2% | 33.3 |
| 19:00 | 70.2% | 23.4 |
| 21:00 | 76.9% | 18.6 |
| 22:00 (peak) | 77.8% | 18.1 |
| 00:00 – 04:00 | ~76–77% | ~19 |
Network-wide occupancy roughly doubles between late morning and 22:00 and then holds on that plateau until about four in the morning. Read as a fleet average, that still sounds survivable — 77% occupied means 23% free, and 18 open bays per site is not nothing.
That average is the trap. Occupancy does not distribute itself politely across the network; it concentrates, and individual lots go hard to zero:
- 57 of the 86 live sites hit zero free bays at some point in the thirty-day window.
- At 23:00 local, 47 of 83 sites observed in that hour had been completely full at least once during the window. At 06:00 local, only 2 had.
- Take one ordinary lot — Wiener Neustadt, 40 truck bays. Average free bays at 07:00 local: 21.1. At 20:00 local: 1.9. From 18:00 local onward, every hourly bucket has a recorded minimum of 0.
Wiener Neustadt is not an exceptional site. It is a normal one, and for the entire second half of the evening its honest answer to “can my driver stop here?” is probably not, and you should have known that at dispatch.
Meanwhile the same network at 09:08 local on 30 July looked completely relaxed: zero of 86 sites full, only two down to their last two bays. Arnoldstein at the Italian border was sitting at 12% occupancy with 352 of its 402 truck bays open. Both pictures are true. They are eleven hours apart. A number that is right at breakfast and wrong at bedtime has to be read live, or it is not worth reading.
Live Occupancy, in the Same /features Call as Everything Else
ASFINAG publishes this as two DATEX II documents: a static ParkingTablePublication describing the sites, and a dynamic ParkingStatusPublication carrying free-space counts. Neither is usable alone — the status document has no geometry, and the table has no occupancy. We join them on parkingRecordReference and publish one feature per site with the live counts folded in:
curl -H "X-API-Key: $KEY" \
"https://api.napspan.com/api/v1/features?type=truck_parking&jurisdiction=AUT"
{
"data": [
{
"id": "AUT-tp-PARK000064",
"source": "AUT",
"jurisdiction": "AUT",
"feature_type": "truck_parking",
"name": "Arnoldstein Zollamt",
"latitude": 46.540813,
"longitude": 13.670096,
"is_active": true,
"properties": {
"truck_parking": true,
"capacity": 431,
"truck_spaces": 402,
"available_spots": 352,
"occupied_spots": 50,
"occupancy_pct": 12,
"occupancy_status": "spacesAvailable",
"opening_status": "open",
"occupancy_updated": "2026-07-30T07:01:44Z"
},
"last_updated": "2026-07-30T07:08:00Z"
}
]
}
Three details in that payload matter more than they look:
truck_spacesis the denominator, notcapacity. Arnoldstein has 431 spaces of which 402 take a lorry, andavailable_spotscounts truck bays only. Divide bycapacityand you will quietly under-report how full the truck side is at every mixed site on the network.available_spots: 0is a fact, not a gap. It means known full. A site with no live feed omits the field entirely. Those two states must not collapse into one in your code — treat “absent” as unknown and “0” as closed to you.occupancy_updatedis the count’s own timestamp, separate fromlast_updated, so you can age out a stale reading on your own threshold rather than trusting our poll cycle.
And the jurisdiction code is ISO 3166-1 alpha-3. ?jurisdiction=AUT, never AT — the two-letter form is not an alias, it returns an empty result set.
The Trend: “Is This Lot Typically Full at My ETA?”
A live count answers a question about now. Dispatch plans a stop for six hours from now, when the live count will have changed. That gap is what the per-hour history is for, and it comes back on the feature-detail endpoint:
curl -H "X-API-Key: $KEY" \
"https://api.napspan.com/api/v1/features/AUT-tp-PARK000402/details"
{
"data": { "id": "AUT-tp-PARK000402", "name": "Wr. Neustadt", ... },
"availability_trend": [
{ "hour": 5, "avg_available": 21.1, "avg_capacity": 71, "samples": 71 },
{ "hour": 12, "avg_available": 14.6, "avg_capacity": 71, "samples": 75 },
{ "hour": 18, "avg_available": 1.9, "avg_capacity": 71, "samples": 30 },
{ "hour": 20, "avg_available": 2.2, "avg_capacity": 71, "samples": 24 }
]
}
Twenty-four buckets, built from the trailing thirty days of recorded occupancy for that specific lot. It is the difference between “there are two bays free right now” and “this lot has been down to single digits every evening for a month” — and only the second one is actionable at 14:00 when you are deciding where the driver sleeps.
Two things to know before you plot it. Hours are UTC; Austria ran at UTC+2 across this window, so bucket 18 is 20:00 on the driver’s dashboard clock — localize before you show it to a human. And samples is there to be read: buckets are recorded on change, so a thin bucket deserves less confidence than a fat one. We publish the count rather than smoothing it away.
Where It Actually Belongs: On the Route, Next to the Break
Querying a lot by id is the debugging path. The one that changes an evening is that occupancy arrives already attached to the route, and to the break the regulation demands.
Send a normal truck route to POST /api/v1/routing/route with include_features: ["truck_parking"], and parking comes back in the features[] channel — distinct from hazard warnings[], opt-in, and costing nothing when you do not ask for it:
{
"features": [
{
"type": "truck_parking",
"name": "Wr. Neustadt",
"distance_along_route_m": 184000,
"detour_m": 240,
"side": "right",
"available_spots": 3,
"capacity": 40,
"as_of": "2026-07-30T18:02:11Z",
"source": "AUT",
"geometry": { "type": "Point", "coordinates": [16.2, 47.8] }
}
]
}
Then add an hos block with the driver’s clock and ruleset: "eu_561", and the response gains an hos[] projection: where the break falls, and which parking is reachable before the limit rather than after it. Where a feed publishes live occupancy, two things follow that a static inventory can never do:
- Reachable parking is ordered by open spaces, so the first suggestion is the one most likely to still have room, not merely the nearest concrete.
- The stop is flagged
feasible: falsewhen every reachable lot reports full. That is the alert worth having. It fires at planning time, in an API response, hours before it would otherwise arrive as a phone call from a lay-by.
It rides the same request as the corridor’s truck bans and VMS signs, its toll costs, its border queues, and the 561/2006 break plan itself. One call returns a drivable truck route, the rules that would stop it, what it costs, where the driver must legally rest — and whether there will be a bay there when they arrive.
What This Data Does Not Do
The honest limits are part of the product, so here they are without decoration.
- Most national feeds publish inventory, not occupancy. Of the European truck-parking feeds NAPSPAN carries, only a minority publish live counts at all — Slovenia, the Netherlands, Bavaria and Latvia all hand us sites and capacities with no availability whatsoever, and the same is true of most of the general
parkingfeeds. Austria is the network this post is built on because it is the one where the live layer is both complete enough to reason about and cleared for redistribution under an open licence. We would rather name the gap than colour in a map that implies coverage we do not have. - Even in Austria it is 86 of 241 sites. The other 155 are real lots that appear with capacity and no counts. Your UI needs a third state — free / full / not reporting — and the absence of
available_spotsis what selects it. - Thirty days of history is thirty days. The Austrian series starts 30 June 2026 and the trend endpoint looks back thirty days, so today the window is the whole record. It has no seasonality in it yet, and an August holiday pattern is not a February one. It will get better on its own; it is not better yet.
- A free bay is not a reserved bay. Nothing here books anything. It tells you what the operator reported and when, which is what you need to choose between two lots — not a guarantee that the space survives the next twenty minutes.
- The trend is a prior, not a prediction. An hour-of-day average over thirty days is a solid base rate and it is blind to the specific Thursday your driver is having. Use it to rank candidates and to know when the network tightens; use the live count for the final call.
The Common Thread
This is the same shape as the five road-data problems every cross-border European fleet hits. The information exists. A public authority publishes it, properly, under an open licence. It arrives split across two DATEX II documents that have to be joined on a reference key, in a national profile, on its own cadence — and doing that once per country, forever, is a maintenance commitment that competes with the product you actually sell.
NAPSPAN does that join once. Austrian bay counts arrive in the same truck_parking schema as every other parking feed in the system, filterable by jurisdiction, carried on the route beside the tolls and the rest breaks, served from Europe, and licence-classified before it ships. The Austrian data is published by ASFINAG under CC BY 4.0 — Datenquelle: ASFINAG — licensed under CC BY 4.0 — and that credit travels with every record we hand you.
Try It
- API docs —
/featureswithtype=truck_parking,/features/{id}/detailsfor the trend, andPOST /routing/routewithinclude_features - Live map — the Austrian network as it stands right now
- Free API key — no card, 14-day trial
Find the full lorry park at 14:00, not at 21:30
Live bay-level occupancy, per-hour occupancy history, and 561/2006 break planning that orders reachable parking by open spaces — in one API call. Free 14-day trial. No card.
Get Free API Key Read the Docs