Julia API Reference
Client
ENTSOE.Client Type
Client(base_url::AbstractString; auth::Auth = NoAuth(), kwargs...)Ergonomic wrapper around OpenAPI.Clients.Client. Composes an Auth strategy into the inner client's pre_request_hook. Extra kwargs are forwarded verbatim to OpenAPI.Clients.Client.
For retry / rate-limit / timeout / logging, compose the call with with_defaults or default_middleware — the Client itself stays minimal so users can pick their own stack per call.
Auth
ENTSOE.Auth Type
AuthAbstract supertype for authentication strategies, applied to outgoing requests via apply! and composed into a pre_request_hook for OpenAPI.Clients.Client by build_pre_request_hook.
ENTSO-E authenticates via a securityToken query parameter, which header-based strategies cannot express — ENTSOEClient therefore always uses NoAuth plus its own query-injecting hook. The Auth seam stays for API completeness and testing.
ENTSOE.NoAuth Type
NoAuth()Pass-through auth: leaves request headers untouched. What ENTSOEClient uses — the real credential travels as the securityToken query parameter injected by its pre-request hook.
ENTSOE.apply! Function
apply!(auth::Auth, headers::Dict{String,String}) -> NothingInject credentials into the outgoing request headers.
sourceENTSOE.build_pre_request_hook Function
build_pre_request_hook(auth) -> FunctionBuild the pre_request_hook accepted by OpenAPI.Clients.Client. The hook implements both required signatures: a Ctx-only pass-through and a (resource, body, headers) form that calls apply! on auth.
Errors
ENTSOE.NetworkError Type
NetworkError(cause)Wraps an underlying transport-layer exception (DNS failure, connection reset, TLS handshake error, etc.).
sourceENTSOE.ClientError Type
ClientError(status, body, parsed=nothing)A 4xx response — caller error. parsed may be nothing or the JSON-decoded body, depending on Content-Type.
ENTSOE.ServerError Type
ServerError(status, body, parsed=nothing)A 5xx response — server-side failure.
sourceENTSOE.AuthError Type
AuthError(status, message)A 401 / 403 response — authentication or authorization failure.
sourceENTSOE.RateLimitError Type
RateLimitError(status=429; retry_after=nothing, body="")A 408 or 429 response. retry_after is the parsed Retry-After header value in seconds, or nothing when absent / unparsable.
ENTSOE.TimeoutError Type
TimeoutError(phase::Symbol)Request exceeded the configured timeout. phase is :connect, :read, or :total.
ENTSOE.check_response Function
check_response(status, body, headers=Dict()) -> NothingThrow the appropriate APIError subtype based on the HTTP status. Returns nothing for 2xx responses.
ENTSOE.rate_limit_message Function
rate_limit_message(err::RateLimitError) -> Union{String,Nothing}Extract the human-readable message from ENTSO-E's HTML 429 body, or nothing when the body is empty / non-HTML / shape-unrecognised. The platform serves a short HTML page on rate-limit hits whose first <p> carries the explanation (e.g. "Your request has exceeded the API throttling limit of 380 requests per minute. The platform will respond again at …"). For non-HTML bodies the raw body field is still available on the error.
ENTSOE.parse_retry_after Function
parse_retry_after(header) -> Union{Float64,Nothing}Parse a Retry-After header value. Supports the seconds form only — HTTP date form returns nothing.
Reliability
ENTSOE.RetryPolicy Type
RetryPolicy(; max_attempts=5,
base_delay=0.5,
max_delay=30.0,
retryable_statuses=DEFAULT_RETRYABLE_STATUSES,
retry_on_network_error=true)Exponential-backoff-with-full-jitter retry configuration. Used by with_retry.
ENTSOE.with_retry Function
with_retry(fn; policy=RetryPolicy(), sleep_fn=Base.sleep, jitter=rand) -> AnyRun fn() under the retry policy. Returns the first non-retryable result. For RateLimitError, the longer of backoff_delay and the server-supplied retry_after is used. sleep_fn and jitter are injectable so tests can avoid real sleeps and assert exact delays.
ENTSOE.is_retryable Function
is_retryable(policy, err) -> BoolDecide whether a thrown exception should trigger another attempt under policy. Honors retryable_statuses for ClientError/ServerError/ RateLimitError, and retry_on_network_error for NetworkError.
ENTSOE.backoff_delay Function
backoff_delay(policy, attempt; jitter=rand)Return the seconds to sleep before retrying. Implements exponential backoff with full jitter, capped at policy.max_delay. jitter is a 0-arg function returning a value in [0, 1); override in tests for determinism.
ENTSOE.TokenBucket Type
TokenBucket(; rate=10.0, burst=10.0)Token-bucket rate limiter. rate is tokens added per second; burst is the maximum reservoir size (and the initial fill).
ENTSOE.acquire! Function
acquire!(bucket; tokens=1.0, timeout=Inf, sleep_fn=Base.sleep, time_fn=time)Block until tokens tokens are available, or throw RateLimitError if the wait would exceed timeout seconds. time_fn and sleep_fn are injectable for testing.
ENTSOE.with_rate_limit Function
with_rate_limit(bucket, fn; kwargs...) -> AnyAcquire from bucket then run fn(). Extra kwargs are forwarded to acquire!.
ENTSOE.with_timeout Function
with_timeout(fn, seconds; phase=:total) -> AnyRun fn() on a background task; throw TimeoutError(phase) if it doesn't complete within seconds. seconds = Inf disables the timeout.
Warning
Julia cannot forcibly cancel a running task, so the underlying work may continue past the timeout. For HTTP calls, prefer the transport-layer connect_timeout / readtimeout exposed by OpenAPI.Clients.Client.
ENTSOE.with_logging Function
with_logging(fn; level=Logging.Info, label="api-call") -> AnyWrap fn() in begin/end log records at level. Captures the elapsed time and outcome (:ok / :error); re-throws any exception unchanged. Useful as the outermost link in a default_middleware stack.
ENTSOE.redact_headers Function
redact_headers(headers) -> Dict{String,String}Return a copy of headers with values for sensitive entries replaced by "[redacted]". Header names are matched case-insensitively. Used by with_logging; also useful when surfacing headers in error messages.
ENTSOE.DefaultMiddleware Type
DefaultMiddleware(; retry, rate_limit, timeout, log_label)Bundle of reliability primitives composed by default_middleware and with_defaults. Each field is nothing to disable that link in the chain.
ENTSOE.default_middleware Function
default_middleware(; kwargs...) -> DefaultMiddlewareBuild a sensible reliability stack. Forward to with_defaults to execute a callable under it.
mw = default_middleware(; rate_limit = TokenBucket(; rate = 5, burst = 10),
timeout = 10.0)
result = with_defaults(mw) do
list_pets(client)
endENTSOE.with_defaults Function
with_defaults(fn, mw::DefaultMiddleware) -> Any
with_defaults(fn; kwargs...) -> AnyRun fn() under the configured middleware stack. Order, top-down: 2. Logging (outermost — sees all attempts and outcomes)
Retry (re-runs everything below on retryable errors)
Rate limit (waits for a token)
Timeout (innermost — bounds a single attempt)
Disable any link by setting it to nothing.
Pagination
Pretty printing
Base.show Method
Base.show(io::IO, ::MIME"text/plain", x::OpenAPI.APIModel)Pretty multi-line display for any generated model type. Lists each non-nothing property on its own line, indented under the type name. Falls back to string for nested models so the output stays readable in the REPL.
ENTSO-E client + period
ENTSOE.ENTSOEClient Function
ENTSOEClient(token; base_url=ENTSOE_BASE_URL, validate_token=false, kwargs...) -> ClientBuild a Client wired with ENTSO-E's securityToken query-parameter auth. Every operation in the generated API declares the SecurityToken security requirement, and this client's pre_request_hook injects the token into the query string for those operations.
Empty or whitespace-only tokens are always rejected with ArgumentError. Pass validate_token = true to additionally require UUID format (see is_uuid_token) — useful when the token comes from user input or config files where typos are likely. The string "PLAYBACK" is always accepted so BrokenRecord-driven tests keep working.
The generated <Group>Api constructors take an OpenAPI.Clients.Client, so unwrap with .inner before constructing them — or use entsoe_apis which does that for you and returns one API per ENTSO-E group:
using ENTSOE
client = ENTSOEClient(ENV["ENTSOE_API_TOKEN"]; validate_token = true)
apis = entsoe_apis(client)
start = entsoe_period(Dates.DateTime("2023-08-23T22:00"))
stop = entsoe_period(Dates.DateTime("2023-08-24T22:00"))
xml, _ = market121_d_energy_prices(apis.market, "A44", EIC.NL, EIC.NL, start, stop)Extra keyword arguments are forwarded verbatim to OpenAPI.Clients.Client (useful for timeout, httplib, etc.).
ENTSOEClient()Convenience no-arg form: builds a client using the token and endpoint from get_config. Token resolution order: 2. get_config().token
ENV["ENTSOE_API_TOKEN"]
Throws if neither is set.
sourceENTSOE.entsoe_apis Function
entsoe_apis(c::Client) -> NamedTupleOne API instance per ENTSO-E group, ready to pass to the generated query functions:
apis = entsoe_apis(client)
apis.market # MarketApi
apis.load # LoadApi
apis.generation # GenerationApi
# ... balancing, master_data, omi, outages, transmissionENTSOE.entsoe_period Function
entsoe_period(t) -> Int64Format t as the integer ENTSO-E expects for periodStart / periodEnd, namely yyyyMMddHHmm in UTC.
Accepts:
Dates.DateTime— interpreted as UTC.Dates.Date— interpreted as00:00UTC on that day.TimeZones.ZonedDateTime— converted to UTC first.
Examples
julia> using Dates: DateTime
julia> entsoe_period(DateTime("2023-08-23T22:00"))
202308232200ENTSOE.is_uuid_token Function
is_uuid_token(token) -> Booltrue when token is in canonical UUID form (8-4-4-4-12 hyphenated, or 32 bare hex characters). ENTSO-E's API keys are UUIDs; callers can use this to fail fast on obviously-malformed input without paying a 401 round-trip. The opt-in validate_token = true kwarg on ENTSOEClient wraps it.
ENTSOE.ENTSOE_BASE_URL Constant
ENTSOE_BASE_URLThe public Transparency Platform API base URL — "https://web-api.tp.entsoe.eu/api". Default value for ENTSOEClient's base_url keyword; override only when testing against the IOP environment or a recorded mock server.
Module configuration
ENTSOE.ENTSOEConfig Type
ENTSOEConfigHolds the global default token, endpoint URL, whether named-argument wrappers should run validate_eic by default, and whether the time-series parsers forward-fill ENTSO-E's sparse (curveType A03) step-function points. Construct via set_config; read via get_config.
Defaults:
token— empty (the no-argENTSOEClientconstructor will fall back toENV["ENTSOE_API_TOKEN"]if both this and the explicit arg are unset).endpoint_url—ENTSOE_BASE_URL(https://web-api.tp.entsoe.eu/api).validate_eic—false. Passingvalidate_eic = truetoset_configmakes every named-arg wrapper validate the EIC by default; the per-callvalidate = …keyword still overrides.fill_gaps—true. ENTSO-E emits variable-sized block (curveTypeA03) series in which unchanged points are omitted: a<Point>at positionpholds until the next listed position (or the period's end). Withfill_gaps = truethe time-series parsers expand those runs so every resolution step gets a row; setfill_gaps = false(globally here, or per-call on theparse_timeseriesfamily) to keep only the literal points. For dense (A01) series the expansion is a no-op.window_concurrency—1(strictly sequential). Auto-split wrappers fetch their period windows one after another by default; settingwindow_concurrency = noverlaps up tonwindow requests per call. Mind ENTSO-E's ~400 requests/minute ban threshold before raising this — pair it with aTokenBucketwhen a script fires many split queries.
ENTSOE.set_config Function
set_config(; token=nothing, endpoint_url=nothing, validate_eic=nothing, fill_gaps=nothing) -> ENTSOEConfigUpdate the global ENTSOEConfig. Any keyword left as nothing keeps its current value. Returns the new (mutated) config.
ENTSOE.set_config(; token = ENV["ENTSOE_API_TOKEN"], validate_eic = true)
client = ENTSOEClient() # picks up the global token
prices = day_ahead_prices(client, EIC.NL,
DateTime("2024-09-01T22:00"),
DateTime("2024-09-02T22:00"))ENTSOE.get_config Function
get_config() -> ENTSOEConfigReturn the current global ENTSOEConfig.
EIC codes
Three ways to spell the same zone:
EIC.NL # field access — best when the zone is a literal
EIC("NL") # callable — useful when zones are built from string data
"10YNL----------L" # the raw 16-char code is always acceptedENTSOE.EIC Constant
EICCurated table of EIC (Energy Identification Code) strings for the most frequently queried ENTSO-E bidding zones and control areas. Use these as in_Domain / out_Domain / area values for the generated query functions:
market121_d_energy_prices(api, "A44", EIC.NL, EIC.NL, period_start, period_end)Three equivalent spellings of the same zone:
EIC.NL # field access — best when the zone is a literal
EIC("NL") # callable — useful when zones are built from string data
"10YNL----------L" # the raw 16-char code is always acceptedThe list is intentionally not exhaustive — pass any 16-character EIC string directly when your zone isn't here. Authoritative codes are published by ENTSO-E at https://www.entsoe.eu/data/energy-identification-codes-eic/.
sourceMissing docstring.
Missing docstring for EIC(::AbstractString). Check Documenter's build log for details.
ENTSOE.EIC_REGISTRY Constant
EIC_REGISTRY :: Dict{String, Vector{NamedTuple{(:name, :types), …}}}Comprehensive catalog of every Energy Identification Code emitted by the ENTSO-E Transparency Platform — about 120 entries covering bidding zones (:BZN), control areas (:CTA), market balance areas (:MBA), scheduling areas (:SCA), load-frequency areas/blocks (:LFA/:LFB), imbalance pricing/balancing areas (:IPA/:IBA), aggregated zones (:BZA), regions (:REG), countries (:CTY), synchronous areas (:SNA), and a handful of cross-border interconnectors.
A single EIC sometimes represents multiple aliases (e.g. SEM in Ireland maps to both IE(SEM) and IE-NIE); the value is therefore a vector of (name, types) rather than a single tuple.
Use lookup_eic for safe lookups and is_known_eic to validate user input. ENTSO-E's authoritative register lives at https://www.entsoe.eu/data/energy-identification-codes-eic/.
julia> lookup_eic("10YNL----------L")
1-element Vector{@NamedTuple{name::String, types::Vector{Symbol}}}:
(name = "NL", types = [:BZN, :CTA, :CTY, :LFA, :LFB, :MBA, :SCA])
julia> is_known_eic("10YNOT-A-CODE---")
falseENTSOE.NEIGHBOURS Constant
NEIGHBOURSCurated EIC → Vector{String} map of cross-border interconnections, keyed by 16-character EIC. Used by cross_border_physical_flows_all to iterate over a zone's neighbours. Covers the most-queried bidding zones — extend in user code by mutating the dict or by passing an explicit neighbours kwarg to the helper.
ENTSOE.lookup_eic Function
lookup_eic(code) -> Vector{NamedTuple{(:name, :types), …}}Return every entry registered for the given EIC code. Empty vector when the code is unknown — see is_known_eic for a boolean form. Most EICs map to exactly one entry; SEM-Ireland and a handful of cross-zone aggregates have two or three.
ENTSOE.is_known_eic Function
is_known_eic(code) -> BoolReturn true if code appears in the registry. Used by validate_eic for opt-in client-side input validation; off by default because the registry trails ENTSO-E's authoritative list — a new bidding zone takes a release before it shows up here.
ENTSOE.eics_of_type Function
eics_of_type(type::Symbol) -> Vector{String}Every EIC code that carries the given type tag (e.g. :BZN, :CTA). Useful for "show me every bidding zone" type queries:
julia> bidding_zones = eics_of_type(:BZN); # ~70 entries
julia> "10YNL----------L" in bidding_zones
trueENTSOE.validate_eic Function
validate_eic(code; type=nothing) -> NothingThrow a descriptive ArgumentError if code is not in the EIC_REGISTRY. Optionally also require the entry to carry a specific area-type tag — e.g. validate_eic(area; type = :BZN) rejects control areas, market balance areas, etc. that aren't bidding zones.
Off by default in the named-argument query wrappers (the registry trails ENTSO-E's authoritative list — newly created bidding zones won't be in it for a release or two). Enable explicitly per call:
day_ahead_prices(client, area, start, stop; validate = true)A typo or scrambled code is by far the most common cause of an ENTSO-E "no matching data" acknowledgement, so flipping this on is a cheap way to debug.
sourceCode lists
ENTSO-E parameters that take IEC code-list values (psrType, businessType, …) are exposed in two complementary shapes:
Semantic-name → code constants for passing to wrappers (
PsrType.SOLAR == "B16",BusinessType.PLANNED_OUTAGE == "A53", …).Code → description NamedTuples for labelling output (
PSR_LABELS.B16 == "Solar",code_for(PSR_LABELS, "wind onshore")).
A third shape, PsrGroup, holds subset tuples for client-side filtering (caps[in.(caps.psr_type, Ref(PsrGroup.HYDRO))]).
ENTSOE.CodeTable Type
CodeTableLookup wrapper around a curated ENTSO-E code list. Owned by ENTSOE.jl so the (::CodeTable)(name) call method isn't piracy on Base.NamedTuple.
Supports the same surface as a NamedTuple:
Field access —
PsrType.SOLARCallable lookup —
PsrType("SOLAR")(case-insensitive name) orPsrType("B16")(raw-code pass-through, validated)Iteration over values —
for v in PsrType; ...; endpropertynames(PsrType),keys,values,pairs,haskey,length
The first field of each constant is the table name (for error messages); the second is the underlying NamedTuple of entries.
ENTSOE.PsrType Constant
PsrTypeENTSO-E psrType codes (production / consumption / infrastructure taxonomy) keyed by semantic name. Each value is a String holding the IEC code:
julia> PsrType.SOLAR
"B16"
julia> PsrType.WIND_ONSHORE
"B19"Pass directly to any wrapper that accepts psr_type:
wind_solar_forecast(client, EIC.NL, t1, t2; psr_type = PsrType.SOLAR)For filtering result tables after a fetch, use PsrGroup subset tuples instead — PsrGroup.HYDRO returns ("B10", "B11", "B12"), which works with in.(rows.psr_type, Ref(...)).
See PSR_LABELS for code → description lookup.
ENTSOE.PsrGroup Constant
PsrGroupCurated subset tuples for grouped client-side filtering of PSR codes. Each value is a Tuple{Vararg{String}} holding the IEC codes in the group:
julia> PsrGroup.HYDRO
("B10", "B11", "B12")Typical use — filter a result table to a family of technologies:
caps = installed_capacity_per_production_type(client, EIC.NL, t1, t2)
hydro_caps = caps[in.(caps.psr_type, Ref(PsrGroup.HYDRO))]The groups are not exhaustive partitions — OTHER, OTHER_RENEWABLE, aggregations (MIXED / GENERATION / LOAD), and infrastructure types are deliberately excluded. Extend in user code by building your own tuple.
ENTSO-E accepts only a single psr_type per server-side query, so groups are useful after a fetch; passing a PsrGroup value directly as the psr_type kwarg will raise.
ENTSOE.BusinessType Constant
BusinessTypeENTSO-E businessType codes keyed by semantic name. Pass directly to any wrapper that accepts business_type:
unavailability_of_generation_units(client, EIC.BE, t1, t2;
business_type = BusinessType.PLANNED_OUTAGE)See BUSINESS_LABELS for code → description lookup.
julia> BusinessType.AREA_CONTROL_ERROR
"B33"ENTSOE.ProcessType Constant
ProcessTypeENTSO-E processType codes keyed by semantic name. Pass directly to any wrapper that accepts process_type:
volumes_and_prices_of_contracted_reserves(client, EIC.DE_LU, t1, t2;
process_type = ProcessType.AFRR)See PROCESS_LABELS for code → description lookup.
julia> ProcessType.REALISED
"A16"ENTSOE.DocumentType Constant
DocumentTypeENTSO-E documentType codes keyed by semantic name. Most named wrappers fill document_type for you — reach for this when calling the generated layer directly or post-processing Raw() responses.
See DOCUMENT_LABELS for code → description lookup.
julia> DocumentType.PRICE
"A44"ENTSOE.AuctionType Constant
AuctionTypeENTSO-E auction.Type codes (Market allocation endpoints).
julia> AuctionType.IMPLICIT
"A01"ENTSOE.AuctionCategory Constant
AuctionCategoryENTSO-E auction.Category codes (Market allocation endpoints).
julia> AuctionCategory.HOURLY
"A04"ENTSOE.ContractType Constant
ContractTypeENTSO-E contract_MarketAgreement.Type codes — the agreement horizon of a market document. Same code shared across day-ahead / intraday / forward variants.
julia> ContractType.DAILY
"A01"ENTSOE.DocStatus Constant
DocStatusENTSO-E docStatus codes — used by the Outages endpoints to slice notices by status (active vs cancelled vs withdrawn).
julia> DocStatus.WITHDRAWN
"A13"ENTSOE.StandardProduct Constant
StandardProductENTSO-E standard_MarketProduct codes — selects the standard balancing product family on the contracted-reserves / balancing-energy-bids endpoints.
julia> StandardProduct.STANDARD
"A01"ENTSOE.DOCUMENT_LABELS Constant
DOCUMENT_LABELSCanonical ENTSO-E documentType code → description NamedTuple, keyed by the IEC code symbol (e.g. :A44). Used for human-readable output and code_for(DOCUMENT_LABELS, "price document") reverse lookup.
For passing a documentType into a query, prefer the semantic DocumentType constant (DocumentType.PRICE == "A44").
julia> DOCUMENT_LABELS.A44
"Price document"ENTSOE.PROCESS_LABELS Constant
PROCESS_LABELSCanonical ENTSO-E processType code → description NamedTuple. Use ProcessType (ProcessType.REALISED == "A16") when passing a processType into a query.
julia> PROCESS_LABELS.A16
"Realised"ENTSOE.BUSINESS_LABELS Constant
BUSINESS_LABELSCanonical ENTSO-E businessType code → description NamedTuple — the most heavily overloaded code list in the standard. These describe the purpose of a document or TimeSeries (energy, capacity, reserve, balancing, redispatch …).
Use BusinessType (BusinessType.PLANNED_OUTAGE == "A53") when passing a businessType into a query.
julia> BUSINESS_LABELS.A33
"Outage"ENTSOE.PSR_LABELS Constant
PSR_LABELSCanonical ENTSO-E psrType code → description NamedTuple — the production / consumption / infrastructure type taxonomy used by the generation, capacity, and balancing endpoints.
Use PsrType (PsrType.SOLAR == "B16") when passing a psrType into a query, and PsrGroup for subset filters (PsrGroup.HYDRO == ("B10", "B11", "B12")).
julia> PSR_LABELS.B16
"Solar"ENTSOE.describe Function
describe(table, code) -> StringResolve a code (string or symbol) against one of the description NamedTuples DOCUMENT_LABELS, PROCESS_LABELS, BUSINESS_LABELS, PSR_LABELS. Throws KeyError if the code isn't in the table.
julia> ENTSOE.describe(DOCUMENT_LABELS, "A44")
"Price document"
julia> ENTSOE.describe(PSR_LABELS, :B19)
"Wind Onshore"ENTSOE.code_for Function
code_for(table, label) -> StringReverse-lookup: case-insensitive substring match on the human-readable description; returns the string code (e.g. "A44"). Useful for quickly finding a code from a fragment of the official label.
julia> ENTSOE.code_for(PSR_LABELS, "wind onshore")
"B19"
julia> ENTSOE.code_for(DOCUMENT_LABELS, "price document")
"A44"Throws if zero or multiple entries match.
sourceXML response parsing
ENTSOE.parse_timeseries Function
parse_timeseries(xml) -> StructVector{@NamedTuple{time::DateTime, value::Float64}}Walk every <TimeSeries>/<Period>/<Point> in the document and produce a Tables.jl-compatible StructVector with two columns:
time—DateTime(UTC) computed from<timeInterval>/<start>plus(position - 1) * resolutionvalue—Float64from<quantity>(load, generation, capacity, balancing volumes) or<price.amount>(price documents), whichever the point carries.
The result indexes like a Vector{NamedTuple} (prices[1].value) and also exposes columns directly (prices.value, prices.time — Vector{Float64} / Vector{DateTime}). It plumbs straight into DataFrames (DataFrame(prices)) and any other Tables.jl consumer.
Returns an empty StructVector if the document has no usable TimeSeries — typically because the API returned an ENTSOEAcknowledgement. For typed handling of that case use a pipeline that calls check_acknowledgement first.
Sparse (curveType A03) series and fill_gaps
ENTSO-E often emits variable-sized block series (<curveType>A03) in which unchanged points are omitted: a <Point> at position p holds its value until the next listed position, and the final point holds until the period's <timeInterval>/<end>. Read literally this leaves gaps in the time column (e.g. a jump from 17:00 straight to 19:00). With fill_gaps = true (the default, taken from get_config().fill_gaps) the parser forward-fills those runs so every resolution step gets a row; pass fill_gaps = false to keep only the literal points. For dense (A01) series the expansion is a no-op. Toggle the default globally with set_config(; fill_gaps = false).
Example
using ENTSOE, Dates
client = ENTSOEClient(ENV["ENTSOE_API_TOKEN"])
prices = day_ahead_prices(client, EIC.NL,
DateTime("2024-09-01T22:00"), DateTime("2024-09-02T22:00"))
prices[1] # → (time = DateTime("2024-09-01T22:00"), value = 91.24)
prices.value # Vector{Float64} of all 24 prices
mean(prices.value)
DataFrame(prices)ENTSOE.parse_timeseries_per_psr Function
parse_timeseries_per_psr(xml) -> StructVector{@NamedTuple{time::DateTime, psr_type::String, value::Float64}}Like parse_timeseries, but additionally extracts the <MktPSRType>/<psrType> from each <TimeSeries> and tags every point with it. Useful for documents that split data per production type, like 14.1.D (wind & solar forecast) and 16.1.B/C (actual generation per production type) — where one TimeSeries holds Solar, another Wind Onshore, etc.
Points without a <MktPSRType> get psr_type = "".
The return value is a Tables.jl-compatible StructVector — index rows (rows[1]), or pull a column (rows.value, rows.psr_type).
Example
rows = actual_generation_per_production_type(client, EIC.NL,
DateTime("2024-09-01T22:00"), DateTime("2024-09-02T22:00"))
# Pivot a column out:
solar_only = rows[rows.psr_type .== "B16"]
solar_only.valueENTSOE.parse_timeseries_quantity_price Function
parse_timeseries_quantity_price(xml) -> StructVector{@NamedTuple{
time::DateTime, quantity::Float64, price::Float64}}Like parse_timeseries, but keeps both value elements a <Point> may carry: <quantity> (MW) in the quantity column and the first *.amount child (e.g. <procurement_Price.amount>, EUR/MW) in the price column. Used by endpoints whose points are genuinely two-valued — 17.1.B&C "Volumes and Prices of Contracted Reserves" — where a single value column would silently drop one of the two.
A column's entry is NaN when the point does not carry that element. A03 forward-fill (see parse_timeseries) applies to both columns with shared run boundaries.
ENTSOE.parse_installed_capacity Function
parse_installed_capacity(xml) -> StructVector{@NamedTuple{psr_type::String, capacity_mw::Float64}}Parse a 14.1.A "Installed Capacity per Production Type" document. Returns one row per <TimeSeries> — each contains a single <MktPSRType>/<psrType> (e.g. "B16" for Solar) and a <Period> with one <Point> carrying the year-ahead declared capacity in MW.
Tables.jl-compatible StructVector. Pull a column directly with rows.capacity_mw (Vector{Float64}) or rows.psr_type (Vector{String}); convert with DataFrame(rows).
The psr_type codes are documented in PSR_LABELS; pass through describe(PSR_LABELS, code) for human-readable labels.
Example
rows = installed_capacity_per_production_type(client, EIC.NL,
DateTime("2024-12-31T23:00"), DateTime("2025-12-31T23:00"))
rows[1] # → (psr_type = "B01", capacity_mw = 580.0)
rows.capacity_mw # 14-element Vector{Float64}
sum(rows.capacity_mw)ENTSOE.parse_installed_capacity_per_unit Function
parse_installed_capacity_per_unit(xml) -> StructVector{@NamedTuple{
unit_mrid::String, unit_name::String, psr_type::String,
capacity_mw::Float64}}Parse a 14.1.B "Installed Capacity per Production Unit" document. One row per <TimeSeries> (one per unit), with fields:
unit_mrid—<registeredResource.mRID>, the unit's EICunit_name—<registeredResource.name>psr_type—<MktPSRType><psrType>(e.g.B19Wind Onshore)capacity_mw—<Period>/<Point>/<quantity>, year-ahead declared capacity in MW
Tables.jl-compatible StructVector; pull columns directly with rows.capacity_mw or DataFrame(rows).
ENTSOE.parse_timeseries_per_unit Function
parse_timeseries_per_unit(xml) -> StructVector{@NamedTuple{
time::DateTime, unit_mrid::String, unit_name::String,
psr_type::String, value::Float64}}Parse a per-generation-unit time-series document — used by 16.1.A "Actual Generation per Generation Unit". One row per <Point>, tagged with the parent generating unit's mRID and name (extracted from <MktPSRType>/<PowerSystemResources>) plus the PSR type.
ENTSOE.parse_unavailability Function
parse_unavailability(xml) -> StructVector{@NamedTuple{
start::DateTime, stop::DateTime,
business_type::String, resource_name::String,
resource_mrid::String, psr_type::String,
nominal_mw::Float64}}Parse an <Unavailability_MarketDocument> — the response shape used by every Outages endpoint (generation, production, transmission, consumption). One row per <TimeSeries>; fields:
start/stop— DateTime UTC bounds of the outage windowbusiness_type—A53(planned) orA54(unplanned); seeBUSINESS_LABELSresource_name—"production_RegisteredResource/name", or empty when the document is an aggregated noticeresource_mrid— mRID of the affected resource (or empty)psr_type—production_RegisteredResource/pSRType/psrType(e.g."B16"Solar,"B19"Wind Onshore)nominal_mw— rated capacity of the unit;NaNwhen absent
The per-15-minute Available_Period curve (i.e. the curtailed-to-MW trajectory during the outage) is intentionally not unpacked here — use Raw() if you need it. For most analyst use cases the one-row summary is what you want; Tables.jl row/column access works as usual.
ENTSOE.parse_unavailability_curve Function
parse_unavailability_curve(xml) -> StructVector{@NamedTuple{
time::DateTime, resource_mrid::String,
resource_name::String, available_mw::Float64}}Sister parser to parse_unavailability that walks each <TimeSeries>'s <Available_Period>/<Point> series and returns one row per timestamp — the per-15-minute (or per-resolution) MW curve the unit was curtailed to during the outage. Use this when the one-row-per-event summary parse_unavailability returns isn't enough — e.g. when you need to know "the unit ran at 50% from 14:00–16:00, full from 16:00–20:00."
Each row carries the parent resource's mRID and name so you can group multiple outages on the same unit. The Available_Period <Point>/<quantity> value is the rated MW available during that slice (not the rated capacity — for that pair this with the nominal_mwcolumn fromparse_unavailability).
For documents without <Available_Period> children (rare), the corresponding TimeSeries contributes no rows.
ENTSOE.parse_master_data Function
parse_master_data(xml) -> StructVector{@NamedTuple{
production_unit_mrid::String, production_unit_name::String,
generating_unit_mrid::String, generating_unit_name::String,
psr_type::String, nominal_mw::Float64,
location::String, bidding_zone::String,
implementation_date::String}}Parse a <Configuration_MarketDocument> from the master-data endpoint (master_data_production_and_generation_units). Returns one row per generating unit, flattened from the per-production-unit grouping in the document — fields:
production_unit_mrid/production_unit_name— the parent production unit (TimeSeries-level metadata).generating_unit_mrid/generating_unit_name— the leaf generating unit (<GeneratingUnit_PowerSystemResources>child). Empty when the production unit has no nested generating units.psr_type— the generating unit's PSR type (B04 Fossil Gas, B14 Nuclear, …); falls back to the production unit's<MktPSRType/psrType>when the generating-unit-level field is absent.nominal_mw— generating-unit rated MW (<nominalP>), or the production-unit nominal when missing.location—registeredResource.location.name.bidding_zone— EIC of the parent bidding zone.implementation_date— ISO date the resource entered the registry (string, not parsed — many entries use just a year).
Group-by-production-unit aggregations are one groupby(rows, :production_unit_mrid) away with DataFrames.
ENTSOE.parse_acknowledgement Function
parse_acknowledgement(xml) -> ENTSOEAcknowledgement | nothingIf the document root is <Acknowledgement_MarketDocument>, parse out the first <Reason> element's <code> and <text> and return them. Otherwise return nothing.
This is the low-level form. Most callers want check_acknowledgement instead, which throws — turning silent "no data" responses into typed errors.
ENTSOE.check_acknowledgement Function
check_acknowledgement(xml) -> xmlThrow an ENTSOEAcknowledgement if xml is an <Acknowledgement_MarketDocument>; otherwise return the input string unchanged. Designed to be chained inline:
xml = check_acknowledgement(xml)
rows = parse_timeseries(xml)Equivalent to:
ack = parse_acknowledgement(xml)
ack === nothing || throw(ack)ENTSOE.ENTSOEAcknowledgement Type
ENTSOEAcknowledgement(reason_code, text) <: APIErrorParsed <Acknowledgement_MarketDocument> payload — also a throwable APIError. ENTSO-E returns a 200 response containing this document when there is no data for the requested query (also when the query is ill-formed but well-typed). The official reason codes live in the IEC 62325 reason-code list — the most commonly seen ones are:
999— "No matching data found" (your query was valid; the Transparency Platform just has nothing for that period / area).113— "Not Authorized" (token rejected).400–499— assorted client-side issues (bad parameter, …).
Use parse_acknowledgement for the non-throwing variant and check_acknowledgement when you want it raised as an error.
ENTSOE.unzip_response Function
unzip_response(zip_bytes) -> Vector{Pair{String, Vector{UInt8}}}ENTSO-E sometimes returns very large queries (especially outage and master-data exports) as a application/zip body containing multiple XML files. Pass the raw response bytes (Vector{UInt8}) and get back a list of name => contents pairs.
String(contents) then yields the XML for each entry, ready to feed into parse_timeseries or any other parser.
using HTTP
resp = HTTP.get(url; query = q, status_exception = false)
if startswith(HTTP.header(resp, "Content-Type", ""), "application/zip")
members = unzip_response(resp.body)
for (name, bytes) in members
rows = parse_timeseries(String(bytes))
# …
end
endUses the stdlib ZipFile (via Pkg) — no extra deps. If the bytes aren't a valid ZIP, errors propagate from ZipFile.
Named-argument query wrappers
These are thin wrappers around the generated operation functions that pre-fill the standard documentType / processType codes, accept DateTime / Date / ZonedDateTime directly, and parse the XML response into a typed StructVector.
Parsed vs. raw — the ResponseFormat dispatch
Every wrapper accepts an optional trailing positional argument of type ResponseFormat that selects the return shape:
prices = day_ahead_prices(client, EIC.NL, t1, t2) # default
prices2 = day_ahead_prices(client, EIC.NL, t1, t2, Parsed()) # explicit
prices_xml = day_ahead_prices(client, EIC.NL, t1, t2, Raw()) # bypass parser| Trailing argument | Return type | When you'd use it |
|---|---|---|
| (none) | StructVector{<row>} | Default. Tables.jl-compatible, drop into DataFrame/plot directly. |
Parsed() | StructVector{<row>} | Same as the default — useful when you want to make the choice explicit at the call site. |
Raw() | String | Skip the parser. Hand the XML to EzXML/XML.jl yourself, archive the body, debug a parse mismatch, etc. |
The dispatch is on the singleton types Parsed/Raw (subtypes of ResponseFormat), so each variant has a concrete runtime return type:
julia> typeof(prices)
StructVector{@NamedTuple{time::DateTime, value::Float64}, …}
julia> typeof(prices_xml)
StringStatic inference is widened to StructArrays.StructArray for the parsed branch (the parser is plumbed through an F <: Function type parameter), but the runtime layout is concrete — DataFrame(prices) specializes correctly, and downstream column access (prices.value, prices.time) hits the typed backing vectors directly.
ENTSOE.ResponseFormat Type
ResponseFormatTag type that selects the return shape of every wrapper. Subtypes: Parsed (the default — a typed StructVector from the matching parser), Raw (the raw application/xml String), and LocalTime (like Parsed but with the time column converted to timezone-aware ZonedDateTime).
Pass an instance as the last positional argument to any wrapper:
prices_xml = day_ahead_prices(client, EIC.NL, t1, t2, Raw()) # ::String
prices = day_ahead_prices(client, EIC.NL, t1, t2) # ::StructVector
prices2 = day_ahead_prices(client, EIC.NL, t1, t2, Parsed()) # explicitENTSOE.Parsed Type
Parsed() <: ResponseFormatDefault response format — wrappers return a StructVector produced by the matching parser (parse_timeseries for time-series documents, parse_installed_capacity for capacity documents, …).
ENTSOE.Raw Type
Raw() <: ResponseFormatPass as the trailing positional argument to any wrapper to skip parsing and return the raw application/xml payload as a String. Useful for debugging or for endpoints whose XML shape isn't covered by our parsers.
ENTSOE.LocalTime Type
LocalTime(tz) <: ResponseFormat
LocalTime("Europe/Amsterdam")Like Parsed() but converts the time column from UTC DateTime to timezone-aware ZonedDateTime in tz. Useful when analyses expect local-time stamps.
prices_local = day_ahead_prices(client, EIC.NL, t1, t2,
LocalTime("Europe/Amsterdam"))
prices_local[1].time # ZonedDateTime in CET/CESTPass either a TimeZones.TimeZone instance or a string accepted by TimeZone(::String). For documents that don't carry a time column (e.g. installed-capacity snapshots), LocalTime is a no-op and returns the same shape as Parsed().
Wrappers — Market
ENTSOE.day_ahead_prices Function
day_ahead_prices(client, area, period_start, period_end[, format]) -> StructVector | StringDay-ahead clearing prices (Market 12.1.D, documentType=A44).
area is used as both in_Domain and out_Domain (they're always the same for an internal day-ahead price query). period_start / period_end accept DateTime, Date, ZonedDateTime, or a raw Int64 yyyymmddHHMM.
Returns a Tables.jl-compatible StructVector{(time, value)} in EUR/MWh by default; pass Raw() as the trailing argument to get the raw XML String instead.
Throws an ENTSOEAcknowledgement if ENTSO-E reports no matching data.
Example
using Dates
client = ENTSOEClient(ENV["ENTSOE_API_TOKEN"])
prices = day_ahead_prices(client, EIC.NL,
DateTime("2024-09-01T22:00"), DateTime("2024-09-02T22:00"))
prices.value # Vector{Float64} — column access
prices_xml = day_ahead_prices(client, EIC.NL,
DateTime("2024-09-01T22:00"), DateTime("2024-09-02T22:00"), Raw())ENTSOE.intraday_prices Function
intraday_prices(client, area, period_start, period_end[, format];
sequence=nothing) -> StructVector | StringIntraday clearing prices (Market 12.1.D, documentType=A44, contract_MarketAgreement.type=A07). Same wire endpoint as day_ahead_prices but flipped to the intraday contract type; ENTSO-E returns one TimeSeries per intraday auction sequence (SIDC IDA 1/2/3 etc.).
Pass sequence=1/2/3 to filter server-side to a single auction; omit it to receive every sequence the publication exposes. Returns a Tables.jl-compatible StructVector{(time, value)} in EUR/MWh.
ENTSOE.total_nominated_capacity Function
total_nominated_capacity(client, in_area, out_area, period_start[, period_end][, format])
-> StructVector | StringTotal nominated capacity per direction (Market 12.1.B, documentType=A26, businessType=B08). Quantities are the total capacity nominated by market participants for the day-ahead schedule. Returns StructVector{(time, value)} in MW.
period_end is optional — when omitted, ENTSO-E returns the single publication snapshot at period_start.
ENTSOE.congestion_income Function
congestion_income(client, in_area, out_area, period_start, period_end[, format];
contract_market_agreement_type=ContractType.DAILY)
-> StructVector | StringCongestion income from implicit + flow-based allocations (Market 12.1.E, documentType=A25, businessType=B10). Returns StructVector{(time, value)} in the local currency. The wrapper's parse_timeseries follows the <*.amount> convention so the value is picked up regardless of whether the field is named <settlement_Price.amount>, <congestionIncome_Price.amount>, etc.
contract_market_agreement_type defaults to "A01" (daily).
ENTSOE.implicit_auction_net_positions Function
implicit_auction_net_positions(client, area, period_start, period_end[, format];
contract_market_agreement_type=ContractType.INTRADAY)
-> StructVector | StringNet positions from implicit auctions (Market 12.1.E variant, documentType=A25, businessType=B09 — Net position). Single-zone — in_Domain and out_Domain are both set to area, matching how ENTSO-E publishes the self-loop net position. Returns StructVector{(time, value)} in MW (positive = net export).
contract_market_agreement_type defaults to "A07" (intraday — the typical use case for implicit auctions); pass "A01" for daily.
ENTSOE.intraday_offered_capacity Function
intraday_offered_capacity(client, in_area, out_area, period_start, period_end[, format];
implicit=true, id_type="IDCT") -> StructVector | StringIntraday cross-border offered transfer capacity. Thin router over the three underlying allocation endpoints:
implicit=false→explicit_allocations_offered_transfer_capacitywithauction_type=AuctionType.EXPLICIT(used on the few explicit-ID borders like BE↔GB).implicit=true, id_type="IDCT"→continuous_allocations_offered_transfer_capacity(SIDC continuous trading,auction_type=AuctionType.CONTINUOUS).implicit=true, id_type="IDA1"/"IDA2"/"IDA3"→implicit_allocations_offered_transfer_capacitywithcontract_market_agreement_type=ContractType.INTRADAYandsequence=1/2/3(SIDC pan-European IDA auctions).
ENTSOE.explicit_allocations_offered_transfer_capacity Function
explicit_allocations_offered_transfer_capacity(client, in_area, out_area, period_start, period_end[, format];
auction_type=AuctionType.EXPLICIT,
contract_market_agreement_type=ContractType.DAILY,
auction_category=nothing,
sequence=nothing)
-> StructVector | StringExplicit allocations offered transfer capacity (Market 11.1.A, documentType=A31). Returns the capacity offered to explicit-auction participants per direction/timeframe.
Defaults match the Postman canonical example (auction_type=AuctionType.EXPLICIT monthly, contract_market_agreement_type=ContractType.DAILY daily).
ENTSOE.flow_based_allocations Function
flow_based_allocations(client, in_area, out_area, period_start, period_end[, format];
process_type=ProcessType.INTRADAY_FLOW_BASED) -> StructVector | StringFlow-based allocation results (Market 11.1.B, documentType=B09). process_type default "A44" (Intraday); pass "A01" for day-ahead. For historical periods use flow_based_allocations_archives.
ENTSOE.flow_based_allocations_archives Function
flow_based_allocations_archives(client, in_area, out_area, period_start, period_end[, format];
process_type=ProcessType.MONTH_AHEAD,
storage_type="archive") -> StructVector | StringArchived flow-based allocations (Market 11.1.B archive variant). process_type default "A32" (Monthly); storage_type default "archive" matches the published archive bucket.
ENTSOE.continuous_allocations_offered_transfer_capacity Function
continuous_allocations_offered_transfer_capacity(client, in_area, out_area, period_start, period_end[, format];
auction_type=AuctionType.CONTINUOUS,
contract_market_agreement_type=ContractType.INTRADAY)
-> StructVector | StringContinuous-intraday offered transfer capacity (Market 11.1, SIDC IDCT), documentType=A31. auction_type=AuctionType.CONTINUOUS is the continuous-intraday auction; contract_market_agreement_type=ContractType.INTRADAY is intraday.
ENTSOE.implicit_allocations_offered_transfer_capacity Function
implicit_allocations_offered_transfer_capacity(client, in_area, out_area, period_start, period_end[, format];
auction_type=AuctionType.IMPLICIT,
contract_market_agreement_type=ContractType.DAILY,
sequence=nothing)
-> StructVector | StringImplicit-auction offered transfer capacity (Market 11.1, implicit day-ahead), documentType=A31. Defaults to day-ahead implicit auction (auction_type=AuctionType.IMPLICIT, contract_market_agreement_type=ContractType.DAILY). Pass sequence to filter SIDC IDA1/2/3 results.
ENTSOE.explicit_allocations_auction_revenue Function
explicit_allocations_auction_revenue(client, in_area, out_area, period_start, period_end[, format];
business_type=BusinessType.VOLUME_CONTRACTED,
contract_market_agreement_type=ContractType.DAILY)
-> StructVector | StringExplicit-allocation auction revenue (Market 12.1.A, documentType=A25, default businessType=B07 — which this endpoint defines as "Auction Revenue"; keep the default. BusinessType.AUCTION_REVENUE (B03) is a different endpoint family's code and returns no data here).
ENTSOE.explicit_allocations_use_of_transfer_capacity Function
explicit_allocations_use_of_transfer_capacity(client, in_area, out_area, period_start, period_end[, format];
business_type=BusinessType.COUNTER_TRADE,
contract_market_agreement_type=ContractType.INTRADAY,
auction_category=nothing,
sequence=nothing)
-> StructVector | StringUse of transfer capacity from explicit allocations (Market 12.1.A, documentType=A25, default businessType=B05 — already allocated).
ENTSOE.total_capacity_already_allocated Function
total_capacity_already_allocated(client, in_area, out_area, period_start, period_end[, format];
business_type=BusinessType.ALREADY_ALLOCATED_CAPACITY,
contract_market_agreement_type=ContractType.DAILY,
auction_category=nothing)
-> StructVector | StringTotal capacity already allocated (Market 12.1.C, documentType=A26, default businessType=A29 — already allocated capacity).
ENTSOE.transfer_capacities_with_third_countries Function
transfer_capacities_with_third_countries(client, in_area, out_area, period_start, period_end[, format];
auction_type=AuctionType.EXPLICIT,
contract_market_agreement_type=ContractType.INTRADAY,
auction_category=nothing,
sequence=nothing)
-> StructVector | StringTransfer capacities allocated with third countries (Market 12.1.H, documentType=A94).
Wrappers — Load (Load 6.1.A–E, 8.1)
ENTSOE.actual_total_load Function
actual_total_load(client, area, start, stop[, format]) -> StructVector | StringRealised total system load (Load 6.1.A, documentType=A65, processType=A16). Quarter-hour resolution. Returns StructVector{(time, value)} with value in MW; pass Raw() for the XML body.
ENTSOE.day_ahead_load_forecast Function
day_ahead_load_forecast(client, area, start, stop[, format]) -> StructVector | StringDay-ahead total load forecast (Load 6.1.B, processType=A01).
ENTSOE.week_ahead_load_forecast Function
week_ahead_load_forecast(client, area, start, stop[, format]) -> StructVector | StringWeek-ahead total load forecast (Load 6.1.C, processType=A31).
ENTSOE.month_ahead_load_forecast Function
month_ahead_load_forecast(client, area, start, stop[, format]) -> StructVector | StringMonth-ahead total load forecast (Load 6.1.D, processType=A32).
ENTSOE.year_ahead_load_forecast Function
year_ahead_load_forecast(client, area, start, stop[, format]) -> StructVector | StringYear-ahead total load forecast (Load 6.1.E, processType=A33).
ENTSOE.year_ahead_forecast_margin Function
year_ahead_forecast_margin(client, area, start, stop[, format]) -> StructVector | StringYear-ahead generation-adequacy forecast margin (Load 8.1, documentType=A70, processType=A33). The surplus of forecasted available capacity over forecasted peak load for the year ahead; one row per published period (StructVector{(time, value)} in MW).
Distinct from year_ahead_load_forecast: that's the demand forecast (documentType A65), whereas this is the margin — margin = available capacity − peak load.
Wrappers — Generation (14.1.x, 16.1.x)
ENTSOE.installed_capacity_per_production_type Function
installed_capacity_per_production_type(client, area, start, stop[, format]) -> StructVector | StringYear-ahead installed capacity per production type (Generation 14.1.A, documentType=A68, processType=A33). For a calendar-year window spanning Dec 31 23:00 → Dec 31 23:00. Returns StructVector{(psr_type::String, capacity_mw::Float64)}.
Map psr_type codes to labels via PSR_LABELS / describe: describe(PSR_LABELS, "B16") == "Solar".
ENTSOE.installed_capacity_per_production_unit Function
installed_capacity_per_production_unit(client, area, period_start, period_end[, format];
psr_type=nothing) -> StructVector | StringYear-ahead installed capacity broken out per generating unit (rather than aggregated per production type) — Generation 14.1.B, documentType=A71, processType=A33. Returns StructVector{(unit_mrid, unit_name, psr_type, capacity_mw)}.
Pass psr_type=PsrType.WIND_ONSHORE (Wind Onshore) etc. to filter to a single technology.
ENTSOE.generation_forecast_day_ahead Function
generation_forecast_day_ahead(client, area, start, stop[, format]) -> StructVector | StringDay-ahead total generation forecast (Generation 14.1.C, documentType=A71, processType=A01). Returns StructVector{(time, value)} in MW.
ENTSOE.wind_solar_forecast Function
wind_solar_forecast(client, area, start, stop[, format]; psr_type=nothing)
-> StructVector | StringWind & solar forecast, day-ahead (Generation 14.1.D, documentType=A69, processType=A01). The returned document carries one TimeSeries per technology — we parse with parse_timeseries_per_psr, so each row is tagged with its psr_type (B16 Solar, B18 Wind Offshore, B19 Wind Onshore).
Pass psr_type=PsrType.WIND_ONSHORE to filter at the API level (returns just that technology).
ENTSOE.intraday_wind_solar_forecast Function
intraday_wind_solar_forecast(client, area, period_start, period_end[, format];
psr_type=nothing) -> StructVector | StringIntraday wind & solar generation forecast (Generation 14.1.D, documentType=A69, processType=A40). Same endpoint as wind_solar_forecast but with the intraday process type — gives the latest published forecast as auctions clear through the day, rather than the day-ahead snapshot.
Returns a StructVector{(time, psr_type, value)} in MW. Pass psr_type=PsrType.SOLAR (Solar), "B18" (Wind Offshore), or "B19" (Wind Onshore) to filter server-side.
ENTSOE.actual_generation_per_production_type Function
actual_generation_per_production_type(client, area, start, stop[, format];
psr_type=nothing) -> StructVector | StringRealised generation broken down by production type (Generation 16.1.B/C, documentType=A75, processType=A16). One TimeSeries per technology — parse rows are (time, psr_type, value) with value in MW.
Pass psr_type=PsrType.SOLAR to fetch a single technology server-side.
ENTSOE.actual_generation_per_generation_unit Function
actual_generation_per_generation_unit(client, area, period_start, period_end[, format];
psr_type=nothing, registered_resource=nothing)
-> StructVector | StringRealised generation broken down per generating unit (Generation 16.1.A, documentType=A73, processType=A16). One row per <Point> per unit; fields are (time, unit_mrid, unit_name, psr_type, value) with value in MW.
Pass psr_type=PsrType.SOLAR to filter to one technology; pass registered_resource to filter to a single generating unit by mRID.
ENTSOE.water_reservoirs_and_hydro_storage_plants Function
water_reservoirs_and_hydro_storage_plants(client, area, start, stop[, format])
-> StructVector | StringFilling rate of hydro reservoirs and pumped-storage plants (Generation 16.1.D, documentType=A72, processType=A16 — Realised). Quantities in MWh of stored energy. Returns StructVector{(time, value)}.
Wrappers — Transmission (11.1.A, 12.1.F/G, 13.1.A–C)
ENTSOE.cross_border_physical_flows Function
cross_border_physical_flows(client, in_area, out_area, start, stop[, format])
-> StructVector | StringCross-border physical flows between two bidding zones (Transmission 12.1.G, documentType=A11). Returns hourly StructVector{(time, value)} in MW.
Note ENTSO-E's ordering: in_area is the receiving zone, out_area is the sending zone — flows are positive when they go from out_area into in_area.
ENTSOE.cross_border_physical_flows_all Function
cross_border_physical_flows_all(client, area, period_start, period_end[, format];
export_=true,
neighbours=NEIGHBOURS[area])
-> StructVector | StringAggregate cross-border physical flows for a zone across every configured border. Calls cross_border_physical_flows once per neighbour and concatenates the results, tagging each row with a border column (the neighbouring EIC).
export_=true (default) sums flows leaving area; export_=false sums flows arriving in area. Pass neighbours explicitly to restrict / extend the default list from NEIGHBOURS.
No-data ENTSOEAcknowledgements on individual borders are caught and skipped — partial coverage is normal when ENTSO-E hasn't published flows on every link. If every border acknowledges, the last acknowledgement is rethrown (matching the windowed-splitting contract), and a border acknowledging with anything other than plain no-data emits a warning.
ENTSOE.commercial_schedules Function
commercial_schedules(client, in_area, out_area, start, stop[, format];
contract_market_agreement_type=ContractType.DAILY) -> StructVector | StringTotal scheduled commercial exchanges between two bidding zones (Transmission 12.1.F, documentType=A09). Returns StructVector{(time, value)} in MW — quantities are scheduled flows from out_area into in_area*, mirroring the same convention as [cross_border_physical_flows`](@ref).
contract_market_agreement_type defaults to "A01" (daily) — set to "A05" for total, "A07" for intraday, etc.
ENTSOE.scheduled_exchanges Function
scheduled_exchanges(client, in_area, out_area, period_start, period_end[, format];
dayahead=false) -> StructVector | StringScheduled cross-border exchanges (Transmission 12.1.F, documentType=A09). Same endpoint as commercial_schedules; this alias exposes a dayahead boolean — dayahead=true selects A01 (day-ahead), dayahead=false (default) selects A05 (total).
Use commercial_schedules(...; contract_market_agreement_type=...) directly for finer control (e.g. A07 intraday).
ENTSOE.commercial_schedules_net_positions Function
commercial_schedules_net_positions(client, area, start, stop[, format];
contract_market_agreement_type=ContractType.DAILY)
-> StructVector | StringNet position from total scheduled commercial exchanges (Transmission 12.1.F, documentType=A09). Same endpoint as commercial_schedules but exposed via the *_net_positions codegen variant that ENTSO-E publishes for the self-loop case (where in_area == out_area).
Pass a single area — it's used for both in_Domain and out_Domain, matching the platform's own net-position calculation.
ENTSOE.forecasted_transfer_capacities Function
forecasted_transfer_capacities(client, in_area, out_area, start, stop[, format];
contract_market_agreement_type=ContractType.DAILY)
-> StructVector | StringForecasted transfer capacities between two bidding zones (Transmission 11.1.A, documentType=A61 — Estimated Net Transfer Capacity). contract_market_agreement_type defaults to "A01" (daily); pass "A02" for weekly, "A03" monthly, "A04" yearly, "A07" intraday.
Returns StructVector{(time, value)} in MW, representing forecasted capacity from out_area into in_area.
ENTSOE.net_transfer_capacity_day_ahead Function
net_transfer_capacity_day_ahead(client, in_area, out_area, period_start, period_end[, format])
-> StructVector | StringDay-ahead forecasted net transfer capacity (contract_marketagreement_type=A01). Thin wrapper over forecasted_transfer_capacities.
ENTSOE.net_transfer_capacity_week_ahead Function
net_transfer_capacity_week_ahead(client, in_area, out_area, period_start, period_end[, format])
-> StructVector | StringWeek-ahead forecasted net transfer capacity (contract_marketagreement_type=A02).
ENTSOE.net_transfer_capacity_month_ahead Function
net_transfer_capacity_month_ahead(client, in_area, out_area, period_start, period_end[, format])
-> StructVector | StringMonth-ahead forecasted net transfer capacity (contract_marketagreement_type=A03).
ENTSOE.net_transfer_capacity_year_ahead Function
net_transfer_capacity_year_ahead(client, in_area, out_area, period_start, period_end[, format])
-> StructVector | StringYear-ahead forecasted net transfer capacity (contract_marketagreement_type=A04).
ENTSOE.redispatching_internal Function
redispatching_internal(client, area, start, stop[, format]) -> StructVector | StringInternal redispatching activations (Transmission 13.1.A, documentType=A63, businessType=A85 — Internal redispatch). Single-zone query — in_Domain and out_Domain are both set to area. Returns StructVector{(time, value)} in MW.
ENTSOE.redispatching_cross_border Function
redispatching_cross_border(client, in_area, out_area, start, stop[, format])
-> StructVector | StringCross-border redispatching activations (Transmission 13.1.A, documentType=A63, businessType=A46 — Cross-border redispatch). Returns StructVector{(time, value)} in MW representing energy redispatched between the two zones.
ENTSOE.countertrading Function
countertrading(client, in_area, out_area, start, stop[, format])
-> StructVector | StringCross-border countertrading activations (Transmission 13.1.B, documentType=A91). Returns StructVector{(time, value)} in MW — volumes traded between the two zones to relieve congestion.
ENTSOE.costs_of_congestion_management Function
costs_of_congestion_management(client, area, start, stop[, format])
-> StructVector | StringCosts paid by the TSO for congestion-management actions (Transmission 13.1.C, documentType=A92). Single-zone query — both in_Domain and out_Domain are set to area. Returns StructVector{(time, value)}; values are the cost amount per period (units depend on the TSO's reporting — typically EUR, sometimes the local currency).
parse_timeseries picks the cost amount out of <congestionCost_Price.amount> automatically (any element ending in .amount is recognised).
ENTSOE.expansion_and_dismantling_project Function
expansion_and_dismantling_project(client, in_area, out_area, period_start, period_end[, format];
business_type=nothing, doc_status=nothing)
-> StructVector | StringInterconnector network expansion and dismantling projects (Transmission 9.1, documentType=A90). TYNDP-related project announcements. StructVector{(time, value)} per project — passing Raw() exposes the full project metadata for richer consumers.
Wrappers — Balancing (1.2.3.A/E, 17.1.B/C/F/G/H)
Most balancing endpoints return application/zip; the wrappers unzip transparently and route each member through parse_timeseries.
ENTSOE.current_balancing_state Function
current_balancing_state(client, area, start, stop[, format];
business_type=BusinessType.AREA_CONTROL_ERROR) -> StructVector | StringReal-time area-control-error / imbalance state (Balancing 1.2.3.A, documentType=A86). business_type defaults to "B33" (Area control error). Returns StructVector{(time, value)} in MW — the cleared imbalance for the area.
ENTSOE.aggregated_balancing_energy_bids Function
aggregated_balancing_energy_bids(client, area, start, stop[, format];
process_type=ProcessType.AFRR) -> StructVector | StringAggregated balancing-energy bid volumes (Balancing 1.2.3.E, documentType=A24). process_type defaults to "A51" (Automatic frequency restoration reserve — aFRR); pass "A47" for mFRR or "A46" for RR. Returns StructVector{(time, value)} of bid volumes in MW.
ENTSOE.balancing_energy_bids Function
balancing_energy_bids(client, connecting_domain, period_start, period_end[, format];
process_type=ProcessType.MFRR,
direction=nothing,
standard_market_product=nothing,
original_market_product=nothing)
-> StructVector | StringRaw balancing-energy bid stream (Balancing 1.2.3.B/C, documentType=A37, businessType=B74). process_type default "A47" (mFRR); pass "A46" (RR), "A51" (aFRR), etc. direction filters by A01 (Up) / A02 (Down). Response is application/zip; _query unzips and parses transparently.
For historical periods use balancing_energy_bids_archives.
ENTSOE.balancing_energy_bids_archives Function
balancing_energy_bids_archives(client, connecting_domain, period_start, period_end[, format];
process_type=ProcessType.MFRR,
storage_type="archive",
offset=nothing)
-> StructVector | StringArchived balancing-energy bids (Balancing 1.2.3.B/C archive variant). Same shape as balancing_energy_bids; use for historical periods. storage_type default "archive".
ENTSOE.allocation_and_use_of_cross_zonal_balancing_capacity Function
allocation_and_use_of_cross_zonal_balancing_capacity(client, acquiring_domain, connecting_domain, period_start, period_end[, format];
process_type=ProcessType.RR,
type_market_agreement_type=nothing)
-> StructVector | StringAllocation and use of cross-zonal balancing capacity (Balancing 1.2.3.H/I, documentType=A38). process_type default "A46" (RR); pass "A47" (mFRR), "A51" (aFRR), etc.
ENTSOE.cross_border_marginal_prices_for_afrr Function
cross_border_marginal_prices_for_afrr(client, control_area, period_start, period_end[, format];
standard_market_product=StandardProduct.STANDARD)
-> StructVector | StringCross-border marginal prices (CBMPs) for aFRR central selection (Balancing IF aFRR 3.1.6, documentType=A84, processType=A67, businessType=A96). Returns the PICASSO clearing prices per control area.
ENTSOE.netted_and_exchanged_volumes Function
netted_and_exchanged_volumes(client, acquiring_domain, connecting_domain, period_start, period_end[, format];
process_type=ProcessType.IMBALANCE_NETTING)
-> StructVector | StringNetted and exchanged volumes between platforms (Balancing IF 3.10/3.16/3.17, documentType=B17). process_type default "A63" (Imbalance Netting); pass "A60" (mFRR scheduled), "A61" (mFRR direct), "A67" (aFRR central selection), etc.
ENTSOE.netted_and_exchanged_volumes_per_border Function
netted_and_exchanged_volumes_per_border(client, acquiring_domain, connecting_domain, period_start, period_end[, format];
process_type=ProcessType.SCHEDULED_ACTIVATION_MFRR)
-> StructVector | StringSame data as netted_and_exchanged_volumes but published per border (Balancing IF 3.10/3.16/3.17, documentType=A30). process_type default "A60" (mFRR scheduled).
ENTSOE.balancing_border_capacity_limitations Function
balancing_border_capacity_limitations(client, in_area, out_area, period_start, period_end[, format];
business_type=BusinessType.AVAILABLE_TRANSFER_CAPACITY, process_type=ProcessType.MFRR,
registered_resource=nothing)
-> StructVector | StringBalancing border capacity limitations (Balancing IF 4.3/4.4, documentType=A31). business_type default "A26"; process_type default "A47" (mFRR); pass "A51" (aFRR) or "A63" (Imbalance Netting).
ENTSOE.permanent_allocation_limitations_to_HVDC Function
permanent_allocation_limitations_to_HVDC(client, in_area, out_area, period_start, period_end[, format];
process_type=ProcessType.IMBALANCE_NETTING, business_type=BusinessType.DC_LINK_CONSTRAINT,
registered_resource=nothing)
-> StructVector | StringPermanent allocation limitations on HVDC cross-border capacity (Balancing IF 4.5, documentType=A99). process_type default "A63" (Imbalance Netting); business_type default "B06".
ENTSOE.elastic_demands Function
elastic_demands(client, acquiring_domain, period_start, period_end[, format];
process_type=ProcessType.MFRR) -> StructVector | StringElastic-demand curves from IF platforms (Balancing IF aFRR 3.4 / mFRR 3.4, documentType=A37, businessType=B75). process_type default "A47" (mFRR); pass "A51" (aFRR).
ENTSOE.changes_to_bid_availability Function
changes_to_bid_availability(client, domain, period_start, period_end[, format];
process_type=ProcessType.MFRR, business_type=nothing,
offset=nothing) -> StructVector | StringChanges to bid availability published by IF platforms (Balancing IF mFRR 9.9 / aFRR 9.6/9.8, documentType=B45). process_type default "A47" (mFRR). Pass business_type like "C46" (Conditional bid), "C40" (Thermal limit), etc.
For historical periods use changes_to_bid_availability_archives.
ENTSOE.changes_to_bid_availability_archives Function
changes_to_bid_availability_archives(client, domain, period_start, period_end[, format];
process_type=ProcessType.MFRR,
storage_type="archive",
business_type=nothing,
offset=nothing) -> StructVector | StringArchived bid-availability changes (Balancing IF mFRR 9.9 / aFRR 9.6/9.8 archive variant).
sourceENTSOE.results_of_criteria_application_process Function
results_of_criteria_application_process(client, area, period_start, period_end[, format];
process_type=ProcessType.MFRR) -> StructVector | StringResults of the criteria-application process (Balancing 18.5.4 SO GL, documentType=A45). StructVector{(time, value)} of TSO-quality measurements. process_type default "A47" (mFRR).
ENTSOE.fcr_total_capacity Function
fcr_total_capacity(client, area, period_start, period_end[, format])
-> StructVector | StringFCR total capacity (Balancing 18.7.2 SO GL, documentType=A26, businessType=A25). Per area, in MW.
ENTSOE.shares_of_fcr_capacity Function
shares_of_fcr_capacity(client, area, period_start, period_end[, format])
-> StructVector | StringShares of FCR capacity (Balancing 18.7.2 SO GL, documentType=A26, businessType=C23). Per area, in MW.
ENTSOE.frr_rr_capacity_outlook Function
frr_rr_capacity_outlook(client, area, period_start, period_end[, format];
process_type=ProcessType.FRR) -> StructVector | StringFRR/RR capacity outlook (Balancing 18.8.3/18.9.2 SO GL, documentType=A26, businessType=C76). process_type default "A56" (FRR); pass "A46" for RR.
ENTSOE.frr_and_rr_actual_capacity Function
frr_and_rr_actual_capacity(client, area, period_start, period_end[, format];
process_type=ProcessType.FRR, business_type=BusinessType.MIN)
-> StructVector | StringFRR & RR actual capacity (Balancing 18.8.4/18.9.3 SO GL, documentType=A26). process_type default "A56" (FRR); business_type default "C77" (Min).
ENTSOE.outlook_of_reserve_capacities_on_rr Function
outlook_of_reserve_capacities_on_rr(client, area, period_start, period_end[, format])
-> StructVector | StringOutlook of reserve capacities on RR (Balancing 18.9.2 SO GL, documentType=A26, processType=A46, businessType=C76).
ENTSOE.rr_actual_capacity Function
rr_actual_capacity(client, area, period_start, period_end[, format])
-> StructVector | StringRR actual capacity (Balancing 18.9.3 SO GL, documentType=A26, processType=A46, businessType=C77).
ENTSOE.sharing_of_rr_and_frr Function
sharing_of_rr_and_frr(client, acquiring_domain, connecting_domain, period_start, period_end[, format];
process_type=ProcessType.FRR) -> StructVector | StringSharing of RR and FRR between connected areas (Balancing 19.0.1 SO GL, documentType=A26, businessType=C22). process_type default "A56" (FRR); pass "A46" for RR.
ENTSOE.sharing_of_fcr_between_sas Function
sharing_of_fcr_between_sas(client, area, period_start, period_end[, format])
-> StructVector | StringSharing of FCR between scheduling areas (Balancing 19.0.2 SO GL, documentType=A26, processType=A52, businessType=C22).
ENTSOE.exchanged_reserve_capacity Function
exchanged_reserve_capacity(client, acquiring_domain, connecting_domain, period_start, period_end[, format];
process_type=ProcessType.RR) -> StructVector | StringExchanged balancing-reserve capacity between control areas (Balancing 19.0.3 SO GL, documentType=A26, businessType=C21). process_type default "A46" (Replacement reserve); pass "A51" (aFRR), "A47" (mFRR), or "A52" (FCR) for other reserve products.
StructVector{(time, value)} in MW.
ENTSOE.financial_expenses_and_income_for_balancing Function
financial_expenses_and_income_for_balancing(client, control_area, period_start, period_end[, format])
-> StructVector | StringFinancial expenses and income for balancing (Balancing 17.1.I, documentType=A87). Monetary flows aggregated per control area; StructVector{(time, value)} in EUR.
ENTSOE.volumes_and_prices_of_contracted_reserves Function
volumes_and_prices_of_contracted_reserves(client, control_area, period_start, period_end[, format];
type_market_agreement_type=ContractType.DAILY,
process_type=nothing,
psr_type=nothing,
offset=nothing)
-> StructVector | StringVolumes and prices of contracted balancing reserves (Balancing 17.1.B/C, documentType=A81, businessType=B95). type_market_agreement_type default "A01" (Daily); pass "A02" (Weekly), "A03" (Monthly), "A04" (Yearly), "A13" (Hourly).
Points on this endpoint are two-valued, so Parsed() returns three columns — (time, quantity, price) via parse_timeseries_quantity_price: quantity is the contracted MW, price the procurement price (NaN when a point omits one).
Optional kwargs:
process_type—"A51"(aFRR),"A52"(FCR),"A47"(mFRR),"A46"(RR)psr_type—"A03"(Mixed),"A04"(Generation),"A05"(Load)
ENTSOE.prices_of_activated_balancing_energy Function
prices_of_activated_balancing_energy(client, control_area, period_start, period_end[, format];
process_type=ProcessType.REALISED,
business_type=nothing,
psr_type=nothing,
standard_market_product=nothing,
original_market_product=nothing)
-> StructVector | StringPrices of activated balancing energy (Balancing 17.1.F, documentType=A84). One row per published settlement period — StructVector{(time, value)} in EUR/MWh. Response is application/zip; the wrapper unzips and parses transparently.
process_type defaults to "A16" (Realised). Pass business_type / psr_type / market-product strings to filter server-side.
ENTSOE.imbalance_prices Function
imbalance_prices(client, area, start, stop[, format]; psr_type=nothing)
-> StructVector | StringImbalance prices per imbalance settlement period (Balancing 17.1.G, documentType=A85). The endpoint returns application/zip; the wrapper unzips transparently and concatenates the XML members through parse_timeseries. Returns StructVector{(time, value)} in EUR/MWh.
psr_type defaults to nothing (no filter); pass "A04" for generation only.
ENTSOE.total_imbalance_volumes Function
total_imbalance_volumes(client, area, start, stop[, format]; business_type=BusinessType.BALANCE_ENERGY_DEVIATION)
-> StructVector | StringTotal imbalance volumes per settlement period (Balancing 17.1.H, documentType=A86). Like imbalance_prices, the response is application/zip — unzipped and parsed transparently. Returns StructVector{(time, value)} in MW.
business_type defaults to "A19" (Balance energy deviation).
ENTSOE.procured_balancing_capacity Function
procured_balancing_capacity(client, area, period_start[, period_end, format];
process_type=ProcessType.AFRR,
type_market_agreement_type=ContractType.DAILY,
offset=nothing) -> StructVector | StringProcured balancing capacity volumes (Balancing 1.2.3.F, documentType=A15). The underlying endpoint takes a single period_start and an optional period_end; both are accepted here. Response is application/zip and is unzipped transparently.
process_type defaults to "A51" (aFRR); pass "A47" for mFRR. type_market_agreement_type defaults to "A01" (daily).
Wrappers — Outages (7.1.A/B, 10.1.A/B/C, 15.1.A–D)
All return Unavailability_MarketDocument, parsed into one row per outage event.
ENTSOE.unavailability_of_generation_units Function
unavailability_of_generation_units(client, area, start, stop[, format];
business_type=nothing,
registered_resource=nothing,
m_r_i_d=nothing, offset=nothing)
-> StructVector | StringOutage notices for individual generation units in area (Outages 15.1.A/B, documentType=A80). Pass business_type=BusinessType.PLANNED_OUTAGE for planned outages only, "A54" for unplanned. Filter to one unit with registered_resource = "22WCOOX6X000064W".
Returns the parse_unavailability shape — one row per outage notice, with resource_name, psr_type, nominal_mw, and the time bounds.
ENTSOE.unavailability_of_production_units Function
unavailability_of_production_units(client, area, start, stop[, format];
business_type=nothing,
registered_resource=nothing,
m_r_i_d=nothing, offset=nothing)
-> StructVector | StringOutage notices for whole production units (Outages 15.1.C/D, documentType=A77). Same shape as unavailability_of_generation_units — production units aggregate one or more generation units under a single mRID.
ENTSOE.unavailability_of_transmission_infrastructure Function
unavailability_of_transmission_infrastructure(client, in_area, out_area,
start, stop[, format];
business_type=nothing,
m_r_i_d=nothing,
offset=nothing)
-> StructVector | StringOutage notices for cross-border transmission infrastructure (Outages 10.1.A/B, documentType=A78). Pass business_type=BusinessType.PLANNED_OUTAGE for planned outages only. Returns parse_unavailability rows.
ENTSOE.unavailability_of_transmission_infrastructure_available_capacity Function
unavailability_of_transmission_infrastructure_available_capacity(
client, control_area, period_start, period_end[, format];
business_type=nothing, asset_registered_resource_m_r_i_d=nothing,
doc_status=nothing, period_start_update=nothing,
period_end_update=nothing, m_r_i_d=nothing,
offset=nothing) -> StructVector | StringAvailable-capacity sub-view of transmission-infrastructure outage notices (Outages 10.1.A/B variant, documentType=A78). Single control_area query (no in/out split). Returns parse_unavailability rows.
ENTSOE.unavailability_of_transmission_infrastructure_net_position_impact Function
unavailability_of_transmission_infrastructure_net_position_impact(
client, ptdf_domain, period_start, period_end[, format];
business_type=nothing, asset_registered_resource_m_r_i_d=nothing,
doc_status=nothing, period_start_update=nothing,
period_end_update=nothing, m_r_i_d=nothing,
offset=nothing) -> StructVector | StringNet-position-impact sub-view of transmission-infrastructure outage notices (Outages 10.1.A/B variant, documentType=A78). Takes a single PTDF domain mRID (ptdf_domain); returns parse_unavailability rows describing how each outage shifts NTC at that node.
ENTSOE.unavailability_of_offshore_grid Function
unavailability_of_offshore_grid(client, bidding_zone, period_start, period_end[, format];
doc_status=nothing, m_r_i_d=nothing,
period_start_update=nothing,
period_end_update=nothing,
offset=nothing) -> StructVector | StringOutage notices for offshore-grid infrastructure (Outages 10.1.C, documentType=A79). Unlike the 10.1.A/B variant for onshore transmission, this one takes a single bidding_zone (no in_Domain / out_Domain split) and has no businessType parameter — ENTSO-E treats offshore-grid outages as a single document family.
Returns parse_unavailability rows (one row per outage event). Pass doc_status=DocStatus.CANCELLED for withdrawn notices, or the *_update pair to slice by publication-update window.
ENTSOE.outages_fall_backs Function
outages_fall_backs(client, bidding_zone, period_start, period_end[, format];
process_type=ProcessType.MFRR, business_type=BusinessType.PLANNED_OUTAGE,
doc_status=nothing, m_r_i_d=nothing,
offset=nothing) -> StructVector | StringFall-back outage notices on the IF platforms (Outages IFs IN 7.2 / mFRR 3.11 / aFRR 3.10, documentType=A53). process_type default "A47" (mFRR); pass "A51" (aFRR) or "A63" (Imbalance Netting). business_type default "A53" (Planned maintenance); pass "A54" (Unplanned) etc.
Returns parse_unavailability rows.
ENTSOE.aggregated_unavailability_of_consumption_units Function
aggregated_unavailability_of_consumption_units(client, area, start, stop[, format];
business_type=nothing)
-> StructVector | StringAggregated consumption-side unavailability (Outages 7.1.A/B, documentType=A76). Returns parse_unavailability rows — the resource_* fields are usually empty (the notice is aggregated for the bidding zone, not tied to a single facility).
Wrappers — Master data
ENTSOE.production_and_generation_units Function
production_and_generation_units(client, area[, format];
implementation_date::Union{Date,AbstractString} = Date(2017, 1, 1),
business_type = BusinessType.PRODUCTION_UNIT,
psr_type = nothing) -> StructVector | StringRegistry snapshot of production + generation units (Master Data master_data_production_and_generation_units, documentType=A95). Unlike every other endpoint this one takes a single date, not a period window — pass Date(2024, 1, 1) to get the registry as it was on that day.
business_type defaults to "B11" (production unit); pass "B12" for generation unit. psr_type filters to one technology (e.g. "B16" for solar, "B14" for nuclear) server-side.
Returns the parse_master_data shape: one row per generating unit with parent production-unit context, rated MW, location, etc. Pass Raw() to get the raw Configuration_MarketDocument XML.
Wrappers — OMI (paginated)
The OMI endpoint paginates server-side; our wrapper handles the offset loop:
ENTSOE.omi_other_market_information Method
omi_other_market_information(client, control_area, start, stop;
document_type="A95",
max_pages=25, validate=nothing)Walk the OMI ("Other Market Information") endpoint with automatic offset-based pagination. The server's page size is fixed at 200 documents — only the offset parameter exists on the wire, so the stride is not configurable (ENTSO-E hard-caps OMI queries at 5000 entries total, i.e. max_pages = 25 pages).
Returns a Vector{String} of XML payloads, one per page. Stops when a page comes back as an ENTSOEAcknowledgement (no more data) or when max_pages is reached.
xmls = omi_other_market_information(
client, EIC.NL,
DateTime("2024-09-01T22:00"), DateTime("2024-09-30T22:00"),
)
# Each entry is a separate <Anomalies_MarketDocument> chunk; users
# parse them however they need (often with `parse_timeseries` or the
# raw XML).Request splitting
ENTSO-E caps most endpoints at "one year per request". The time-series wrappers handle this transparently: hand them a longer range and they split it into per-endpoint window-sized chunks (default Year(1), or Day(1) for the balancing-bid family), fetch each chunk, skip empty ones, and concatenate the results. split_period exposes the underlying chunk arithmetic if you want the window boundaries themselves.
ENTSOE.split_period Function
split_period(start, stop; window=Year(1)) -> Vector{Tuple{DateTime, DateTime}}Slice the half-open interval [start, stop) into consecutive (window_start, window_end) chunks of at most window length. The last chunk is short if the total period isn't an exact multiple of window. Accepts DateTime, Date, or yyyymmddHHMM integer endpoints.
This is the pure arithmetic primitive; the named wrappers reuse it internally (via _split_query) to fetch one chunk per window and concatenate the results automatically.
julia> using Dates
julia> split_period(DateTime("2022-01-01"), DateTime("2025-01-01"); window = Year(1))
3-element Vector{Tuple{DateTime, DateTime}}:
(DateTime("2022-01-01T00:00:00"), DateTime("2023-01-01T00:00:00"))
(DateTime("2023-01-01T00:00:00"), DateTime("2024-01-01T00:00:00"))
(DateTime("2024-01-01T00:00:00"), DateTime("2025-01-01T00:00:00"))