# EU Car Stock by Fuel — Electric, Hybrid, Petrol & Diesel (`nexgensignal/eu-passenger-car-energy-mix-records`) Actor

Eurostat passenger-car stock by country and motor energy, newest year first. Newer table road\_eqs\_carpda (2013-2025): electric, hybrid, plug-in, gas, LPG and hydrogen cars by owner. Original road\_eqs\_carmot (petrol/diesel by engine size) is the default. Vehicle stock, not sales. Pay per record.

- **URL**: https://apify.com/nexgensignal/eu-passenger-car-energy-mix-records.md
- **Developed by:** [NexGen Signal](https://apify.com/nexgensignal) (community)
- **Categories:** Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $33.50 / 1,000 car energy 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

## EU Car Stock by Fuel — Electric, Hybrid, Petrol & Diesel

Turn Eurostat's passenger-car-stock tables into clean, per-record benchmarks — one row per published observation of the car stock by country and motor energy. The original table (`road_eqs_carmot`, the default) splits petrol and diesel by engine size; the newer table (`road_eqs_carpda`, 2013–2025) adds electric, hybrid, plug-in, gas, LPG and hydrogen cars by owner type.

Each row of the source multidimensional cube becomes **one clean, flat record**: every dimension is
expanded into an explicit code **and** its label, the observation value is reproduced exactly as Eurostat
published it, and each record is stamped with source, dataset code, licence, attribution, a UTC retrieval
timestamp and an interpretation caveat.

### Two source tables — choose with `sourceTable`

| `sourceTable` | Years | Motor energy | Other split |
|---|---|---|---|
| `road_eqs_carmot` (the default — runs exactly as before) | from 2000 in many countries | petrol, diesel, total only | engine size (`engineSize`) |
| `road_eqs_carpda` (added 30 Sep 2026) | 2013–2025 (Eurostat last updated it 1 Sep 2026) | 16 codes: electric, petrol and diesel hybrids and plug-ins, gas, LPG, hydrogen and more | owner type (`ownerType`: private or legal person) |

**They are not one continuous series** and the newer table has no engine-size split. `engineSize` works only with
the original table and `ownerType` only with the newer one; the wrong combination stops the run before anything is
fetched, with nothing charged. Every record carries `dataset_code`, so you always know which table a row came from.

**Watch the overlaps:** in `road_eqs_carpda`, `PET` and `DIE` already include their hybrids and plug-ins (Germany
2024: `PET` 32,712,008 = `PET_X_HYB` 29,918,520 + `ELC_PET_HYB` 1,897,379 + `ELC_PET_PI` 896,109). `ELC` is
battery-electric cars only and sits inside `ALT`. Don't add `PET` and `ELC_PET_PI` together.

**Question:** how many electric cars were on Germany's roads in 2025, against petrol and diesel?

```json
{"sourceTable": "road_eqs_carpda", "geo": "DE", "fuel": ["TOTAL", "ELC", "ELC_PET_PI", "PET", "DIE"], "ownerType": ["TOTAL"], "sinceTimePeriod": "2024", "newestFirst": true, "maxRecords": 10}
```

Run on 30 Sep 2026 this returned 10 records (10 × $0.05 = $0.50 on Apify's Free plan):

| Code | Meaning | 2024 | 2025 |
|---|---|---|---|
| `TOTAL` | All cars | 49,339,166 | 49,486,487 |
| `ELC` | Battery-electric | 1,651,643 | 2,034,260 |
| `ELC_PET_PI` | Plug-in hybrid (petrol) | 896,109 | 1,044,644 |
| `PET` | Petrol (incl. its hybrids) | 32,712,008 | 32,837,331 |
| `DIE` | Diesel (incl. its hybrids) | 14,592,567 | 14,254,484 |

<details><summary>All 16 <code>road_eqs_carpda</code> motor-energy codes</summary>

| Code | Eurostat label |
|---|---|
| `TOTAL` | Total |
| `PET` | Petrol |
| `PET_X_HYB` | Petrol (excluding hybrids) |
| `ELC_PET_HYB` | Hybrid electric-petrol |
| `ELC_PET_PI` | Plug-in hybrid petrol-electric |
| `DIE` | Diesel |
| `DIE_X_HYB` | Diesel (excluding hybrids) |
| `ELC_DIE_HYB` | Hybrid diesel-electric |
| `ELC_DIE_PI` | Plug-in hybrid diesel-electric |
| `ALT` | Alternative energy |
| `ELC` | Electricity |
| `HYD_FCELL` | Hydrogen and fuel cells |
| `REN_OTH` | Other renewable fuels |
| `GAS` | Natural gas |
| `LPG` | Liquefied petroleum gases (LPG) |
| `OTH` | Other |

</details>

### What one record represents

The source dataset is Eurostat **`road_eqs_carmot`** — passenger cars by type of motor energy and engine size (vehicle stock). Eurostat publishes it as a
JSON-stat hypercube indexed by several dimensions (frequency, unit, motor energy (fuel type), engine size class, geography and time); this Actor unpacks it so **every
present observation cell becomes exactly one record**. Cells Eurostat does not publish are absent from
the source and are neither invented nor delivered; published zeros are kept as real values.

For each record you get a composite `record_id`, the `dataset_code`, the `indicator` name, then — for
each dimension — the code and its label, plus `time_period`, the numeric `value`, and Eurostat's
`obs_status` flag when present. The dimension columns include `mot_nrg` (motor energy: petrol, diesel or total — the only three in this table) with its label, `engine` (engine size class) and `unit`.

### Coverage and volume

The licence-permitted cube holds a compact, complete set of stock observations by fuel type, engine class and country across the published years.

**Live licence-clean count is 6,054 non-null observations across EU/EFTA/candidate territories; the Wave-3 index figure of 6,225 counts all territories including commercial-barred ones. This README states the difference; the capacity line is the licence-clean count.**

The reporting country (`geo`) is optional: leave it empty for every licence-permitted territory, or set one code such as `DE`. The ingester auto-partitions by territory if a response is too large, and stops at your **Maximum records** cap.

### Licence and attribution

This dataset is redistributed under the terms Eurostat publishes it with; the full notice travels on
every record in the `licence` field:

> Eurostat, CC BY 4.0. Reformatted from Eurostat JSON-stat; values unmodified. Third-party content and logos excluded. Commercial-barred geographies removed.

A structural **geography allow-list is applied at ingest**: only EU member states, EU/euro-area
aggregates, EFTA members and official EU acceding/candidate countries are delivered; commercial-barred
territories are excluded at ingest and counted in the run receipt. The required attribution —
`Source: Eurostat (dataset road_eqs_carmot)` — is on every record.

### Interpretation caveat

Figures are counts of the passenger-car stock by motor-energy (fuel) type and engine class, not new registrations, CO2 emissions, or shares. Read the mot\_nrg and engine dimensions to know which fuel and engine class a row counts.

Eurostat values are reproduced verbatim: no rescaling, re-basing, interpolation or seasonal adjustment.
Read each value together with its dimension labels — the `indic_sb` code tells you which measure a row
carries.

### Person-data policy

This is a statistics product about enterprises, industries and territories. There are no natural-person
or contact fields anywhere in the record, and a per-record assertion enforces that allow-list at write
time.

### Provenance, licensing and compliance

Every run begins with a live source-preflight: the Actor reads the exact host's `robots.txt` at runtime
and refuses to proceed if the crawl policy disallows the data path. The gate result — URL, HTTP status,
byte length and a SHA-256 of the policy — is written to the run's `RUN_RECEIPT`, so each run carries its
own audit trail. The Actor identifies itself with a transparent, non-impersonating User-Agent and never
bypasses a block, solves a challenge, or fetches through a cache or mirror. When the door is genuinely
unavailable the run fails loudly and bills nothing.

### Choosing the series (search options)

Pick the series you want before the run, instead of paging through every combination. Codes are Eurostat's own; they are sent to Eurostat as filters (only matching series are read and billed) and checked against the dataset's live code list first, so a wrong code stops the run with the valid codes listed and nothing charged. With no option set the actor sends exactly the request it sent before.

| Input | Eurostat dimension | Codes |
|---|---|---|
| fuel | `mot_nrg` | Optional. `TOTAL` Total; `PET` Petrol; `DIE` Diesel. This Eurostat table has only these three; it has no electric or hybrid split. |
| engineSize | `engine` | Optional. `TOTAL` Total; `CC_LT1400` Less than 1 400 cm³; `CC1400-1999` From 1 400 to 1 999 cm³; `CC_GE2000` 2 000 cm³ or over. |
| unit | `unit` | Optional. `NR` Number. |
| ownerType | `leg_form` | `road_eqs_carpda` only: `TOTAL`, `PER_PHY` private persons, `PER_LEG` companies and other legal persons. |
| sourceTable | — | `road_eqs_carmot` (default) or `road_eqs_carpda`. The fuel codes above are the original table's; the newer table's 16 codes are listed under Two source tables. |
| newestFirst | time | Most recent periods first, before cutting to `maxRecords` (monthly, quarterly and annual periods are ordered by the date they end). |

Example (the Store example):

```json
{
  "geo": "DE",
  "fuel": [
    "PET",
    "DIE"
  ],
  "engineSize": [
    "TOTAL"
  ],
  "sinceTimePeriod": "2015",
  "newestFirst": true,
  "maxRecords": 10
}
```

First rows it returned when checked (Sep 2026):

```json
[
  {
    "geo": "DE",
    "time_period": "2025",
    "value": 14254484,
    "mot_nrg_label": "Diesel",
    "engine_label": "Total",
    "unit_label": "Number"
  },
  {
    "geo": "DE",
    "time_period": "2025",
    "value": 32837331,
    "mot_nrg_label": "Petrol",
    "engine_label": "Total",
    "unit_label": "Number"
  },
  {
    "geo": "DE",
    "time_period": "2024",
    "value": 14592567,
    "mot_nrg_label": "Diesel",
    "engine_label": "Total",
    "unit_label": "Number"
  }
]
```

Eurostat table `road_eqs_carmot` splits the car stock into petrol and diesel only (plus total), by engine size. It has no electric, hybrid or LPG split; for those set `sourceTable` to `road_eqs_carpda` (see Two source tables). Vehicle-stock counts, not sales or listings.

### Inputs

**Default changed on 30 Sep 2026:** if you leave `maxRecords` out, a run now returns up to **10** records (it was 500). Set `maxRecords` yourself to get more — the maximum is unchanged.

- **Source table** (`sourceTable`) — `road_eqs_carmot` (default: petrol/diesel by engine size) or `road_eqs_carpda` (2013–2025: electric, hybrids and more, by owner type).
- **Motor energy** (`fuel`), **Engine size** (`engineSize`, original table only), **Owner type** (`ownerType`, newer table only), **Unit** (`unit`) — optional Eurostat codes; see Choosing the series.
- **Newest first** (`newestFirst`) — most recent years first, before the record cap.
- **Country / territory** (`geo`) — optional; one Eurostat geo code (e.g. `DE`). Empty = every licence-permitted territory.
- **Earliest period** (`sinceTimePeriod`) — return observations from this year onward. An earlier start
  yields more records.
- **Maximum records** (`maxRecords`) — hard cap on records delivered and billed.

### Output

Records land in the Actor's default dataset and export as JSON, CSV, Excel or via the Apify API. A
tabular **overview view** surfaces geography, period, the key dimension labels and the value.

### Fields in detail

Each record leads with a composite `record_id` built from every dimension code, so it is stable and
join-ready across runs. Every dimension arrives as both a machine code and a human-readable label, which
means you can group and filter on the codes while reading the labels — no separate code list to maintain.
The `value` is the observation itself, reproduced exactly; `obs_status` carries Eurostat's flag (for
example a break in series or a provisional marker) when one is present, so you never silently lose the
caveats Eurostat attaches to a number. The provenance block — `source`, `source_dataset`, `licence`,
`attribution`, `caveat`, `observed_at` — is present on every record, so each row is self-describing and
audit-ready without reference back to this page.

### Sibling Actors

This Actor counts the **stock** of passenger cars by fuel type; the fleet's **`eu-vehicle-co2-records`** cell instead carries EEA **new-car CO2 monitoring** values (grams per km on newly registered cars). Fleet composition versus new-car emissions - two different questions, and both distinct from the RDW registration-count cells. It also shares its engineering — the runtime robots gate, the geo allow-list, the
push-then-charge billing and the verbatim-value discipline — with the fleet's other Eurostat cells.

### Sample output

![Sample output — EU Passenger-Car Energy Mix — Stock by Fuel Type](https://api.apify.com/v2/key-value-stores/IXCaMKjxSmUTLHhmq/records/eu-passenger-car-energy-mix-records.png)

*Real rows from a live run of this actor (first 5 rows, selected columns).*

One full record from the same run, exactly as delivered:

```json
{
  "record_id": "A:NR:DIE:CC1400-1999:AL:2021",
  "dataset_code": "road_eqs_carmot",
  "indicator": "Passenger cars by type of motor energy (vehicle stock)",
  "freq": "A",
  "freq_label": "Annual",
  "unit": "NR",
  "unit_label": "Number",
  "mot_nrg": "DIE",
  "mot_nrg_label": "Diesel",
  "engine": "CC1400-1999",
  "engine_label": "From 1 400 to 1 999 cm³",
  "geo": "AL",
  "geo_label": "Albania",
  "time_period": "2021",
  "value": 233368,
  "obs_status": null,
  "source": "Eurostat",
  "source_dataset": "road_eqs_carmot",
  "licence": "Eurostat, CC BY 4.0. Reformatted from Eurostat JSON-stat; values unmodified. Third-party content and logos excluded. Commercial-barred geographies removed.",
  "attribution": "Source: Eurostat (dataset road_eqs_carmot)",
  "caveat": "Figures are counts of the passenger-car stock by motor-energy (fuel) type and engine class, not new registrations, emissions, or shares. Read the mot_nrg (motor energy) and engine dimensions to know which fuel and engine class a row counts. Values reproduced verbatim from Eurostat.",
  "observed_at": "2026-09-25T17:33:32Z"
}
```

### Pricing

This Actor uses Apify's pay-per-event model: a flat **$0.05 per record** actually delivered to the
dataset, and nothing else — no monthly rental, no per-run base fee, no compute charge. Deliver 40
records and you pay $2.00; deliver 10,000 and you pay $500.00. Billing is wired *after* delivery — each
record is pushed first and only then does the per-record event fire — so a mid-run failure can only
ever under-charge you, never over-charge. Use **Maximum records** to cap spend precisely.

### Scaling and limits

Set **Maximum records** low to sample cheaply or high to pull a territory in full. The Actor streams the
cube and delivers incrementally, so memory stays bounded regardless of how large the requested territory
is, and you are billed only for records actually delivered. Because Eurostat updates this cube on its own
release calendar, re-running the Actor picks up new periods automatically, and each record's `observed_at`
stamp dates the snapshot — schedule a run to keep a downstream table current. To assemble a multi-country
panel, run the Actor once per territory and concatenate; every record already carries its `geo` code and
label, so the panels align without any reconciliation work.

### Typical uses

Compare the petrol/diesel mix of the car stock across member states; size the diesel or petrol fleet by engine class; benchmark the pace of the energy transition; or feed a mobility-planning, charging-infrastructure or policy model with clean, licence-clean stock inputs.

### What this Actor does not do

It does not forecast, model, seasonally adjust, or merge multiple Eurostat datasets into one record, and
it does not deliver commercial-barred geographies. It gives you faithful, licence-clean, analysis-ready
observation records — one row per published cell — with an auditable provenance trail.

# Actor input Schema

## `sourceTable` (type: `string`):

Which Eurostat table to read. <code>road\_eqs\_carmot</code> is the original table and stays the default; <code>road\_eqs\_carpda</code> is Eurostat's newer table. Their codes differ, so the other inputs are checked against the table you choose.

## `fuel` (type: `array`):

Original table: Optional. <code>TOTAL</code> Total; <code>PET</code> Petrol; <code>DIE</code> Diesel. This Eurostat table has only these three; it has no electric or hybrid split. Newer table: With road\_eqs\_carpda: <code>TOTAL</code>, <code>PET</code> petrol, <code>DIE</code> diesel, <code>ELC</code> electricity, <code>ELC\_PET\_HYB</code> petrol hybrid, <code>ELC\_PET\_PI</code> petrol plug-in hybrid, <code>ELC\_DIE\_HYB</code>, <code>ELC\_DIE\_PI</code>, <code>ALT</code> alternative energy, <code>GAS</code> natural gas, <code>LPG</code>, <code>HYD\_FCELL</code> hydrogen, <code>REN\_OTH</code>, <code>OTH</code>, <code>PET\_X\_HYB</code>, <code>DIE\_X\_HYB</code>. <code>PET</code> and <code>DIE</code> already include their hybrids and plug-ins (<code>PET</code> = <code>PET\_X\_HYB</code> + <code>ELC\_PET\_HYB</code> + <code>ELC\_PET\_PI</code>); <code>ELC</code> is battery-electric only.

## `engineSize` (type: `array`):

Optional. <code>TOTAL</code> Total; <code>CC\_LT1400</code> Less than 1 400 cm³; <code>CC1400-1999</code> From 1 400 to 1 999 cm³; <code>CC\_GE2000</code> 2 000 cm³ or over.

## `unit` (type: `array`):

Optional. <code>NR</code> Number.

## `ownerType` (type: `array`):

road\_eqs\_carpda only: <code>TOTAL</code>, <code>PER\_PHY</code> private persons, <code>PER\_LEG</code> companies and other legal persons.

## `newestFirst` (type: `boolean`):

Order by period, most recent first, before cutting to Maximum records (monthly, quarterly and annual periods are ordered by the date they end).

## `sinceTimePeriod` (type: `string`):

Return observations from this year onward (annual stock series). Use a year (2000). Earlier start = more records. Optionally set a single country.

## `geo` (type: `string`):

Optional Eurostat geo code (e.g. DE). Leave blank to pull all licence-permitted territories (auto-partitioned if the full cube is too large for one request).

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

Maximum records delivered and billed. You are billed only for records actually delivered. Raise it to pull the full set.

## Actor input object example

```json
{
  "sourceTable": "road_eqs_carpda",
  "fuel": [
    "TOTAL",
    "ELC",
    "ELC_PET_PI",
    "PET",
    "DIE"
  ],
  "ownerType": [
    "TOTAL"
  ],
  "newestFirst": true,
  "sinceTimePeriod": "2024",
  "geo": "DE",
  "maxRecords": 10
}
```

# Actor output Schema

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

The delivered EU passenger-car energy-mix record.

# 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 = {
    "sourceTable": "road_eqs_carpda",
    "fuel": [
        "TOTAL",
        "ELC",
        "ELC_PET_PI",
        "PET",
        "DIE"
    ],
    "ownerType": [
        "TOTAL"
    ],
    "newestFirst": true,
    "sinceTimePeriod": "2024",
    "geo": "DE",
    "maxRecords": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("nexgensignal/eu-passenger-car-energy-mix-records").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 = {
    "sourceTable": "road_eqs_carpda",
    "fuel": [
        "TOTAL",
        "ELC",
        "ELC_PET_PI",
        "PET",
        "DIE",
    ],
    "ownerType": ["TOTAL"],
    "newestFirst": True,
    "sinceTimePeriod": "2024",
    "geo": "DE",
    "maxRecords": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("nexgensignal/eu-passenger-car-energy-mix-records").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 '{
  "sourceTable": "road_eqs_carpda",
  "fuel": [
    "TOTAL",
    "ELC",
    "ELC_PET_PI",
    "PET",
    "DIE"
  ],
  "ownerType": [
    "TOTAL"
  ],
  "newestFirst": true,
  "sinceTimePeriod": "2024",
  "geo": "DE",
  "maxRecords": 10
}' |
apify call nexgensignal/eu-passenger-car-energy-mix-records --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nexgensignal/eu-passenger-car-energy-mix-records"
        }
    }
}
```

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/n2hkCoHxbOxESPdf2/builds/07j20ygldnbkUaER9/openapi.json
