# Fuel Prices Scraper & API: Spain, France, EU Open Data (`ocius-data/fuel-prices-official`) Actor

Official fuel prices for every station in Spain and France, current and historical, plus weekly EU averages by country. AI agents ready via MCP.

- **URL**: https://apify.com/ocius-data/fuel-prices-official.md
- **Developed by:** [Ocius Data](https://apify.com/ocius-data) (community)
- **Categories:** Travel, Business, Agents
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.11 / 1,000 price records

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Fuel Prices Scraper & API: Spain, France, EU Open Data

Every station price comes already compared with its area: the area average, the lowest price, its rank (1 = cheapest) and how far it sits from the average, plus a free `INSIGHTS` record with the cheapest station per area and fuel.

**Fuel Prices API** returns official fuel prices published by governments as open data. You get **every petrol station in Spain and France** with its price for diesel, gasoline 95 and 98, E10, E85, LPG, CNG, LNG, hydrogen and AdBlue, current or historical, with address and coordinates. You also get the **weekly national average** for every EU member state from the European Commission. Each row is one price observation (one fuel at one station or country on one date) and carries its source and licence. You pay only for price records saved to the dataset.

### What this fuel price scraper does

- **Station prices for Spain:** about 11,800 stations from the Ministry for the Ecological Transition (MITECO). The Ministry refreshes the data every 30 minutes, and daily snapshots go back to 2007.
- **Station prices for France:** about 9,800 stations from the government site prix-carburants.gouv.fr. The live feed refreshes every 10 minutes, and daily end-of-day files cover about the last 30 days.
- **National averages for the EU-27:** weekly average consumer prices with taxes for 27 countries, plus the EU and euro-area averages, from the European Commission Weekly Oil Bulletin. The series start in 2005.
- **Search by area:** filter by province, autonomous community, department or French region, by postal code prefix, or by radius around a point. Radius results are sorted by distance and include `distanceKm`.
- **One row per price, with attribution:** every row includes the source, the source URL, the licence and a ready-to-use attribution sentence.
- **Price compared with the area, on every row:** `areaAveragePrice`, `areaMinPrice`, `priceVsAreaAverage`, `priceVsAreaAveragePercent` and `priceRankInArea` compare each station with the other stations of the same province, department or search radius, for the same fuel and date. The run's status message names the cheapest station of the largest areas with real figures from that run.
- **Free `INSIGHTS` record:** per country, area and fuel, the cheapest and the most expensive station, average, median, spread and, for history runs, the change of the average over the period.
- **Data-quality flags:** `dataQuality` (`good` or `check`) and `warnings` mark prices that were not updated for 3 days, prices far from the area average and stations without coordinates.
- **More station details at no extra cost:** normalised `brand` (Spain), opening hours and a 24/7 pump flag (Spain and France), station services (France), road side and supply type (Spain).
- **Fair billing:** one `price-record` event per row saved. Failed requests, dates the source no longer keeps, the insights and the run summary are free.

### Use cases

- **Fleet and logistics:** find the cheapest diesel near depots and along routes, and track fuel cost per region.
- **Price comparison apps and maps:** feed station prices with coordinates into an app or a dashboard.
- **Market analysis:** compare brands, regions and countries over time, and study pass-through and price dispersion.
- **Finance and research:** weekly national series for all EU countries since 2005, in euros per litre.
- **Monitoring:** schedule a daily run and alert when prices in an area move.

### How to use it

1. Select the **countries**. ES and FR return station prices; any other EU code returns the national average.
2. Select the **fuel types**, or leave the list empty to get every fuel.
3. Optional: limit the area with **regions**, **postal codes** or **latitude, longitude and radius**.
4. Optional: set **History (days back)** or a **start and end date**, and a daily or weekly interval.
5. Click **Start**, then read the **Prices**, **Price vs area average**, **Stations and location**, **National averages (EU)** or **Source and licence** views, or download JSON, CSV or Excel. The **Output** tab also links the Prices view as a CSV file and the `INSIGHTS` record.

| Option | Default | What it does |
|---|---|---|
| `countries` | `["ES"]` | ES and FR return stations. AT, BE, BG, CY, CZ, DE, DK, EE, FI, GR, HR, HU, IE, IT, LT, LU, LV, MT, NL, PL, PT, RO, SE, SI and SK return national averages. EU and EUR return the weighted EU and euro-area averages. |
| `fuelTypes` | all | `diesel`, `diesel_premium`, `diesel_agricultural`, `renewable_diesel`, `biodiesel`, `gasoline95`, `gasoline95_premium`, `gasoline95_e10`, `gasoline98`, `gasoline98_e10`, `e85`, `bioethanol`, `lpg`, `cng`, `lng`, `hydrogen`, `adblue`, `heating_oil`. |
| `dataLevel` | `stations` | `stations`: station prices for ES and FR, national averages for the others. `national`: national averages only, ES and FR included. `both`: station prices and national averages. |
| `regions` | — | Spain: a province or autonomous community, for example `Madrid`, `Barcelona` or `Andalucía`. France: a department code or name, or a region, for example `75`, `Gironde` or `Bretagne`. Add the country prefix to target one country, for example `ES:Sevilla` or `FR:69`. |
| `postalCodes` | — | A full postal code or its first digits, for example `28001` or `75`. |
| `latitude`, `longitude`, `radiusKm` | radius 10 | Returns only stations within the radius, sorted by distance. |
| `historyDays` | 0 | `0` returns current prices. `1` to `366` returns one snapshot per day or per week, from that many days ago until today. |
| `startDate`, `endDate` | — | An exact date range in `YYYY-MM-DD` format. It overrides `historyDays`. Station data accepts up to 366 days per run; national averages accept any range since 2005. |
| `historyInterval` | `daily` | `weekly` returns one station snapshot every 7 days, counting back from the end date. |
| `maxPriceAgeDays` | 30 | Leaves out station prices that were not updated for this many days before the snapshot date, which removes stations that stopped reporting. `0` keeps every price. |
| `maxRecords` | 10,000 | The run stops after this many rows. |

Example: diesel within 5 km of central Barcelona, once a week for the last month.

```json
{
  "countries": ["ES"],
  "fuelTypes": ["diesel"],
  "latitude": 41.3874,
  "longitude": 2.1686,
  "radiusKm": 5,
  "historyDays": 28,
  "historyInterval": "weekly"
}
```

Example: weekly diesel and gasoline averages for Germany, Italy and Poland in 2025.

```json
{
  "countries": ["DE", "IT", "PL"],
  "fuelTypes": ["diesel", "gasoline95"],
  "dataLevel": "national",
  "startDate": "2025-01-01",
  "endDate": "2025-12-31"
}
```

### Output example and field dictionary

Every row has a `recordType`: `stationPrice` (one station, Spain or France) or `nationalAverage` (one EU country, weekly). Runs with both types open on the **Prices** view, which shows the columns common to both.

Example station row:

```json
{
  "recordType": "stationPrice",
  "level": "station",
  "country": "ES",
  "countryName": "Spain",
  "stationId": "9020",
  "stationName": "GRATSA",
  "brand": "GRATSA",
  "isKnownChain": false,
  "address": "CASANOVA 23",
  "city": "BARCELONA",
  "municipality": "Barcelona",
  "municipalityCode": "881",
  "postalCode": "08011",
  "region": "BARCELONA",
  "regionCode": "08",
  "communityCode": "09",
  "latitude": 41.383083,
  "longitude": 2.161861,
  "distanceKm": 0.739,
  "fuelType": "diesel",
  "fuelName": "Diesel (B7, standard)",
  "sourceFuelName": "Gasoleo A",
  "price": 1.979,
  "currency": "EUR",
  "unit": "L",
  "priceDate": "2026-11-04",
  "priceUpdatedAt": "2026-11-04T04:25:50.000Z",
  "isCurrent": true,
  "areaAveragePrice": 1.9417,
  "areaMinPrice": 1.759,
  "priceVsAreaAverage": 0.0373,
  "priceVsAreaAveragePercent": 1.92,
  "priceRankInArea": 19,
  "stationsInArea": 52,
  "comparisonArea": "the 5 km radius, diesel, 2026-11-04 (52 stations)",
  "openingHours": "L-D: 06:00-22:00",
  "open24h": false,
  "saleType": "public",
  "roadSide": "none",
  "supplyType": "retailDistributor",
  "bioethanolPercent": null,
  "methylEsterPercent": null,
  "services": null,
  "dataQuality": "good",
  "warnings": [],
  "source": "MITECO – Geoportal de Gasolineras (Spain)",
  "sourceUrl": "https://sedeaplicaciones.minetur.gob.es/ServiciosRESTCarburantes/PreciosCarburantes/EstacionesTerrestres/FiltroProducto/4",
  "datasetUrl": "https://catalogo.datosabiertos.miteco.gob.es/catalogo/dataset/214e0895-b3aa-4662-8ebe-18134c21fb45",
  "license": "CC BY 4.0",
  "licenseUrl": "https://creativecommons.org/licenses/by/4.0/",
  "attribution": "Source: Ministerio para la Transición Ecológica y el Reto Demográfico, Geoportal de Gasolineras (CC BY 4.0).",
  "scrapedAt": "2026-11-04T04:25:48.599Z"
}
```

| Field | Meaning | When it is null |
|---|---|---|
| `recordType` | `stationPrice` or `nationalAverage`. | Never |
| `level` | `station` for a station price, `national` for a national weekly average (same meaning as `recordType`, kept for compatibility). | Never |
| `country`, `countryName` | Country code (ISO 3166-1; `EU` and `EUR` for the averages) and English name. | Never |
| `stationId` | The station ID in the official register (MITECO `IDEESS` or the French `pdv` id). It stays the same over time, so you can join history on it. | National rows |
| `stationName` | Brand or sign of the station as published (Spain). | France (the source does not publish it) and national rows |
| `brand`, `isKnownChain` | Normalised brand: known chains get one canonical name (for example `BP DUALEZ 365` becomes `BP`), other signs are kept as published; `isKnownChain` says which. | France and national rows |
| `municipality`, `municipalityCode`, `communityCode` | Spain: municipality, its ministry code and the autonomous community code. | France and national rows |
| `address`, `city`, `postalCode` | Station address. | National rows |
| `region`, `regionCode` | Spain: province and its ministry code. France: department and its INSEE code. | National rows |
| `latitude`, `longitude` | Station coordinates (WGS84). | National rows and the rare station without coordinates |
| `distanceKm` | Distance from your search point. | When no radius search was made |
| `fuelType` | Normalised fuel code (see the table of options above). | Never |
| `fuelName`, `sourceFuelName` | Readable fuel name, and the product name used by the source. | Never |
| `price` | Price including taxes. | Never |
| `currency` | Always `EUR`. The Commission converts national averages of non-euro countries to euros. | Never |
| `unit` | `L` (litre), or `kg` for CNG, LNG and hydrogen in Spain. | Never |
| `priceDate` | The date the price applies to: the snapshot date. For the French live feed it is the date of the station's last update. For national rows it is the Monday of the bulletin week. | Never |
| `priceUpdatedAt` | ISO 8601 time in UTC. France: when the station last changed the price. Spain: when the Ministry published the snapshot. | National rows and Spanish history |
| `isCurrent` | `true` for current prices, `false` for historical snapshots. | Never |
| `areaAveragePrice`, `areaMinPrice` | Average and lowest price of the same fuel on the same date among the stations of the area that passed your filters. The area is the province (Spain), the department (France) or your search radius. | National rows |
| `priceVsAreaAverage`, `priceVsAreaAveragePercent` | Price minus the area average, in EUR and in percent. Negative means cheaper than the average. | National rows |
| `priceRankInArea`, `stationsInArea` | Rank of the price in the area (1 = cheapest; equal prices share a rank) and the number of stations compared. | National rows |
| `comparisonArea` | The area, fuel, date and number of stations used for the comparison, in words. | National rows |
| `openingHours` | Opening hours. Spain: as published. France: built from the published days and hours (for example `Mon-Sun 07:00-21:00`), with `24/7 automatic pump` when the station has one. | National rows and stations that publish no hours |
| `open24h` | `true` when the station sells fuel 24 hours a day (Spain: hours marked 24H; France: 24/7 card pump). | National rows and stations that publish no hours |
| `saleType` | Spain: `public` or `restricted` (restricted means fleet or members only). France: `road` or `motorway`. | National rows |
| `roadSide` | Spain: side of the road, `right`, `left` or `none`. | France and national rows |
| `supplyType` | Spain: `wholesaleOperator` (supplied by a wholesale operator) or `retailDistributor`. | France and national rows |
| `bioethanolPercent`, `methylEsterPercent` | Spain: bioethanol and methyl ester (biodiesel) content declared by the station, in percent. | France, national rows and Spanish requests for a single fuel nationwide or by radius (that endpoint omits them) |
| `services` | France: services listed by the station (shop, car wash, 24/7 card payment, EV chargers...), as published in French. | Spain, national rows and stations that list none |
| `dataQuality` | `good`, or `check` when a warning below applies (a restricted sale alone does not lower it). | Never |
| `warnings` | Codes: `PRICE_NOT_UPDATED_3_DAYS` (current price last changed more than 3 days before the run), `PRICE_FAR_FROM_AREA_AVERAGE` (25 % or more from the average of an area with at least 5 stations), `NO_COORDINATES`, `RESTRICTED_SALE` (fleet or members only). Empty list when there is nothing to report. | Never (empty list) |
| `source`, `sourceUrl`, `datasetUrl` | Publisher, the exact file or endpoint that was read, and the official dataset page. | Never |
| `license`, `licenseUrl`, `attribution` | Licence of the data and the sentence to show when you reuse it. | Never |
| `input`, `scrapedAt` | The input that produced the row, and when the run read it. | Never |

### Key-value store records

| Record | Content |
|---|---|
| `INSIGHTS` | Free. `areas`: one entry per country, area and fuel with `latest` (date, number of stations, average, median, lowest and highest price, spread, cheapest and most expensive station with address and coordinates), `first` (first date and its average), `averageChange` and `averageChangePercent` (history runs), and `savingVsAverage` (average minus lowest price). Largest areas first, up to 2,000 entries; `areasTotal` gives the full count. |
| `RUN_SUMMARY` | Status per source request, resolved regions, record counts, charge reconciliation, warnings and `topInsights` (the five sentences of the largest areas). |
| `INPUT` | The input of the run. |
| `STATE` | Internal progress, used to resume after a server move. |

### Sources and licences

The Actor only uses sources whose terms allow reuse, including commercial reuse, with attribution. When you publish or redistribute the data, show the `attribution` text of each row.

| Country | Publisher and dataset | Licence |
|---|---|---|
| Spain | Ministerio para la Transición Ecológica y el Reto Demográfico (MITECO), [Precio de carburantes en las gasolineras españolas](https://catalogo.datosabiertos.miteco.gob.es/catalogo/dataset/214e0895-b3aa-4662-8ebe-18134c21fb45) | [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) |
| France | Ministère de l’Économie (DGCCRF), [Prix des carburants en France](https://www.prix-carburants.gouv.fr/rubrique/opendata/), also listed on data.gouv.fr | [Licence Ouverte / Open Licence 2.0](https://www.etalab.gouv.fr/licence-ouverte-open-licence/) |
| EU-27 national averages | European Commission, DG Energy, [Weekly Oil Bulletin](https://energy.ec.europa.eu/data-and-analysis/weekly-oil-bulletin_en) | Reuse is authorised provided the source is acknowledged ([Decision 2011/833/EU](https://eur-lex.europa.eu/eli/dec/2011/833/oj)) |

This Actor is not affiliated with or endorsed by any of these publishers. Prices come from the operators' declarations to the authorities. The Actor does not change them, apart from converting units and formats. Austria (E-Control), Western Australia (FuelWatch) and Mexico are not included, because their current terms do not clearly allow redistribution. The Actor does not collect phone numbers, e-mail addresses or any other personal data.

### Pricing and cost calculator

**Apify Store discounts:** `price-record` costs 15% less on Silver and 30% less on Gold and above.

**Typical job cost** (prices read from the Actor's live pricing on 2026-11-04, Free and Bronze plans; Apify platform compute is included, you pay only the events):

| Job | Rows | Cost |
|---|---|---|
| Cheapest diesel within 5 km of central Barcelona, today | 52 | about USD 0.008 |
| Diesel and gasoline 95 in the Madrid province, today, with the insights | 1,711 | about USD 0.26 |
| Example input (Madrid, Paris and the German average, three fuels) | 1,777 | about USD 0.27 |

Pay per event: USD 0.00015 per `price-record` (USD 0.15 per 1,000), one per row saved to the dataset. The only other charge is Apify's standard start event (`apify-actor-start`), USD 0.00005 per run at the default memory.

| Event | When it is charged |
|---|---|
| `price-record` | One price of one fuel, at one station or for one country, on one date, after it passes validation and is saved. |

**Free plan:** the USD 5 of monthly usage included in the Apify Free plan covers about 33,000 price records (USD 0.00015 each), for example about 19 runs of diesel and gasoline 95 for the Madrid province.

Never charged: invalid input, failed source requests, dates the source no longer keeps, prices removed by your filters or by `maxPriceAgeDays`, and the `RUN_SUMMARY` record. The Actor respects your maximum cost per run: it never saves more rows than that limit can pay for.

Rows per run = stations x fuels x dates (national: countries x fuels x weeks).

| Scenario | Rows (approx.) | Cost (approx.) |
|---|---|---|
| Diesel within 5 km of central Barcelona, today | 55 | USD 0.008 |
| Madrid province, diesel and gasoline 95, today | 1,700 | USD 0.26 |
| All of Spain, diesel only, today | 11,200 | USD 1.68 |
| All of Spain, every fuel, today | 42,600 | USD 6.39 |
| Diesel within 5 km of central Barcelona, daily for 31 days | 1,600 | USD 0.24 |
| Weekly diesel average for all 27 EU countries, one year | 1,400 | USD 0.21 |

Formula: `rows × 0.00015`. Prices shown are for the Free and Bronze plans; Silver and Gold pay less.

### Integrations: schedules, API, webhooks, Sheets and AI agents

- **Schedules.** Save your input as a task and schedule it daily (Spain and France update several times a day) or weekly for national averages (the bulletin is dated on Mondays and published a few days later).

- **API.** Run the Actor and get the rows in one call:

  ```bash
  curl -X POST "https://api.apify.com/v2/acts/ocius-data~fuel-prices-official/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
    -H "Content-Type: application/json" \
    -d '{"countries":["FR"],"regions":["Gironde"],"fuelTypes":["diesel"]}'
  ```

  Python, with the official `apify-client` package:

  ```python
  from apify_client import ApifyClient

  client = ApifyClient("YOUR_API_TOKEN")
  run = client.actor("ocius-data/fuel-prices-official").call(
      run_input={"countries": ["ES"], "latitude": 40.4168, "longitude": -3.7038, "radiusKm": 3, "fuelTypes": ["diesel"]}
  )
  cheapest = min(client.dataset(run["defaultDatasetId"]).iterate_items(), key=lambda r: r["price"])
  print(cheapest["stationName"], cheapest["address"], cheapest["price"])
  ```

- **Webhooks.** In the **Integrations** tab, add a webhook for `ACTOR.RUN.SUCCEEDED`. The rows are available at `/v2/datasets/{defaultDatasetId}/items`.

- **Google Sheets, Zapier, Make and n8n.** Use the Apify integration or app to append each run to a sheet or a database.

- **MCP and AI agents.** Add `ocius-data/fuel-prices-official` to the Apify MCP server (`https://mcp.apify.com`). An agent can then answer questions such as "cheapest diesel near Lyon today" with a plain input.

### Statuses and errors

Statuses are stored in the `RUN_SUMMARY` record, never in the dataset. Each source request (one country, one date and, in Spain, one province) gets one status:

| Status | Meaning | Charged | What to do |
|---|---|---|---|
| `OK` | The source answered and the matching prices were saved. | Yes, per row | Nothing |
| `NO_MATCH` | The source answered, but no price matched your filters. | No | Widen the area or the fuels. |
| `UNAVAILABLE` | The source no longer keeps that date (France: older than about 30 days). | No | Use a more recent date range, or national averages. |
| `ERROR_SOURCE` | The official service did not answer after 3 attempts, or answered in an unexpected format. | No | Run again later. If it persists, open an issue. |
| `PARTIAL` | The run stopped in the middle of this request at `maxRecords`, at your maximum cost or before the timeout. | Only saved rows | Raise the limit. |
| `NOT_PROCESSED` | The run stopped before this request. | No | Raise the limit. |

Invalid input, such as an unknown country, region, fuel or date, stops the run within seconds with a message that explains the fix. The run is marked **failed** when nothing could be saved because a source failed, or when more than 20% of the source requests failed, so a source outage never looks like an empty market. `RUN_SUMMARY` also lists the provinces or departments that each region matched, warnings (for example, prices skipped by `maxPriceAgeDays`) and the reconciliation between rows saved and events charged.

### Known limits

- **France** does not publish station names or brands, only the address. Daily history covers about the last 30 days. Older French history exists only as yearly archives, which this Actor does not read yet.
- **Spain**: history starts in 2007. `priceUpdatedAt` is the time of the Ministry's snapshot, not of the station's last price change.
- **National averages** are weekly. Each country reports the prices most frequently charged, as a weighted average, so countries are not strictly comparable. Some countries publish some weeks late.
- **Live feeds** can change while a run is in progress. If Apify moves a run to another server, the run resumes from the number of rows already saved and never charges a row twice.
- **Station data** is limited to 366 days per run. Split longer histories into several runs.

### FAQ

**Is it legal to use this data commercially?** Yes, within each licence: CC BY 4.0 (Spain), Licence Ouverte 2.0 (France) and the Commission reuse decision (EU) all allow commercial reuse with attribution. Show the `attribution` field wherever you display the data.

**How fresh are the prices?** Spain updates every 30 minutes and France every 10 minutes. Each run reads the live feed at the moment it starts.

**Why does the price of a French station look old?** Some stations stop reporting. By default, prices more than 30 days old are left out. `priceUpdatedAt` shows the exact time of each price.

**How do I get only the cheapest stations?** Open the `INSIGHTS` record for the cheapest station per area and fuel, or sort the **Price vs area average** view by `priceRankInArea`. Radius search rows are sorted by distance.

**Germany or Italy at station level?** Not yet. Germany's official data requires each user to have a personal API key, and Italy's files could not be reached reliably. Both are planned. The national averages already cover them.

### Related Actors from ocius-data

Built to the same standard (a status for every request in `RUN_SUMMARY`, actionable errors, charges only for valid data):

- **[Google Trends API: Interest, Related & Trending Now](https://apify.com/ocius-data/google-trends-reliable)**: demand for fuel, electric cars and mobility topics by region and over time.
- **[Google News API: Real URLs, Pay per Article](https://apify.com/ocius-data/google-news-reliable)**: news about fuel prices, taxes and supply, to explain the moves you see in the data.

### Changelog

- **0.1.7** (November 2026) Every station price is compared with its area (average, lowest price, rank and difference), with a free `INSIGHTS` record and the cheapest stations in the status message. New fields at no extra cost: `recordType`, `brand`, `isKnownChain`, opening hours and `open24h` for France, `services`, `roadSide`, `supplyType`, biofuel content, municipality and community codes, `dataQuality` and `warnings`. Labelled columns in every view, new views **Price vs area average** and **National averages (EU)**, and direct links to each view and to a CSV file in the Output tab. Spain, France and the EU bulletin are now downloaded in parallel: the example input finished in 9.7 s instead of 13.6 s (measured on Apify, 04-nov-2026). Existing fields are unchanged.
- **0.1.4** (November 2026) Billing check fix: the end-of-run charge check now waits for the platform's charge counter to catch up, so it no longer reports a false mismatch. Charges were always correct.
- **0.1** (November 2026) First version. Station prices for Spain and France, current and historical, with region, postal code and radius filters. Weekly national averages for the EU-27, the EU and the euro area since 2005. Source and licence on every row.

### Tutorials and examples

**Ready-to-import templates:** [Google Sheets](https://github.com/christianbarbosapayan-commits/apify-data-apis-examples/tree/main/integrations/google-sheets), [Make](https://github.com/christianbarbosapayan-commits/apify-data-apis-examples/blob/main/integrations/make.md), [Zapier](https://github.com/christianbarbosapayan-commits/apify-data-apis-examples/blob/main/integrations/zapier.md) and a [webhook receiver](https://github.com/christianbarbosapayan-commits/apify-data-apis-examples/blob/main/integrations/webhook/receiver.mjs).

- Tutorial: [Find the cheapest fuel near any location with official open data (Spain, France, EU) in Python](https://github.com/christianbarbosapayan-commits/apify-data-apis-examples/blob/main/tutorials/cheapest-fuel-prices-spain-france-api.md)
- Example code: [Python: cheapest fuel nearby](https://github.com/christianbarbosapayan-commits/apify-data-apis-examples/blob/main/python/cheapest_fuel_nearby.py)
- All examples: [apify-data-apis-examples on GitHub](https://github.com/christianbarbosapayan-commits/apify-data-apis-examples)

### Rate this Actor

If this Actor saved you time, please consider leaving a rating or a short review on its Apify Store page. It helps other users find it and shows us what to improve. If something does not work as expected, please open an issue first so we can fix it.

### Support

Open an issue on the Actor page. Issues are answered within one business day.

# Changelog

This Actor's version history is a separate document: https://apify.com/ocius-data/fuel-prices-official/changelog.md

# Actor input Schema

## `countries` (type: `array`):

Two-letter country codes. Spain (ES) and France (FR) return every station's prices. Any other EU member state returns the weekly national average from the European Commission Weekly Oil Bulletin. EU and EUR are the EU and euro-area weighted averages.

## `fuelTypes` (type: `array`):

Fuels to return. Leave empty for every fuel the source publishes. Spain publishes all of them except heating oil; France: diesel, gasoline95, gasoline95_e10, gasoline98, e85 and lpg; national averages: gasoline95, diesel, lpg and heating_oil.

## `dataLevel` (type: `string`):

Stations: station prices for Spain and France, national averages for the other countries. National: national weekly averages for every selected country, Spain and France included. Both: station prices and national averages.

## `regions` (type: `array`):

Limit station prices to regions. Spain: province or autonomous community ("Madrid", "Barcelona", "Andalucía"). France: department code or name, or region ("75", "Gironde", "Bretagne"). Prefix with the country to be explicit: "ES:Sevilla", "FR:69". A station country without a region is returned in full.

## `postalCodes` (type: `array`):

Full postal codes or their beginning, for example "28001" or "75" (all codes starting with 75). Prefix with the country if needed: "FR:69".

## `latitude` (type: `number`):

Centre of a radius search, in decimal degrees (for example 40.4168). Give it together with the longitude.

## `longitude` (type: `number`):

Centre of a radius search, in decimal degrees (for example -3.7038).

## `radiusKm` (type: `number`):

Only stations within this distance of the latitude and longitude. Rows are then sorted by distance and carry distanceKm.

## `historyDays` (type: `integer`):

0 returns current prices only. 1 to 366 returns one snapshot per day (or per week) from that many days ago until today. France keeps daily files for about the last 30 days; Spain since 2007; national averages are weekly since 2005.

## `startDate` (type: `string`):

Exact start of the history, YYYY-MM-DD. Overrides "History (days back)". Station data: at most 366 days per run. National averages: any range since 2005.

## `endDate` (type: `string`):

Exact end of the history, YYYY-MM-DD. Defaults to today.

## `historyInterval` (type: `string`):

One station snapshot per day or one per week (the end date and every 7 days before it). National averages are always weekly.

## `maxPriceAgeDays` (type: `integer`):

Station prices not updated for more than this many days before the snapshot date are left out (stations that stopped reporting). 0 keeps every price.

## `maxRecords` (type: `integer`):

The run stops after saving this many rows (one row = one price of one fuel at one station or country on one date). Spain has about 11,800 stations and France about 9,800, each selling 3 to 6 fuels.

## Actor input object example

```json
{
  "countries": [
    "ES",
    "FR",
    "DE"
  ],
  "fuelTypes": [
    "diesel",
    "gasoline95",
    "gasoline95_e10"
  ],
  "dataLevel": "stations",
  "regions": [
    "ES:Madrid",
    "FR:Paris"
  ],
  "radiusKm": 10,
  "historyDays": 0,
  "historyInterval": "daily",
  "maxPriceAgeDays": 30,
  "maxRecords": 10000
}
```

# Actor output Schema

## `results` (type: `string`):

One row per price observation: station (Spain, France) or country (EU national average) x fuel x date, with source and licence.

## `overview` (type: `string`):

Common columns for every row type, with the price compared with the area average.

## `priceComparison` (type: `string`):

Each station price with the area average, the lowest price and its rank in the area (1 = cheapest).

## `stations` (type: `string`):

Address, coordinates, opening hours, 24/7 pump and services.

## `nationalAverages` (type: `string`):

Weekly EU national averages.

## `attribution` (type: `string`):

Publisher, source file, licence and attribution text per row.

## `csv` (type: `string`):

The Prices view as a CSV file, ready for Excel or Google Sheets.

## `insights` (type: `string`):

Per country, area and fuel: cheapest and most expensive station, average, median, spread and change over the history. Free.

## `runSummary` (type: `string`):

Status per source request (OK, NO_MATCH, UNAVAILABLE, ERROR_SOURCE, PARTIAL, NOT_PROCESSED), resolved regions and charge reconciliation.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "countries": [
        "ES",
        "FR",
        "DE"
    ],
    "fuelTypes": [
        "diesel",
        "gasoline95",
        "gasoline95_e10"
    ],
    "regions": [
        "ES:Madrid",
        "FR:Paris"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ocius-data/fuel-prices-official").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "countries": [
        "ES",
        "FR",
        "DE",
    ],
    "fuelTypes": [
        "diesel",
        "gasoline95",
        "gasoline95_e10",
    ],
    "regions": [
        "ES:Madrid",
        "FR:Paris",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("ocius-data/fuel-prices-official").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "countries": [
    "ES",
    "FR",
    "DE"
  ],
  "fuelTypes": [
    "diesel",
    "gasoline95",
    "gasoline95_e10"
  ],
  "regions": [
    "ES:Madrid",
    "FR:Paris"
  ]
}' |
apify call ocius-data/fuel-prices-official --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ocius-data/fuel-prices-official"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/P1vDOQNaEEUYeCuMu/builds/IJZ6OtQBMyyb9XGDJ/openapi.json
