Diesel is the largest variable cost on almost every European haul, and it is the one a planner can actually move. Tolls are set by the route. Driver hours are set by 561/2006. Fuel is set by where the truck stops — and that decision is usually made against a single national average published once a week.
That average is not a price. It is a statistic computed over prices, and no station in Europe charges it. The gap between the statistic and the pump is where the money is, and it is bigger than most planning tools assume.
Everything below was measured in a single query against NAPSPAN production at 10:10 UTC on 27 August 2026. Fuel prices move daily, so treat the figures as a dated observation and re-run the queries yourself — each one is a live API call, not a number we are asking you to trust.
Three Countries Publish the Pump. Thirty-Five Publish the Building.
NAPSPAN carries 169,986 active fuel stations across 38 European countries. Of those, 41,614 carry an actual price, and they come from exactly three national registers:
| Country | Stations in NAPSPAN | Carrying a price |
|---|---|---|
| Italy | 45,426 | 20,531 |
| Spain | 22,896 | 11,406 |
| France | 10,855 | 9,677 |
| The other 35 countries | ~90,800 | 0 |
That is the honest shape of European per-station fuel data, and it is worth internalising before anyone scopes a project around it. Everywhere else — Germany, Poland, the Netherlands, the Nordics, the whole of the Balkans — a European fuel layer means locations. Where the forecourt is, what brand is on the sign, sometimes the opening hours. Not what it costs. We say why further down, because the reason is not technical.
Why the Average Hides the Decision
Take the base diesel grade in each of the three priced countries at the snapshot moment. Not the cheapest headline, not the outliers — the 10th percentile, the median and the 90th percentile of every priced station in the country:
| Country | Priced diesel pumps | 10th pct | Median | 90th pct |
|---|---|---|---|---|
Spain (gasoleo_a) | 11,194 | €1.727 | €1.899 | €1.979 |
Italy (gasolio_self) | 19,222 | €2.095 | €2.139 | €2.184 |
France (gazole) | 9,630 | €2.177 | €2.232 | €2.299 |
One note on the Spanish column before anyone plans a route with it: the Canary Islands, Ceuta and Melilla sit well below the peninsula and are not reachable by road from anywhere in this post. Their effect on the figure is small — drop the Canaries and the Spanish 10th percentile moves from €1.727 to €1.741 — but it is the kind of thing worth knowing you have in your denominator.
Read the medians across the rows and the first lever appears: €0.333 per litre between the French and Spanish medians. On a 600-litre fill that is €200, decided entirely by which side of a line the driver stops on.
National medians are still an abstraction, though, so narrow it to the regions on either side of the Pyrenean crossings:
| Region | Priced diesel pumps | Median diesel |
|---|---|---|
Navarre (ESP-NC) | 236 | €1.794 |
Catalonia (ESP-CT) | 1,449 | €1.895 |
Aragon (ESP-AR) | 418 | €1.905 |
Basque Country (ESP-PV) | 342 | €1.939 |
Nouvelle-Aquitaine (FRA-NAQ) | 1,126 | €2.206 |
Occitanie (FRA-OCC) | 1,092 | €2.249 |
Occitanie to Navarre is €0.455 per litre — roughly €273 on a 600-litre fill, over a distance a truck covers inside a single driving period. No weekly national figure on either side of the border contains that fact.
And there is a second lever that sits entirely inside one country. French stations are tagged with the road class they sit on. At the snapshot:
- 431 French stations on the autoroute network — median
gazole€2.340. - 9,199 French stations off it — median
gazole€2.229.
An €0.111 per litre motorway premium, or about €67 a fill. A truck routed down an autoroute passes the expensive 431 by default; the cheaper 9,199 are the ones you have to deliberately look for, which requires knowing where they are and what they charge before dispatch, not after the fuel card statement arrives.
One /features Call, Prices Included
Per-station prices arrive in the same fuel_stations feature type as every other forecourt in the system, filtered the same way as any other layer:
curl -H "X-API-Key: $KEY" \
"https://api.napspan.com/api/v1/features?type=fuel_stations&jurisdiction=FRA-IDF"
{
"data": [
{
"feature_type": "fuel_stations",
"jurisdiction": "FRA-IDF",
"name": "180 Rue d'Herblay, Taverny",
"properties": {
"city": "Taverny",
"region": "Île-de-France",
"highway_type": "R",
"prices": {
"gazole": {
"value": 2.179,
"unit": "litre",
"currency": "EUR",
"label": "Gazole",
"updated": "2026-08-27T07:32:05+00:00"
},
"sp95": { "value": 2.059, "unit": "litre", "currency": "EUR", "label": "SP95", "updated": "2026-08-27T07:32:05+00:00" },
"sp98": { "value": 2.1, "unit": "litre", "currency": "EUR", "label": "SP98", "updated": "2026-08-27T07:32:05+00:00" }
},
"fuels_available": ["Gazole", "SP95", "SP98"],
"fuels_unavailable": ["E85", "GPLc", "E10"]
}
}
]
}
Note fuels_unavailable in passing: the French register also states which grades a station is currently out of, which is a different and occasionally more urgent fact than what it charges.
Three things about that payload will save you a week each.
1. There is no diesel key
Diesel is gazole in France, gasoleo_a in Spain, and gasolio_self in Italy — and those are just the base grades. Across the three registers the snapshot counts 128 distinct grade keys: 6 in France, 14 in Spain, and 108 in Italy, where branded premium diesels are reported as separate products under their marketing names. Any integration that looks up a hard-coded "diesel" field returns nothing in all three countries.
We keep the national keys rather than flattening them, because flattening loses information you need — a premium diesel is not the same product as the base grade, and pricing a fleet fill against the wrong one is a real error. Map the base grades once, ignore the rest, and you are done.
2. In Italy the same pump has two prices
12,220 Italian stations publish both a self-service and an attended diesel price, and the median difference between them is €0.190 per litre — with a maximum, at one site, of €0.884. That is €114 on a 600-litre fill riding on which of two keys you happened to read.
It is the most expensive misreading this dataset makes available, and it is invisible if you assume one station means one price. gasolio_self and gasolio_servito are different products at the same address.
3. Freshness is not uniform, and we do not paper over it
Each price carries its own updated stamp where the source publishes one, separate from when we polled. That matters because the three registers do not move at the same speed. At the snapshot:
- France — all 9,630 priced diesel pumps carry a per-price timestamp. The median observation was from 06:33 UTC the previous day; 5,360 of them had been updated within 48 hours.
- Italy — all 19,222 carry a timestamp, but the newest was 25 August 08:02 UTC and the median 24 August 10:14 UTC. Italian prices ran roughly two to four days behind. Not one was inside 48 hours — the same gap this post measured a fortnight earlier, so treat it as the register’s cadence rather than a bad day.
- Spain — publishes no per-price timestamp at all. You know when we last polled and nothing about when the operator last changed the number.
So read updated and age the value out on your own threshold. An Italian price is directionally right and a few days old; a French one is usually same-day; a Spanish one is undated and must be treated accordingly. We would rather hand you the stamp and let you decide than stamp everything with our poll time and imply a freshness we did not measure.
One caveat on that field, since it is the kind of thing that silently breaks an alert: the French stamps track the source's own publication clock, not true UTC. At this snapshot 366 of the 9,630 French stamps sat in the future relative to our wall clock, the furthest ahead by 50 minutes. Compare these timestamps to each other, and do not build a “stale if older than n minutes” rule that assumes they are synchronised with yours.
Querying by place
And one more that costs an afternoon if you meet it in production: the stamp is not the same format in both countries that publish one. France emits ISO 8601 with an offset (2026-08-27T07:32:05+00:00); Italy emits 25/08/2026 08:02:02 — day-first, space-separated, no timezone at all. We hand both through as the register wrote them rather than silently reinterpreting a date we cannot verify the zone of, so a parser pointed at ISO will throw on all 19,222 Italian rows. Parse per country, and read an Italian stamp as local time.
France and Spain are keyed by region — 14 French and 19 Spanish subdivision codes carry priced stations (FRA-OCC, ESP-CT, and so on). Italy is a single national code, ITA. The bare country codes FRA and ESP are separate jurisdiction rows of their own, not parents, and they do not roll up their regions. At the snapshot, ESP held 11,490 records with no price on any of them, and FRA held 1,061 records of which exactly 5 carried a price. That second number is the dangerous one: a query on jurisdiction=FRA returns five priced stations out of the country’s 9,677, so it neither errors nor comes back empty — it comes back looking like it worked. Use the regional codes, or skip codes entirely and ask spatially:
curl -H "X-API-Key: $KEY" \
"https://api.napspan.com/api/v1/features?type=fuel_stations&lat=43.60&lng=1.44&radius_km=50"
Where It Belongs: On the Route
Querying a region is the analysis path. The one that changes a fuel bill is prices arriving already attached to the route the truck is driving.
Fuel stations are a dense layer — mapped at essentially every interchange — so they ride a dedicated, lazy endpoint rather than the synchronous routing call. Compute a truck route, then ask for what is on it:
curl -H "X-API-Key: $KEY" \
"https://api.napspan.com/api/v1/routing/route/saved/$ROUTE_ID/features?types=fuel_stations&buffer_m=300"
{
"route_id": "01HKZ9P5XJVQ6NB8E2RTH4FMW7",
"features": [
{
"type": "fuel_station",
"name": "180 Rue d'Herblay, Taverny",
"distance_along_route_m": 56200,
"detour_m": 120,
"side": "left",
"source": "FRA-IDF",
"properties": {
"city": "Taverny",
"highway_type": "R",
"prices": { "gazole": { "value": 2.145, "currency": "EUR", "updated": "..." } }
}
}
]
}
Every match carries distance_along_route_m (how far along the route it sits), detour_m (how far off the line it is) and side (left or right of the direction of travel) — the three fields that turn a list of nearby stations into a refuelling plan, because a cheap pump on the wrong carriageway is not cheap. The station's full properties, prices included, pass through untouched. The call does not re-run the routing engine and does not count against routing quota.
It rides the same corridor as the toll cost, the truck bans and VMS signs, the live parking occupancy and the border queues. One route, and the answer to what will this trip cost and where does it stop comes back with it.
What You Cannot Get, and Why It Is Not a Coverage Gap
The obvious question about a three-country fuel layer is why it is only three countries. The answer is worth publishing, because the constraint is legal rather than technical and every team that scopes this project discovers it the expensive way.
Per-station prices exist in most of Europe. Reusing them commercially mostly does not:
- Germany — prices are collected by the official market-transparency unit for fuel. Redistributing them requires authorisation as a consumer information service under German competition law. That is an application, not an API key, and until it exists Germany stays a roadmap item.
- Austria — the public price service is shaped by regulation to return only the five cheapest stations per query, with no national bulk endpoint. A complete per-station layer is not merely restricted; it is impossible by design.
- Portugal — per-station prices are published on a portal whose terms prohibit commercial use. The openly licensed distribution of the same dataset carries locations and metadata, without the prices.
- Croatia — prices are shown on a ministry website; a formal request for a machine-readable open-data release was refused.
- Lithuania — the national energy agency publishes strong daily per-station data and marks it all rights reserved.
- Switzerland and Iceland — no government per-station feed exists at all. What circulates is a motoring-club product in one case and a community scrape of oil-company sites in the other. Neither is licensed for redistribution.
A handful are genuinely open and simply not built yet — Cyprus publishes under a share-alike licence, Slovenia publishes without stating one, and Denmark's per-brand publication became a legal obligation on 1 January 2026. Those are engineering work. The list above is not.
We would rather show you that map than colour in a continent and let you find out at integration time. A vendor claiming European per-station fuel coverage is either doing something we have concluded we cannot lawfully do, or is showing you locations and calling them prices.
The Honest Limits
- Three countries. That is the coverage. France, Spain, Italy. The other 35 countries in the fuel layer are locations only. If your corridor is Rotterdam–Warsaw, this feature does nothing for you today, and we would rather say so now.
- Not every station in those three is priced. Italy is 20,531 of 45,426 and Spain 11,406 of 22,896 — the remainder are location records from the open map layer that the national registers do not cover. The absence of a
pricesobject means unpriced, never free. Your code needs that third state. - Italian prices lag. Two to four days behind at the snapshot. Good enough to choose between two regions, not good enough to promise a driver a number at the pump.
- Spanish prices carry no observation time. You have our poll time and nothing else.
- These are retail posted prices. They are not your fuel-card contract price, and no register publishes negotiated fleet rates. The spread between regions and road classes is a real signal about where to buy; the absolute figure on your invoice will be your own.
- A price is a snapshot, not a forecast. The medians above are what 27 August looked like. Re-pull before you rely on them — and if a number in this post matters to your decision, the API call that produced it is printed above precisely so you can check whether it still holds.
The Common Thread
This is the same shape as the five road-data problems every cross-border European fleet hits, and as the useful road data that lives outside the National Access Points. Three governments publish something genuinely valuable, properly, under open licences. They publish it in three different schemas, with three different words for diesel, on three different cadences, with three different attribution obligations — and one of them counts the same pump twice on purpose. Doing that join once per country, and then keeping it working, is a permanent maintenance commitment that competes with whatever you actually sell.
NAPSPAN does the join once. The prices are open data and the credit travels with every record we hand you: French data under Licence Ouverte, with the Ministères économiques et financiers as licensor; Spanish data as Origen de los datos: Ministerio para la Transición Ecológica y el Reto Demográfico; Italian data as Dati: Ministero delle Imprese e del Made in Italy (MIMIT) — Osservaprezzi Carburanti, under the Italian Open Data Licence 2.0. Station locations outside the priced registers come from OpenStreetMap under ODbL. Every source is licence-classified before it ships, and the ones that fail that check are the countries listed above — which is why they are absent rather than quietly included.
Try It
- API docs —
/featureswithtype=fuel_stations, and/routing/route/saved/{id}/featureswithtypes=fuel_stations - Live map — the priced networks as they stand right now
- Free API key — no card, 14-day trial
Stop budgeting fuel against a number nobody charges
Per-station diesel and petrol prices for France, Spain and Italy — on the corridor, with the toll cost, the truck bans and the parking, in one API. Free 14-day trial. No card.
Get Free API Key Read the Docs