ENTSO-E Transparency Platform API: how to get a token and query it
Reviewed , against the code that runs Voltstack's ENTSO-E feeds
To use the ENTSO-E API, register on the Transparency Platform, email transparency@entsoe.eu with “Restful API access” in the subject, generate a security token (the API key) under My Account, then send GET requests to https://web-api.tp.entsoe.eu/api with a documentType, an area code and a UTC period in yyyyMMddHHmm.
Answers come back as XML, except imbalance prices (A85) and unit outages (A77, A80), which come back as ZIP archives. ENTSO-E allows 400 requests a minute per token and bans the token for about ten minutes when you go over. The working requests, in curl and Python, are below, followed by the traps we met running these feeds every day.
Voltstack capture of the ENTSO-E Transparency Platform, 23 Sep 2026 00:00 UTC to 28 Oct 2026 14:02 UTC; recording of these series began on 23 Sep 2026. Each quarter-hour was re-read for about three days, so later corrections are not counted and every figure is a minimum. Method and change records: doi:10.5281/zenodo.23749147. ENTSO-E Transparency Platform, CC BY 4.0, aggregated and changed by Voltstack.
Voltstack reads ENTSO-E's load, generation, outage, flow and imbalance series and does this parsing for you, naming the source on each. For imbalance prices and cross-border flows it keeps each value it reads with the time it read it, since 23 Sep 2026, so you can see what a quarter-hour said before it was corrected. The 14-day trial opens the workspace. The Voltstack API is in early access: keys are issued on request, not self-serve.
Start a 14-day free trialRequest early access →The button opens a 14-day free trial sign-up. Sign-up needs a work email.
The button opens the early-access request on our home page.
How to get an ENTSO-E API key
ENTSO-E calls the key a security token. Getting one takes an email, not a form.
- Register a free account on transparency.entsoe.eu and confirm your email address.
- Email
transparency@entsoe.eufrom that address withRestful API accessin the subject, and name the account email in the body. - Wait for ENTSO-E to switch API access on. It can take up to three working days.
- Sign in, open My Account, and choose to generate a new security token.
The token travels as the securityToken query parameter on every request, so it ends up in any log that records URLs. Keep it in an environment variable, keep it out of code and screenshots, and do not print request URLs in your logs. A request with no token or a wrong one is refused with HTTP 401, which is also a cheap way to check that the API is up.
The File Library, ENTSO-E's bulk CSV extracts, is separate: it takes your website login, not the token, and has its own limit of 100 requests a minute.
Document type, area, period
Every request is a GET to https://web-api.tp.entsoe.eu/api with the token, a documentType, one or two area parameters holding EIC codes, and periodStart and periodEnd in UTC as yyyyMMddHHmm. Some document types need a processType or another filter. The name of the area parameter changes with the document type, which is the first thing that trips people up.
| Data (Transparency article) | documentType | Area parameter | Also needs | Free re-use list |
|---|---|---|---|---|
| Day-ahead prices (12.1.D) | A44 | in_Domain and out_Domain, both the zone | contract_MarketAgreement.type=A01 | No: the exchange's or TSO's agreement |
| Actual total load (6.1.A) | A65 | outBiddingZone_Domain | processType=A16 | No: the owner's agreement |
| Day-ahead load forecast (6.1.B) | A65 | outBiddingZone_Domain | processType=A01 | Yes, CC BY 4.0 |
| Actual generation per type (16.1.B and C) | A75 | in_Domain | processType=A16 | No: the owner's agreement |
| Unit unavailability (15.1.A to D) | A77 production, A80 generation | biddingZone_Domain | offset=0, 200, 400 ... | No: the owner's agreement |
| Cross-border physical flows (12.1.G) | A11 | out_Domain and in_Domain, the two zones | none | Yes, CC BY 4.0 |
| Imbalance prices (17.1.G) | A85 | controlArea_Domain | none | Yes, CC BY 4.0 |
The answer is a market document holding one or more TimeSeries. Each has one or more Period blocks with a time interval, a resolution such as PT15M or PT60M, and numbered points. A query with no data, or one the API will not run, comes back as an Acknowledgement_MarketDocument whose Reason says why. This is the shape of an actual total load answer, values left out:
<GL_MarketDocument xmlns="urn:iec62325.351:tc57wg16:451-6:generationloaddocument:3:0">
<mRID>...</mRID>
<revisionNumber>1</revisionNumber>
<type>A65</type>
<process.processType>A16</process.processType>
<TimeSeries>
<outBiddingZone_Domain.mRID codingScheme="A01">10YFR-RTE------C</outBiddingZone_Domain.mRID>
<quantity_Measure_Unit.name>MAW</quantity_Measure_Unit.name>
<curveType>A01</curveType>
<Period>
<timeInterval><start>2026-11-04T23:00Z</start><end>2026-11-05T23:00Z</end></timeInterval>
<resolution>PT15M</resolution>
<Point><position>1</position><quantity>...</quantity></Point>
<Point><position>2</position><quantity>...</quantity></Point>
...
</Period>
</TimeSeries>
</GL_MarketDocument>Area codes we use
| Area | EIC code | Note |
|---|---|---|
| DE-LU (bidding zone) | 10Y1001A1001A82H | Day-ahead, load, generation and outages. Two day-ahead auctions; see the traps. |
| France | 10YFR-RTE------C | The same code serves the A85 imbalance query. |
| Netherlands | 10YNL----------L | The same code serves the A85 imbalance query. |
| Belgium | 10YBE----------2 | Our A85 imbalance query uses the same code. |
| Austria | 10YAT-APG------L | Two day-ahead auctions, as DE-LU. |
| Spain | 10YES-REE------0 | Imbalance prices in two categories, A04 and A05. |
| Norway NO2 | 10YNO-2--------T | Bidding zone. Norway as a whole is 10YNO-0--------C for generation and outages. |
| Italy (national) | 10YIT-GRTN-----B | For generation and outages. Publishes A80 outages, not A77. |
Great Britain has no day-ahead price or generation data on the platform, and an actual load query for GB answers “No matching data found”. Its cross-border flows still publish.
Day-ahead, load, generation and outages from the shell
Set the token and two area codes once. Times are UTC, so a delivery day in Central European Time starts at 23:00 UTC the evening before in winter and 22:00 UTC in summer.
export ENTSOE_TOKEN="paste-your-token-here"
API="https://web-api.tp.entsoe.eu/api"
DE_LU="10Y1001A1001A82H"
FR="10YFR-RTE------C"
# Delivery day 5 Nov 2026 in CET is 4 Nov 23:00 to 5 Nov 23:00 UTC.
FROM=202611042300
TO=202611052300Day-ahead prices (A44)
Day-ahead prices belong to the power exchanges and are not on ENTSO-E's free re-use list, so this guide shows how to request them and prints none. contract_MarketAgreement.type=A01 asks for the daily auction only; leave it out and a zone that also publishes intraday auctions mixes the two in one answer.
# Day-ahead prices (A44), DE-LU. Saved to a file, not printed.
curl -s "$API?securityToken=$ENTSOE_TOKEN&documentType=A44\
&contract_MarketAgreement.type=A01\
&in_Domain=$DE_LU&out_Domain=$DE_LU\
&periodStart=$FROM&periodEnd=$TO" -o a44-de-lu.xmlActual total load (A65) and generation per type (A75)
# Actual total load (A65, processType A16), France
curl -s "$API?securityToken=$ENTSOE_TOKEN&documentType=A65&processType=A16\
&outBiddingZone_Domain=$FR&periodStart=$FROM&periodEnd=$TO" -o a65-fr.xml
# Actual generation per production type (A75, processType A16), France
curl -s "$API?securityToken=$ENTSOE_TOKEN&documentType=A75&processType=A16\
&in_Domain=$FR&periodStart=$FROM&periodEnd=$TO" -o a75-fr.xmlUnit outages (A77 and A80)
# Generation unit unavailability (A80), France, the next 30 days.
# The answer is a ZIP with one XML document per outage, 200 at most:
# ask again with offset=200, 400 ... until a page comes back short.
curl -s "$API?securityToken=$ENTSOE_TOKEN&documentType=A80\
&biddingZone_Domain=$FR&offset=0\
&periodStart=202611060000&periodEnd=202612060000" -o a80-fr-0.zip
unzip -l a80-fr-0.zip | tail -1
# A77 (production units) takes the same parameters.
# Older versions of one outage: ENTSO-E returns them only when the request
# names the outage's mRID (the mRID element of a document above).
curl -s "$API?securityToken=$ENTSOE_TOKEN&documentType=A80\
&biddingZone_Domain=$FR&mRID=PASTE-OUTAGE-MRID\
&periodStart=202611060000&periodEnd=202612060000" -o a80-one-outage.zip
unzip -l a80-one-outage.zipImbalance prices (A85)
# Imbalance prices (A85), Spain. Also a ZIP, asked for by imbalance price area.
curl -s "$API?securityToken=$ENTSOE_TOKEN&documentType=A85\
&controlArea_Domain=10YES-REE------0\
&periodStart=$FROM&periodEnd=$TO" -o a85-es.zip
unzip -l a85-es.zipENTSO-E API in Python with requests
Two helpers do most of the work: fetch sends the request, unzips the archive types and turns an acknowledgement into an exception, and points turns one TimeSeries into a dictionary of UTC start times. Python 3.9 or later, with requests.
import io
import os
import zipfile
import xml.etree.ElementTree as ET
from datetime import datetime, timedelta
import requests
API = "https://web-api.tp.entsoe.eu/api"
TOKEN = os.environ["ENTSOE_TOKEN"]
def fetch(**params):
"""Return the XML documents in one answer, unzipping A85, A77 and A80."""
r = requests.get(API, params={"securityToken": TOKEN, **params}, timeout=60)
if r.status_code == 429:
raise RuntimeError(r.text) # "Requester banned until <instant>"
if r.content[:2] == b"PK":
with zipfile.ZipFile(io.BytesIO(r.content)) as z:
return [z.read(name) for name in z.namelist()]
if b"Acknowledgement_MarketDocument" in r.content:
reason = ET.fromstring(r.content).findtext(".//{*}Reason/{*}text")
raise LookupError(reason) # no data for the query, or a refused query
r.raise_for_status()
return [r.content]
STEP = {"PT15M": 15, "PT30M": 30, "PT60M": 60}
def utc(text):
return datetime.fromisoformat(text.replace("Z", "+00:00"))
def points(series, value_tag):
"""One TimeSeries as {UTC start: value}. Under curveType A03 a point that
repeats the one before is left out, so carry it forward to the end."""
out = {}
fill = series.findtext("{*}curveType") == "A03"
for period in series.iterfind("{*}Period"):
start = utc(period.findtext("{*}timeInterval/{*}start"))
end = utc(period.findtext("{*}timeInterval/{*}end"))
step = timedelta(minutes=STEP[period.findtext("{*}resolution")])
given = {
int(p.findtext("{*}position")): float(p.findtext("{*}" + value_tag))
for p in period.iterfind("{*}Point")
}
last = None
for pos in range(1, int((end - start) / step) + 1):
if pos in given:
last = given[pos]
elif not fill:
continue
if last is not None:
out[start + (pos - 1) * step] = last
return outDay-ahead prices, keeping the SDAC series
DE_LU = "10Y1001A1001A82H"
SEQ = ".//{*}classificationSequence_AttributeInstanceComponent.position"
[doc] = fetch(
documentType="A44",
**{"contract_MarketAgreement.type": "A01"},
in_Domain=DE_LU,
out_Domain=DE_LU,
periodStart="202611042300",
periodEnd="202611052300",
)
day_ahead = {}
for ts in ET.fromstring(doc).iterfind(".//{*}TimeSeries"):
if ts.findtext(SEQ) in (None, "1"): # 1 is SDAC; 2 is the EXAA auction
day_ahead.update(points(ts, "price.amount"))
print(len(day_ahead), "quarter-hours") # 96 on a normal day, 92 or 100 on a clock changeLoad and generation
FR = "10YFR-RTE------C"
window = dict(periodStart="202611042300", periodEnd="202611052300")
[doc] = fetch(documentType="A65", processType="A16", outBiddingZone_Domain=FR, **window)
load = {}
for ts in ET.fromstring(doc).iterfind(".//{*}TimeSeries"):
load.update(points(ts, "quantity")) # MW, a rate
[doc] = fetch(documentType="A75", processType="A16", in_Domain=FR, **window)
generation = {}
for ts in ET.fromstring(doc).iterfind(".//{*}TimeSeries"):
if ts.find("{*}inBiddingZone_Domain.mRID") is None:
continue # pumping and battery charging arrive as a second series
fuel = ts.findtext(".//{*}psrType") # B14 nuclear, B04 fossil gas ...
generation.setdefault(fuel, {}).update(points(ts, "quantity"))Outages, page by page
Each outage is its own document with an mRID and a revisionNumber. The unavailable capacity is the nominal power minus the available quantity in each Available_Period.
# Without DocStatus, ENTSO-E returns active and cancelled outages only.
outages, offset = [], 0
while True:
try:
docs = fetch(
documentType="A80",
biddingZone_Domain=FR,
offset=offset,
periodStart="202611060000",
periodEnd="202612060000",
)
except LookupError:
break # nothing (more) for this window
for xml in docs:
root = ET.fromstring(xml)
outages.append({
"mrid": root.findtext("{*}mRID"),
"revision": int(root.findtext("{*}revisionNumber")),
"status": root.findtext("{*}docStatus/{*}value") or "active", # A09 cancelled, A13 withdrawn
"kind": root.findtext(".//{*}businessType"), # A53 planned, A54 forced
"unit": root.findtext(".//{*}production_RegisteredResource.name"),
"nominal": root.findtext(".//{*}production_RegisteredResource.pSRType.powerSystemResources.nominalP"),
})
if len(docs) < 200:
break
offset += 200
def versions(mrid, period_start, period_end):
"""The versions of one outage that ENTSO-E returns for the period you ask.
Without mRID a query returns the current version only. Withdrawn versions
come back only on a pass with DocStatus=A13, so ask twice, page by page,
and make the period cover the outage's whole life. ENTSO-E caps one
request at one year, so a longer window is refused with an
acknowledgement, which this loop reads as "no more": split a longer
life into yearly windows and call it once for each."""
found = {}
for status in (None, "A13"): # active and cancelled, then withdrawn
offset = 0
while True:
params = dict(
documentType="A80",
biddingZone_Domain=FR,
mRID=mrid,
offset=offset,
periodStart=period_start,
periodEnd=period_end,
)
if status:
params["DocStatus"] = status
try:
docs = fetch(**params)
except LookupError:
break
for xml in docs:
root = ET.fromstring(xml)
revision = int(root.findtext("{*}revisionNumber"))
found[revision] = root.findtext("{*}docStatus/{*}value") or "active"
if len(docs) < 200:
break
offset += 200
return dict(sorted(found.items()))Imbalance prices
[doc] = fetch(
documentType="A85",
controlArea_Domain="10YES-REE------0",
periodStart="202611042300",
periodEnd="202611052300",
)
imbalance = {}
for ts in ET.fromstring(doc).iterfind(".//{*}TimeSeries"):
category = ts.findtext(".//{*}imbalance_Price.category") or "single" # A04 or A05
imbalance.setdefault(category, {}).update(points(ts, "imbalance_Price.amount"))
print({k: len(v) for k, v in imbalance.items()}) # counts, one entry per categoryIf you would rather not write the parsing, entsoe-py is a widely used open-source Python client that returns pandas series and data frames, and entsoeapi does the same for R. Whichever you use, check a day you know against the platform's website, a clock-change day included, and check how it handles the traps in section 06.
400 requests a minute, and a ban when you go over
ENTSO-E allows 400 requests a minute per token. The next one gets HTTP 429 with a body that reads “Requester banned until” and an instant about ten minutes ahead, and every request on that token fails until then. The ban covers the token, so a website and a worker that share one token share the ban.
We met it on 8 Sep 2026, and it was our own doing. After a long outage, our health checks retried every failed ENTSO-E request on each poll, and the moment the API came back the burst went over the limit: the first answer after the outage was the ban. Since then one gate sits in front of every request we send. It admits at most 80 a minute from one process, honours the instant in a 429, and stops for a minute after eight failures in a row, so a failed burst is remembered rather than repeated.
The API goes down for days
- The Web API answered 503 from the evening of 30 Aug 2026 until 2 Sep, about 65 hours hard down.
- Our monitoring saw it down again for about 27 hours on 7 and 8 Sep 2026, during ENTSO-E's infrastructure migration.
- The File Library kept serving monthly extracts through the first outage. Build the fallback before you need it, and alert on stale data, not only on failed requests.
What the documentation does not warn you about
A85 imbalance prices arrive as a ZIP
Imbalance prices come back as a ZIP archive even for a one-hour window, not as XML like day-ahead prices. The archive is written with the streaming flag set, so the compressed size in each local header is zero and the real sizes sit only in the central directory. Python's zipfile reads the central directory and copes; a small hand-written reader that trusts the local header gets nothing. Inside, the value tag is imbalance_Price.amount with a capital P. Areas that price both directions, Spain and France among them, publish two series for the same quarter-hour, category A04 for surplus and A05 for deficit, with different values: keep them apart. A query with no data comes back as a plain, unzipped acknowledgement. Unit outages (A77, A80) are ZIPs too, one XML document per outage.
A44 returns two day-ahead auctions for DE-LU and Austria
DE-LU and Austria have a second day-ahead auction run by EXAA, so A44 returns two TimeSeries per delivery day with the same contract type and business type. Only classificationSequence_AttributeInstanceComponent.position tells them apart: 1 is the SDAC coupling price, 2 is EXAA. Their order in the document is not stable; we saw both orders live, so code that lets the last series win picks an auction by luck. We found it on 20 Jul 2026, when our cross-check against the Bundesnetzagentur's SMARD failed for DE-LU and Austria and matched to the cent everywhere else.
A second trap sits inside the first. Day-ahead series use curveType A03, which leaves out any point whose value repeats the one before. Left unfilled, those gaps read as missing quarter-hours, and the EXAA series' explicit point at the same instant can slip into them. Carry each value forward to the end of its period, as points() above does, and keep sequence 1 and untagged series only.
DE-LU, 13 Sep 2026: a day published late
When we looked on 14 Sep 2026, the A44 answer for DE-LU delivery day 13 Sep carried only the EXAA series. The SDAC series was absent from every window we tried, including a request filtered to position 1, and the File Library's monthly extract lacked the same rows. The auction had cleared and other public sources had all 96 quarter-hours, so the gap was in the platform's publication. ENTSO-E published an SDAC series for that day later: by 23 Sep it was there, with 95 points in our record, so count it again before you call it whole.
Late publication is the trap. A parser that correctly drops the EXAA series is left with no prices for that day, and a feed that re-reads only the last few days never picks up the late series once the day has fallen out of its window, so the hole stays in your store after ENTSO-E has published the series. Count points per delivery day against what the day should hold (96 quarter-hours, 92 or 100 on a clock-change day), alert on a short day, and go back for it later rather than trusting that a 200 OK means complete.
More we met
- Outage paging. A77 and A80 answer at most 200 documents, and a query that would return more fails with “exceeds the allowed maximum” unless you pass
offset. Withoffset=0,200,400it pages cleanly. - Italy and kilowatts. Italy publishes A80 outages and no A77. Some Italian units give their nominal power in kW while labelling it MW: in an Italian A80 pull on 23 Sep 2026, 191 of 327 documents carried a nominal power between 106,000 and 885,000. Read as MW, one plant showed hundreds of gigawatts unavailable.
- Storage in the generation mix. In A75, pumped storage (B10) and batteries (B25) publish two series per fuel: one tagged
inBiddingZone_Domainfor generation and one taggedoutBiddingZone_Domainfor pumping or charging. Add them together and you blend output with consumption. - Resolution changes under you. Day-ahead moved to 15-minute products on 1 Oct 2025, so a long history mixes
PT60MandPT15Mperiods. Read the resolution from each period, never assume it. - Imbalance prices are reported, by default, per imbalance price area. A85 takes the area in
controlArea_Domain, and the area is not always the bidding zone. In July 2026 we asked for the four German control-area codes (10YDE-VE-------2,10YDE-RWENET---I,10YDE-EON------1,10YDE-ENBW-----N) on a 35-day lookback, and all four returned nothing but acknowledgements. Germany settles imbalance with one price, reBAP, that its TSOs publish on netztransparenz.de.
The first value, outage filings as of a moment, one schema
The value as first published
The API answers with values as they stand when you ask. Ask again tomorrow and a corrected value replaces the one you saw, with nothing in the answer to say it changed. Imbalance prices carry a status of intermediate or final, and on 28 Oct 2026 some Belgian prices from January 2026 and Austrian prices for whole months of 2025 were still intermediate. If a backtest, a settlement check or a trade review needs to know what the number said at the time, you have to keep that copy yourself, with the time you read it.
| Series (ENTSO-E) | Quarter-hours first seen | Corrected | Detail |
|---|---|---|---|
| Spain imbalance price, surplus (A04) | 3,674 | 2,423 (66%) | Typically about 35 hours from first capture to last correction; 142 corrections changed the sign of the price. A minimum. |
| Spain imbalance price, deficit (A05) | 3,677 | 2,456 (67%) | Typically about 34.5 hours to last correction; 140 changed sign. A minimum. |
| Austria imbalance price (A04) | 3,274 | 1,606 (49%) | 1,248 of the 1,606 were corrected more than once; typically 38 hours to last correction. A minimum. |
These counts come from Voltstack's own capture between 23 Sep and 28 Oct 2026, read every 30 minutes with each read reaching about three days back. A correction made after those three days is not counted, and later corrections are common: for delivery on 21 Sep, 96 of the 102 Spanish quarter-hours we had recorded as corrected had changed again by 28 Oct. The window is five weeks, so do not read it as “always”. The method and the change records are published: the paper (doi:10.5281/zenodo.23749147) and its dataset (doi:10.5281/zenodo.23749094). Both are ours: the author runs Voltstack, and the capture is Voltstack's.
Outage filings as they stood at a past moment
Ask for a window of A77 or A80 and you get each outage at its current version. ENTSO-E's documentation says older versions of an outage are returned only when the request names its mRID, so the history is there one outage at a time: you need the mRID of each outage you care about and a request for each, as versions() above does. Without mRID a query returns current versions only, so no single request rebuilds the whole outage list as it stood at 08:00 on the morning you traded. The revisionNumber counts the filings, and we have seen one reach 256; a cancelled outage carries docStatus A09 and a withdrawn one A13, and a query without DocStatus returns active and cancelled outages only, so withdrawn ones need a second request with DocStatus=A13. If you need that as-of view across every unit, store each revision as you see it, keyed on mRID and revisionNumber, and never overwrite.
One schema across zones
Each document type names its area differently, resolution differs by zone and by year, A03 series leave out repeated points, some zones publish two auctions or two imbalance categories and others one, the four German control-area codes returned no imbalance prices when we tried them in July 2026, Italy files A80 and no A77, and GB is gone from prices and generation. Every consumer of the raw API ends up writing the same normalisation layer, and finds each of these differences the first time a cross-check fails.
Free to download is not free to republish
Items on ENTSO-E's List of Data Available for Free Re-use (18 Oct 2023) are CC BY 4.0 under its Terms of Use applicable from 1 Nov 2023: load forecasts, cross-border flows, transfer capacities, redispatch, and balancing and imbalance data among them. Credit “ENTSO-E Transparency Platform”, link the licence and say what you changed. IFA and Nemo Link data are excluded even for listed items.
Items off the list, day-ahead prices, actual total load, generation and unit outages among them, need the agreement of the data's primary owner before you republish them or feed them to someone else's model, and ENTSO-E's terms say its own rights cannot be sub-licensed. Day-ahead prices belong to the exchanges whichever route they reach you by. The 2027 edition of our API ratings sets out the licence of each source, including for AI use. This is a reading of published terms, not legal advice.
ENTSO-E API questions
How do I get an ENTSO-E API key?
securityToken parameter.Is the ENTSO-E API free?
What is the ENTSO-E API rate limit?
Why does the ENTSO-E imbalance price request return a ZIP file?
Why does ENTSO-E return two day-ahead prices for Germany?
classificationSequence_AttributeInstanceComponent.position: 1 is the SDAC coupling price, 2 is EXAA. The order in the document is not stable, so filter on the position instead of taking the last series.Does ENTSO-E data change after it is published?
Is there a Python library for the ENTSO-E API?
Keep the value you saw, not only the value that stands now
Voltstack keeps each value it reads with the time it read it: ENTSO-E imbalance prices and cross-border flows since 23 Sep 2026, so a desk can see what a quarter-hour said at a past moment and what it says now. Other series are served as currently published. The 14-day trial opens the workspace with these series in it; the Voltstack API is in early access, with keys issued on request.
The button opens a 14-day free trial sign-up. Sign-up needs a work email.
The button opens the early-access request on our home page.
More for builders
Sources: ENTSO-E Transparency Platform (https://transparency.entsoe.eu/), its Web API and File Library, its Terms of Use (1 Nov 2023) and List of Data Available for Free Re-use (18 Oct 2023). Request parameters, area codes and the traps come from the code and notes behind Voltstack's own ENTSO-E feeds, as of 6 Nov 2026. Correction counts: Voltstack capture of the ENTSO-E Transparency Platform, 23 Sep to 28 Oct 2026, CC BY 4.0, aggregated and changed by Voltstack (doi:10.5281/zenodo.23749147). This page prints no price from ENTSO-E or any exchange.
Disclaimer: Produced by Voltstack Intelligence for information only. ENTSO-E changes its API and terms from time to time; check the platform's own documentation before you rely on a parameter here. Corrections to research@voltstack.energy.