BYTETOOLS

Energi Data Service API

Free Danish energy API with no key: day-ahead electricity spot prices, production and consumption datasets from the national grid operator. Tested example included.

No API key requiredHTTPSFree tier

Endpoint tested and returned HTTP 200 on 2026-08-21

What is the Energi Data Service API?

Energi Data Service is the open data platform run by Energinet, Denmark's transmission system operator. Its dataset endpoints need no API key and return hourly records — the Elspotprices dataset gives day-ahead electricity prices per bidding zone in both DKK and EUR.

National grid operators sit on some of the most useful public data there is, and Denmark publishes more of it than almost anyone. Every dataset — spot prices, production by fuel type, CO2 emission intensity, cross-border flows — lives behind one uniform `/dataset/{name}` path with a shared query grammar for filtering, sorting and limiting, so learning one endpoint teaches you all of them.

The Elspotprices dataset used here carries a detail worth understanding: `PriceArea` covers more than Denmark. DK1 and DK2 are the two Danish bidding zones split by the Great Belt, but the same dataset also carries neighbouring zones such as DE, because the Nordic and German markets clear together. Two operational notes: the API rejects any request carrying an `Origin` header by returning an empty body, so browser calls are effectively impossible, and a rate limiter will hand you a 429 with a `Retry-After` figure in the message if you hammer it.

Quick facts

Base URL
https://api.energidataservice.dk
Authentication
No API key and no account for any dataset.
Rate limit
Enforced but unpublished. Exceeding it returns HTTP 429 with a message stating how many seconds until the window resets.
Pricing
Free. Data is published under an open licence by Energinet.
CORS
Not enabled — call it from your server
Official docs
Read the docs

How to use the Energi Data Service API

Every request below was executed against the live API on 2026-08-21, and the response shown is the real body it returned — not an illustration.

1. Fetch day-ahead electricity spot prices

GET https://api.energidataservice.dk/dataset/Elspotprices?limit=2

curl
curl 'https://api.energidataservice.dk/dataset/Elspotprices?limit=2'
JavaScript (fetch)
const res = await fetch("https://api.energidataservice.dk/dataset/Elspotprices?limit=2");
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
const data = await res.json();
console.log(data);
Python (requests)
import requests

res = requests.get("https://api.energidataservice.dk/dataset/Elspotprices?limit=2", timeout=20)
res.raise_for_status()
print(res.json())
Response — HTTP 200
{
  "total": 2,
  "filters": "",
  "limit": 2,
  "dataset": "Elspotprices",
  "records": [
    {
      "HourUTC": "2025-09-30T21:00:00",
      "HourDK": "2025-09-30T23:00:00",
      "PriceArea": "DE",
      "SpotPriceDKK": 690.789978,
      "SpotPriceEUR": 92.540001
    },
    {
      "HourUTC": "2025-09-30T21:00:00",
      "HourDK": "2025-09-30T23:00:00",
      "PriceArea": "DK1",
      "SpotPriceDKK": 690.700059,
      "SpotPriceEUR": 92.540001
    }
  ]
}

Parameters

ParameterTypeRequiredDescription
(dataset)pathRequiredDataset name after `/dataset/`, such as `Elspotprices`, `ProductionConsumptionSettlement` or `CO2Emis`. Elspotprices
limitqueryOptionalMaximum records to return. Without it you get a large default page. 2
offsetqueryOptionalRecords to skip, for paging. 0
start / endqueryOptionalISO datetime bounds on the dataset's time column. 2026-08-01T00:00
filterqueryOptionalJSON object filtering by column, URL-encoded — for example `{"PriceArea":["DK1"]}`. {"PriceArea":["DK1"]}
sortqueryOptionalColumn to sort by, with `DESC` for reverse order. HourUTC DESC

Response fields

datasetstring
Echoes which dataset answered, useful when you are proxying several.
totalinteger
Number of records in this response, not the size of the whole dataset.
limitinteger
The limit that was applied.
filterstring
The filter expression that was applied, echoed back — empty when none was sent.
recordsarray
The data rows. Columns vary by dataset.
records[].HourUTCstring
Hour of the observation in UTC. Use this one for any cross-border comparison.
records[].HourDKstring
The same hour in Danish local time, which shifts with daylight saving.
records[].PriceAreastring
Bidding zone — `DK1` and `DK2` for Denmark, plus neighbouring zones such as `DE` that clear in the same market.
records[].SpotPriceDKK / SpotPriceEURfloat
Day-ahead price per MWh in Danish kroner and euros. Negative values are real and occur when renewable output exceeds demand.

What you can build with the Energi Data Service API

  • Chart Danish and German day-ahead electricity prices
  • Schedule heavy loads such as EV charging into the cheapest hours
  • Analyse how wind output correlates with negative price events
  • Feed a home-automation system with tomorrow's tariff

Common errors and how to fix them

Empty body with HTTP 200

The request carried an `Origin` header.

Fix: The API returns zero bytes to cross-origin requests. Call it server-side, without an Origin header.

429 Too Many Requests

The unpublished rate limiter tripped.

Fix: The message names how many seconds remain. Back off for that long rather than retrying immediately.

Negative prices

That is genuine market data, not a bug.

Fix: When renewable generation outstrips demand the clearing price goes below zero. Handle negatives in any chart or billing logic.

Wrong hours in your chart

You used `HourDK`, which follows Danish local time and daylight saving.

Fix: Use `HourUTC` for anything crossing timezones or spanning a clock change.

Energi Data Service API — frequently asked questions

Is Energi Data Service free?

Yes, entirely free with no key or account. Energinet publishes the data as open data under a permissive licence.

Can I call it from browser JavaScript?

No. The API responds to any request carrying an `Origin` header with an empty body, so a browser fetch returns nothing. Proxy it through your own server.

What are DK1 and DK2?

Denmark's two electricity bidding zones, divided by the Great Belt. Prices differ between them, and the same dataset also returns neighbouring zones such as DE that clear in the coupled market.

Why are some spot prices negative?

Because they genuinely go negative. When wind and solar output exceeds demand, generators pay to keep exporting rather than curtail, and the market clears below zero.

Tools that pair with this API

Energi Data Service is an independent third-party service and is not affiliated with ByteTools or ByteVancer. Details on this page were verified on 2026-08-21; always check the official documentation before relying on this API in production, as terms and limits can change.