API Guide
API Guide: How to use our open data portal
Welcome to the API guide for Svenska Kraftnät's Data Service. We want to make our electricity market data and ancillary services as accessible as possible for reuse. The portal offers a powerful REST API (based on CKAN) that allows you to retrieve machine-readable data free of charge directly into your applications or integration workflows.
Authentication and access
💡 No API token required: Our data portal is completely open. You do not need to register an account, create developer profiles, or include an
API_TOKEN(orX-CKAN-API-Key) in your HTTP headers to call our public APIs.
Best practices for API usage
To ensure a stable platform for all users, we recommend the following guidelines when integrating, in line with how data management is handled by other Nordic system operators:
- The API is not a direct backend for end-user applications: The portal is intended for fetching data for further processing. If you are building an app or service, your platform should fetch the data from us and then act as the data source for your own end users.
- Avoid unnecessary polling: Design your integrations to respect the dataset's update frequency rather than continuously making the same request. If a dataset is updated once per day, a single daily call is sufficient.
- Filter at the source: Use the API's parameters to fetch only the data you actually need, rather than retrieving the entire dataset and filtering locally.
Building your query (Request methods)
Our REST API is a synchronous interface accessible via standard HTTP GET requests. Other operations that could modify data on the portal, e.g. PUT, DELETE, etc., are disabled for external users.
The portal's primary search endpoint (datastore) is:
https://data.svk.se/sv/api/3/action/ with the operation datastore_search
The response is returned in JSON format and contains both metadata (schema/ontologies) and the actual data records (records).
Note: there are several operations available, described in CKAN's official Action API guide. In this guide, however, we focus on
datastore_search.
Parameters
You specify your selection criteria as parameters directly in the URI string:
- resource_id (Required): The unique ID (UUID) of the specific dataset or resource you want to retrieve.
- limit: Maximum number of rows to return (default is often 100). Use
limitandoffsetto paginate through large datasets. - q: Full-text search across all fields.
- filters: A JSON-formatted object for filtering on exact column values (e.g. bidding zone or a specific reserve product).
Example requests
In this guide and examples, we use the dataset FCR capacity market, bid volumes (No longer updated, see description).
The dataset contains historical observations and has resource ID: bbe7d8c7-912f-4665-99e0-74493c75f7ef.
You can find the resource ID for the dataset you want to work with either:
- In the URL of a dataset, e.g.: https://data.svk.se/sv/dataset/fcr_accepted_aggregated_offers/resource/bbe7d8c7-912f-4665-99e0-74493c75f7ef
- In the ID field value on the dataset page, under the "More information" section.
- Nested in the JSON data structure from a Package search API call.
1. Retrieve the first 5 rows
To quickly inspect the structure of a data resource, you can limit the result using limit.
HTTP GET request: browser or via e.g. Postman
https://data.svk.se/sv/api/3/action/datastore_search?resource_id=bbe7d8c7-912f-4665-99e0-74493c75f7ef&limit=5
Expected result (excerpt): You receive a JSON object where the key records contains the array of data. Here you can clearly see fields such as reserve_direction (e.g. up), reserve_product (e.g. FCRD), and information about price and volume. The response also includes the metadata decorated as properties of records to achieve Open Linked Data principles.
"result": {
"include_next_page": false,
"include_total": true,
"limit": 5,
"records_format": "objects",
"resource_id": "bbe7d8c7-912f-4665-99e0-74493c75f7ef",
"total_estimation_threshold": null,
"records": [
{
"_id": 1, // The API sorts by _id ascending by default
"start_time_sweden": "2025-12-07T18:00:00",
"start_time_utc": "2025-12-07T17:00:00",
"auction_round": "fcrAuction2",
"reserve_product": "FCRD",
"reserve_direction": "up",
"volume": 396.6,
"volume_unit": "MW",
"soda_hashbyte": "989e8a0e88e53df8e053189d4c2553d2",
"soda_identity": 1
},
{
"_id": 2,
"start_time_sweden": "2023-02-13T03:00:00",
"start_time_utc": "2023-02-13T02:00:00",
"auction_round": "fcrAuction2",
"reserve_product": "FCRD",
"reserve_direction": "up",
"volume": 313.1,
"volume_unit": "MW",
"soda_hashbyte": "217d84df7ff9f8be97d4614a44fca6d4",
"soda_identity": 2
},
// etc. more JSON data and Open Linked Data metadata
2. Search by keyword and filter
If you want to search for a specific keyword across all columns, use the q parameter. Here we filter on a real ancillary service, for example the frequency containment reserve normal FCRN.
Keyword request:
https://data.svk.se/sv/api/3/action/datastore_search?resource_id=bbe7d8c7-912f-4665-99e0-74493c75f7ef&q=FCRN
The result is automatically filtered to show only the observations where the string FCRN appears in any of the columns.
Request with filter
You can also search with an attached filter. The filter is formatted as a json object passed as a URL parameter in the GET request.
To find 4 rows matching product FCRD and direction up, we construct the filter:
// Example filter 1
{
"reserve_product":"FCRD",
"reserve_direction":"up"
}
and attach it as a URL parameter &filters= followed by &limit=4:
https://data.svk.se/sv/api/action/datastore_search?resource_id=bbe7d8c7-912f-4665-99e0-74493c75f7ef&filters={"reserve_product":"FCRD","reserve_direction":"up"}&limit=4
Response
"result": {
"filters": {
"reserve_product": "FCRD",
"reserve_direction": "up"
},
"include_next_page": false,
"include_total": true,
"limit": 4,
"records_format": "objects",
"resource_id": "bbe7d8c7-912f-4665-99e0-74493c75f7ef",
"total_estimation_threshold": null,
"filterops": {
"op": "$and",
"field": null,
"value": [
{
"op": "eq",
"field": "reserve_product",
"value": "FCRD"
},
{
"op": "eq",
"field": "reserve_direction",
"value": "up"
}
]
},
"records": [
{
"_id": 1,
"start_time_sweden": "2025-12-07T18:00:00",
"start_time_utc": "2025-12-07T17:00:00",
"auction_round": "fcrAuction2",
"reserve_product": "FCRD",
"reserve_direction": "up",
"volume": 396.6,
"volume_unit": "MW",
"soda_hashbyte": "989e8a0e88e53df8e053189d4c2553d2",
"soda_identity": 1
},
{
"_id": 2,
"start_time_sweden": "2023-02-13T03:00:00",
"start_time_utc": "2023-02-13T02:00:00",
"auction_round": "fcrAuction2",
"reserve_product": "FCRD",
"reserve_direction": "up",
"volume": 313.1,
"volume_unit": "MW",
"soda_hashbyte": "217d84df7ff9f8be97d4614a44fca6d4",
"soda_identity": 2
}
// more rows and Open Linked Data metadata
3. Search via SQL statement (datastore_search_sql)
For more advanced or complex queries, the portal supports SQL queries via the datastore_search_sql endpoint.
💡 SQL IS A HEAVY OPERATION Note that an
SQL SELECT statementscans the entire dataset before returning a response. Where our earlier requests return40–50 KB, this endpoint processes the full dataset and sorts before returning results, meaning the response can be15+ MBin size.
Say you want to retrieve 2 data rows for FCRD (reserve_product) and reserve direction (reserve_direction) Up, sorted by start time (start_time_sweden) — you would construct the SQL statement as follows:
SELECT * from "bbe7d8c7-912f-4665-99e0-74493c75f7ef" WHERE reserve_product = 'FCRD' AND reserve_direction = 'up' ORDER BY start_time_sweden ASC LIMIT 2 // note the absence of a trailing ; character.
HTTP GET request: browser or via e.g. Postman
https://data.svk.se/sv/api/3/action/datastore_search_sql?sql=SELECT * from "bbe7d8c7-912f-4665-99e0-74493c75f7ef" WHERE reserve_product = 'FCRD' AND reserve_direction = 'up' ORDER BY start_time_sweden ASC LIMIT 2
Tip: Note that the resource ID must be enclosed in double quotes ("") in the SQL string, while text values use single quotes (''), and the trailing ; is omitted from this SQL statement.
Response
"result": {
"sql": "SELECT * from \"bbe7d8c7-912f-4665-99e0-74493c75f7ef\" WHERE reserve_product = 'FCRD' AND reserve_direction = 'up' ORDER BY start_time_sweden ASC LIMIT 2",
"records": [
{
"_id": 241056,
"_full_text": "'-01':2,3 '-12':8 '-31':9 '00':5,6,11,12 '2019':7 '2020':1 '241056':19 '672.4':16 'f149cf5f25e1f798b6033ed19d7ad947':18 'fcrauction1':13 'fcrd':14 'mw':17 't00':4 't23':10",
"start_time_sweden": "2020-01-01T00:00:00", // same time of day
"start_time_utc": "2019-12-31T23:00:00",
"auction_round": "fcrAuction1", // applies to auction round 1
"reserve_product": "FCRD",
"reserve_direction": "up",
"volume": 672.4,
"volume_unit": "MW",
"soda_hashbyte": "f149cf5f25e1f798b6033ed19d7ad947",
"soda_identity": 241056
},
{
"_id": 256531,
"_full_text": "'-01':2,3 '-12':8 '-31':9 '00':5,6,11,12 '2019':7 '2020':1 '216.9':16 '256531':19 'a72ab08f1cf43b4f1c14395a80dcd54d':18 'fcrauction2':13 'fcrd':14 'mw':17 't00':4 't23':10",
"start_time_sweden": "2020-01-01T00:00:00", // same time of day
"start_time_utc": "2019-12-31T23:00:00",
"auction_round": "fcrAuction2", // but applies to auction round 2
"reserve_product": "FCRD",
"reserve_direction": "up",
"volume": 216.9,
"volume_unit": "MW",
"soda_hashbyte": "a72ab08f1cf43b4f1c14395a80dcd54d",
"soda_identity": 256531
}
...further JSON with metadata fields...
Understanding the result: Semantics and Linked Data
Our portal is built on the principles of Open Linked Data. When you make a call to the API, you receive not only the raw values, but also the semantic schema of the data via the schema block in the JSON response.
This defines how our data maps to open, structured ontologies:
- bidding_zone: Relates the value to
https://data.svk.se/ontology/emdo#hasBiddingZone(geographic market area). - price: Relates to
https://data.svk.se/ontology/base#priceValue, where the price unit is defined separately via thehasPricePerUnitproperty. - start_time_utc: Defined via
https://data.svk.se/ontology/base#validFromDateTime(standardised validity period in UTC).
This allows you as an integrator to trust that values such as SE1, FCRN, or the price value 4.73 are not merely isolated strings, but entities with clearly defined concepts within the European electricity market standard. The goal is machine-readability and semantic clarity end to end!