Skip to content

Methods — energy — Energy

How the energy work is done. The site-level contract at /methods/ binds whatever the subject is; this page records what that contract means when the subject is electricity systems, and the specific traps this data carries.

Where the numbers come from

Two sources, both chosen for licence as much as for content.

Generation, load, residual load, renewable share, and cross-border exchange come from the Energy-Charts API operated by Fraunhofer ISE, which re-serves ENTSO-E for Portugal and Spain. It returns CC BY 4.0 with attribution to energy-charts.info, and needs no key.

Day-ahead prices come from OMIE directly. This is not the convenient choice — Energy-Charts serves the same series — but Energy-Charts declares Iberian prices as "private and internal use only", and ENTSO-E's open-data list does not cover Art. 12.1.d day-ahead prices at all. OMIE is the rights-holder, and its legal notice permits free reuse provided the source is cited.

That is worth stating plainly, because it generalises: the same numbers carry different rights depending on the channel you take them through. Three of the four obvious routes to an Iberian price return a wrong "no". Asking the rights-holder dissolves a restriction that looks industry-wide from the intermediary layer.

The archive

Every fetch is committed with a provenance sidecar recording the request URL, the actual fetch time, the licence text the response carried, the row count, and the sha256 of the response body.

Published figures cite the response sha256, not a commit hash. It is content-addressed, it verifies against a re-fetch, and it does not depend on any repository being reachable.

The archive itself is a private working repository. What is public is this bundle: the prose, the figures, and the facts.json beside each report holding every number the prose states. A reader can check a sentence against the value the script produced without cloning anything.

Properties of this data that have already caused errors

Each of these is recorded because it produced a wrong answer here first, not because it is theoretically possible.

Units differ per endpoint. public_power reports MW; cbet and cbpf report GW. Same API, same country, same day. A comparison across them without scaling is wrong by 1000× and looks plausible.

Resolution differs and changed mid-series. Portugal is hourly throughout. Spain switched to quarter-hourly at 2023-01-01. A full-range query spanning that boundary declares its resolution as null, so any check keyed on the declared value silently skips exactly where the data is most likely to be wrong.

The declared column set depends on the query window. The same day fetched inside a twelve-year window declares more series than inside a one-year window, with identical values. The canonical column set is therefore pinned once from a full-range query, and a series outside it is refused and reported rather than written.

Column absence is not always physical. Spain's hydro_pumped_storage appears in 2023, and Spain has had pumped storage since the 1970s. That is a reporting change that looks exactly like a trend. Every structural break gets a judgement about whether it is physics or bookkeeping before it crosses into prose.

Timestamps are not where you expect. OMIE stamps both the Portuguese and the Spanish price in Spanish peninsular time, so a Portuguese local day spans two OMIE files and reading the period index as local time is wrong by an hour, year-round. Separately, a request for a local calendar year begins in the previous December in UTC — which destroyed twelve Decembers of this archive on its first run while reporting complete success.

The published series do not reconcile. Regulation (EU) 543/2013 Art. 2(27) defines total load as "a load equal to generation and any imports deducting any exports and power used for energy storage" — the exact identity, with losses inside it. It does not hold, because the cross-border series is a day-ahead nomination under Art. 12(1)(f) rather than a metered flow under Art. 12(1)(g). The residual is around 2% of load and reaches 5.7% in a single hour. It is reported, never absorbed into a fuel band, and it bounds how precisely any share can be stated.

What follows from that

Aggregate shares are safe; single-hour shares are not. At annual scale the choice of denominator moves a renewable share by well under a percentage point. In a single hour the two denominators diverge by several points. Hourly shares are not published to better than about a point, and a single extreme hour is never a headline.

Missing is not zero. An empty cell means the value was not published. Solar is legitimately zero at midnight and that is data; Spanish load is absent for 283 intervals around the 28 April 2025 blackout and that is not zero. Nothing is interpolated or forward-filled, and a gap renders as a gap.

Duration curves are not time series. Sorting destroys time. A duration curve carries no information about sequence, ramps or duration of any single event, and annotating one with seasons is a category error.