# German Fuel Station Prices Scraper - Petrol & Diesel (`ninhothedev/fuel-prices-scraper`) Actor

$0.5/1K 🔥 German fuel price scraper! Live petrol & diesel prices for 15k stations with brands & locations. JSON, CSV, Excel or API in seconds. Build price comparison & fleet tools ⚡

- **URL**: https://apify.com/ninhothedev/fuel-prices-scraper.md
- **Developed by:** [ninhothedev](https://apify.com/ninhothedev) (community)
- **Categories:** Developer tools, Travel
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## German Fuel Station Prices Scraper 🇩🇪⛽

**Live petrol and diesel prices for 15,000+ German fuel stations.** Scrape current
E5, E10 and diesel prices with brand, street address, postcode, GPS coordinates,
open/closed status and opening hours — searched by radius around any coordinates
or looked up by station ID.

Data comes from **MTS-K** (*Markttransparenzstelle für Kraftstoffe*), the official
German federal fuel-price reporting body, published via the Tankerkönig
Creative-Commons API. Every filling station in Germany is legally required to
report price changes to MTS-K within five minutes, so this is the authoritative
source for German fuel prices — not a scraped price-comparison site.

***

### ✨ What you get

| Capability | Details |
|---|---|
| **Coverage** | ~15,000 German fuel stations (all brands, incl. independents) |
| **Fuels** | Diesel, Super E5, Super E10 — prices in EUR (e.g. `1.789`) |
| **Radius search** | Any `lat,lng` centre point, up to 25 km, unlimited centres per run |
| **Station lookup** | Full detail records including structured opening hours |
| **Freshness** | Prices update within minutes of a station changing its pylon |
| **Cost** | ~**$0.5 per 1,000 stations** |

***

### 🚀 Quick start

```json
{
  "mode": "radius",
  "centers": ["52.5200,13.4050", "48.1351,11.5820"],
  "radiusKm": 5,
  "fuelType": "all",
  "maxItems": 500
}
```

This returns every fuel station within 5 km of central Berlin and central Munich,
with all three fuel prices for each.

#### Cheapest diesel near a location

```json
{
  "mode": "radius",
  "centers": ["50.1109,8.6821"],
  "radiusKm": 25,
  "fuelType": "diesel",
  "maxItems": 200
}
```

Selecting a single fuel type sorts the results **cheapest first**.

#### Full detail for specific stations

```json
{
  "mode": "stations",
  "stationIds": [
    "278130b1-e062-4a0f-80cc-19e486b4c024",
    "94e70fc4-b22f-4e5a-877f-bc1082cdae81"
  ]
}
```

Station mode adds `opening_times` and `open_whole_day`, then refreshes every
station against the live price endpoint. Run `radius` mode first to discover the
station IDs you want to monitor.

***

### 🔑 API key — read this before your first run

The actor ships with Tankerkönig's **shared public demo key**
(`00000000-0000-0000-0000-000000000002`) so you can try it instantly.

**Verified demo-key behaviour (tested against all three endpoints):**

| Aspect | Demo key |
|---|---|
| `list.php`, `detail.php`, `prices.php` | ✅ All work, `HTTP 200`, `ok: true` |
| Station master data (name, brand, address, postcode, GPS, distance) | ✅ **Real** |
| Open/closed status, opening hours, whole-day flag | ✅ **Real** |
| **Fuel prices** | ❌ **Placeholders** — `1.009` from `list.php`/`detail.php`, `1.234` from `prices.php`, identical for every station |
| Rate limit | No throttling observed at ~3 requests/second across 25 consecutive calls |

**So: the demo key is perfect for building and testing your integration, but it
will never give you real prices.** Get your own key — it is **free**, personal and
issued in a few clicks at
[creativecommons.tankerkoenig.de](https://creativecommons.tankerkoenig.de/) — and
paste it into the `apiKey` input. Everything else works identically.

***

### 📥 Input reference

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | select | `radius` | `radius` = search around coordinates · `stations` = look up explicit IDs |
| `centers` | array | Berlin + Munich | `"lat,lng"` centre points; each is searched separately, results de-duplicated |
| `radiusKm` | integer | `5` | Search radius, **max 25 km** (the API silently clamps larger values) |
| `fuelType` | select | `all` | `all`, `e5`, `e10` or `diesel`; a single fuel sorts results by price |
| `stationIds` | array | `[]` | Tankerkönig station UUIDs (`stations` mode) |
| `apiKey` | string | demo key | Your free personal Tankerkönig key |
| `maxItems` | integer | `500` | Hard cap on stations collected per run (max 5000) |

***

### 📤 Output

One dataset item per fuel station:

```json
{
  "station_id": "278130b1-e062-4a0f-80cc-19e486b4c024",
  "name": "Aral Tankstelle",
  "brand": "ARAL",
  "street": "Holzmarktstraße",
  "house_number": "12/14",
  "post_code": "10179",
  "city": "Berlin",
  "state": null,
  "latitude": 52.514153,
  "longitude": 13.421487,
  "distance_km": 1.3,
  "is_open": true,
  "price_diesel": 1.699,
  "price_e5": 1.859,
  "price_e10": 1.799,
  "cheapest_fuel": "diesel",
  "opening_times": null,
  "open_whole_day": true,
  "search_lat": 52.52,
  "search_lng": 13.405,
  "search_radius_km": 5,
  "source": "tankerkoenig",
  "scraped_at": "2026-07-28T18:06:52Z"
}
```

**Field notes**

- `price_diesel` / `price_e5` / `price_e10` — EUR floats. The upstream API returns
  the boolean `false` for a fuel a station does not sell, and occasionally `0`.
  **Both are normalised to `null`** — this actor never emits a 0.00 EUR fuel price.
- `cheapest_fuel` — the fuel type with the lowest non-null price, or `null` when the
  station has no usable price (e.g. it is closed).
- `distance_km` — only populated in `radius` mode, `null` otherwise.
- `opening_times` — only populated in `stations` mode, as a compact list of
  `{text, start, end}` blocks. Empty when `open_whole_day` is `true`.
- `search_lat` / `search_lng` / `search_radius_km` — the query centre that produced
  the row, so you can trace multi-centre runs. `null` in `stations` mode.
- `post_code` — emitted as a zero-padded 5-character string (the API returns an int).
- All fields are nullable.

***

### 💡 Use cases

- **Fuel price comparison apps** — power a "cheapest station near me" feature with
  authoritative, legally-mandated price data instead of scraped estimates.
- **Fleet cost optimisation** — route delivery and service fleets past the cheapest
  diesel on their corridor and quantify the saving per refuel.
- **Price monitoring** — schedule the actor hourly and track competitor pylon prices,
  regional spreads, and how fast brands pass through wholesale moves.
- **Local market analysis** — map brand density, pricing power and station coverage
  by postcode for site selection, real-estate or energy-transition research.

***

### ⚖️ Licence & attribution (important)

The underlying data is published by Tankerkönig under
**[CC BY 4.0](https://creativecommons.org/licenses/by/4.0/deed.en)**. This licence
**requires attribution** wherever you publish or display the data. Include a credit
such as:

> Fuel price data: [Tankerkönig](https://creativecommons.tankerkoenig.de/) / MTS-K,
> licensed under CC BY 4.0

Please also respect Tankerkönig's fair-use guidance: do not poll far more often than
prices actually change, and cache aggressively. This actor batches requests and
de-duplicates stations to keep your footprint small.

***

### 🔗 Related actors

- [EV Charging Stations Scraper](https://apify.com/ninhothedev/ev-charging-scraper)
- [Public Transit Scraper](https://apify.com/ninhothedev/public-transit-scraper)
- [Postal Code Scraper](https://apify.com/ninhothedev/postal-code-scraper)
- [Geocoding Scraper](https://apify.com/ninhothedev/geocoding-scraper)

***

### ❓ FAQ

**Why are all my prices exactly 1.009 or 1.234?**
You are on the demo key. Add your own free key to `apiKey`. See the API key section.

**Can I search a radius larger than 25 km?**
No — the API caps it at 25 km and silently ignores larger values. Pass several
`centers` instead; results are de-duplicated by `station_id`.

**Why is `price_e10` null for some stations?**
That station does not sell E10 (the API returns `false`), or it is currently closed.

**How current are the prices?**
German stations must report price changes to MTS-K within five minutes, and
Tankerkönig republishes them immediately.

**Does it cover all of Germany?**
Yes — around 15,000 stations. It does not cover Austria, Switzerland or other
countries.

***

*Keywords: German fuel prices, Tankstellen Preise scraper, Benzinpreise API, diesel
price Germany, E5 E10 petrol prices, Tankerkönig scraper, MTS-K fuel data, gas
station scraper Germany, fuel price monitoring, Spritpreise API.*

# Actor input Schema

## `mode` (type: `string`):

How to find stations. 'radius' searches around one or more lat,lng centre points and returns current prices. 'stations' takes explicit station UUIDs and returns the full detail record including opening hours.

## `centers` (type: `array`):

Centre points for the radius search, each as a 'lat,lng' string (for example '52.5200,13.4050' for Berlin). Add as many as you like - every centre is searched separately and results are de-duplicated by station ID. Used in 'radius' mode only.

## `radiusKm` (type: `integer`):

Search radius around each centre point in kilometres. The Tankerkoenig API silently caps this at 25 km, so larger values are clamped. Used in 'radius' mode only.

## `fuelType` (type: `string`):

Which fuel to query. 'all' returns diesel, E5 and E10 prices for every station. Choosing a single fuel returns only that price but sorts the results by price (cheapest first).

## `stationIds` (type: `array`):

Tankerkoenig station UUIDs to look up, for example '278130b1-e062-4a0f-80cc-19e486b4c024'. Run 'radius' mode first to discover the IDs you need. Used in 'stations' mode only.

## `apiKey` (type: `string`):

Your personal Tankerkoenig API key. The default is the shared public DEMO key: it returns real station master data but PLACEHOLDER prices (1.009 / 1.234 EUR). Request a free personal key at creativecommons.tankerkoenig.de to receive live prices.

## `maxItems` (type: `integer`):

Stop after this many stations have been collected across all centre points or station IDs. Keeps runs predictable and cheap.

## Actor input object example

```json
{
  "mode": "radius",
  "centers": [
    "52.5200,13.4050",
    "48.1351,11.5820"
  ],
  "radiusKm": 5,
  "fuelType": "all",
  "stationIds": [],
  "apiKey": "00000000-0000-0000-0000-000000000002",
  "maxItems": 500
}
```

# Actor output Schema

## `records` (type: `string`):

No description

# 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 = {
    "centers": [
        "52.5200,13.4050",
        "48.1351,11.5820"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ninhothedev/fuel-prices-scraper").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 = { "centers": [
        "52.5200,13.4050",
        "48.1351,11.5820",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("ninhothedev/fuel-prices-scraper").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 '{
  "centers": [
    "52.5200,13.4050",
    "48.1351,11.5820"
  ]
}' |
apify call ninhothedev/fuel-prices-scraper --silent --output-dataset

```

## MCP server setup

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

```

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/dBNeVZ9EAGxoOgyt6/builds/impVpROoYzChsFcGW/openapi.json
