Gaps declared, never interpolated
The API reports missing data as a gap with a coverage envelope, never as a plausible fill. Interior absence only: the edges of coverage are not gaps. Query them at /v0/gaps.
A public, unauthenticated API over NL imbalance settlement. Built for people who backtest against it — batteries, flexibility operators, aggregators and quant desks — rather than for dashboards.
Imbalance settlement is where flexibility earns. Its prices are also the series where quality problems are expensive and invisible. A silent gap or a quietly-restated value corrupts a revenue backtest without ever throwing an error. Backtest against today's settled values and you trade on information you could not have had. The returns look better than they were.
The API reports missing data as a gap with a coverage envelope, never as a plausible fill. Interior absence only: the edges of coverage are not gaps. Query them at /v0/gaps.
Each series carries its provenance and redistribution terms. The public API serves only what is genuinely redistributable, enforced fail-closed rather than by convention.
?as_of=The API keeps every revision it has observed. Observation starts 2026-06-18, the revisions_observed_from carried in every series and bulk response. Ask what was known at an instant and you get exactly that, with nothing published later leaking in. Earlier points carry the final settled value. The API rejects an earlier as_of with a 400, never an empty result. Revisions are rare here, which is what makes them dangerous. Between 2026-06-18 and 2026-08-15 we observed one revision in 11,120 observations. It cut a settlement price by 77%, thirteen days after the interval closed. ENTSO-E's Transparency Platform serves only the latest value of each point, so nothing there tells you which period moved.
Every observation states its own resolution_min. NL imbalance prices are 15-minute across their whole history. If a resolution ever changes, the API represents the change rather than resampling it away. Gap detection stays correct across it.
Two views over one canonical store. /v0/series serves windowed
and latest reads as JSON for anything interactive.
/v0/bulk serves the history as Parquet. The whole archive is one
object, full.parquet. A first load is a single request, not one
per month. A discovery manifest lists the monthly partitions for staying current afterwards.
Frozen months keep stable URLs and ETags, so you re-download only what moved.
Every file carries
publication_ts and revision,
so you can apply as_of yourself without a query engine. The
Parquet files are also your exit. They sit in an open
format on your own disk. If Tolven ever stops, you lose the refresh, not the history.
Neither view is intraday, and we would rather say so than let you find out. Imbalance settlement arrives in one batch per Dutch local day, so the newest observation is normally between 1 and 25 hours old. Measured 2026-08-16, upstream published at about 23:00 UTC for 44 consecutive days; before 2026-06-30 it published several hours later. That time follows the Dutch local day, so it lands about an hour later under winter time. It is an observation of upstream, not a schedule we can hold it to. A freshness SLA is a paid-tier question.
There is no redistributable public source for NL day-ahead prices. They are set on EPEX SPOT, and ENTSO-E's copy is free to access but not to redistribute. SMARD's open day-ahead data covers DE-LU, AT and LU, not NL. We could not verify the downstream CC-BY claims for NL. Publishing it properly would need a distribution licence from the exchange. Rather than serve data we cannot defend, we serve none — and say so. The full licensing picture →
The free API serves the Dutch bidding zone, whole: history back to 2014-12-05, the revisions observed since 2026-06-18, the bulk Parquet. The imbalance series for other zones come from the same upstream, under the same redistribution terms. Each zone we serve is a zone we operate, so zones beyond NL belong to the paid tier.
That tier — more zones, higher rate limits, a freshness SLA — does not exist yet. We build it when enough people say they would pay for it. If that is worth money to you, name your zone: the address in the footer reaches the operator. Whatever we build, the free API stays whole.