← Back to all posts
Fuel Prices Cross-Border Cost Planning

Your Fuel Plan Uses One Diesel Price. Europe Publishes 41,614.

August 14, 2026 · updated August 27, 2026 · 10 min read

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:

CountryStations in NAPSPANCarrying a price
Italy45,42620,531
Spain22,89611,406
France10,8559,677
The other 35 countries~90,8000

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:

CountryPriced diesel pumps10th pctMedian90th 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:

RegionPriced diesel pumpsMedian 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:

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:

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:

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

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

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