Skip to content

API Guide

25 June 2026

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 (or X-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. PUTDELETE, 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 limit and offset to paginate through large datasets. The maximum value for limit is 32,000.
  • 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).
  • sort: Used to control the order in which results are returned from the API.

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:

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. Working with Dates

To efficiently retrieve relevant datasets, you can use date filters in your API requests.

Time Zones

Dates and times follow the ISO 8601 standard (YYYY-MM-DDTHH:MM:SS), for example April 1, 2026 at 08:00 👉 2026-04-01T08:00:00.

Time fields exist in two variants:

  • start_time_utc – time in UTC
  • start_time_sweden – local Swedish time

💡 Note that specifying only a date without time (e.g., "2026-04-01") will not match timestamp fields that include time, and will result in an empty result.

Date Filtering

Filtering is done via the filters parameter, where dates can be combined with comparison operators.

Available operators:

  • gt (greater than)
  • gte (greater than or equal to)
  • lt (less than)
  • lte (less than or equal to)

Example: filtering for a specific date

To retrieve data for a single day, define an interval from 00:00 of the selected day to 00:00 of the following day. Since the default limit is 100, we set it to 144 in this example to include all observations:

// Example date 1

{
  "start_time_utc": {
    "gte": "2026-04-01T00:00:00",
    "lt": "2026-04-02T00:00:00"
  }
}
&sort=start_time_sweden
&limit=144

Attach it as a URL parameter using &filters=:

https://data.svk.se/api/action/datastore_search?resource_id=bbe7d8c7-912f-4665-99e0-74493c75f7ef&filters={"start_time_sweden":{"gte":"2026-04-01T00:00:00","lt":"2026-04-02T00:00:00"}}&sort=start_time_sweden&limit=144

The result contains all observations for April 1, 2026.

Response (excerpt)

"result": {
    "filters": {
        "start_time_sweden": {
        "gte": "2026-04-01T00:00:00",
        "lt": "2026-04-02T00:00:00"
        }
    },
    "include_next_page": false,
    "include_total": true,
    "limit": 144,
    "records_format": "objects",
    "resource_id": "bbe7d8c7-912f-4665-99e0-74493c75f7ef",
    "sort": "start_time_sweden",
    ...

Example: filtering from a given start date

To retrieve data from a certain date onward, use only gte without an upper bound:

// Example date 2

{
  "start_time_sweden": {
    "gte": "2026-04-01T00:00:00"
  }
}

https://data.svk.se/api/action/datastore_search?resource_id=bbe7d8c7-912f-4665-99e0-74493c75f7ef&filters={"start_time_sweden":{"gte":"2026-04-01T00:00:00"}}&sort=start_time_sweden

💡 If the limit parameter is not specified, the API returns the first 100 rows by default.

// Example date 3

{
  "start_time_sweden": {
    "gte": "2026-04-01T00:00:00"
  }
}
&limit=1000

https://data.svk.se/api/action/datastore_search?resource_id=bbe7d8c7-912f-4665-99e0-74493c75f7ef&filters={"start_time_sweden":{"gte":"2026-04-01T00:00:00"}}&sort=start_time_sweden&limit=1000

In the example above, the first 1000 rows are retrieved. For large datasets, combine limit with offset to retrieve data step by step.

// Example date 4
// Request 1: rows 1–1000

{
  "start_time_sweden": {
    "gte": "2026-04-01T00:00:00"
  }
}
&limit=1000
&offset=0

// Request 2: rows 1001–2000

{
  "start_time_sweden": {
    "gte": "2026-04-01T00:00:00"
  }
}
&limit=1000
&offset=1000

💡 It is not possible to specify multiple offset values in a single request. To retrieve multiple pages of data, you must make separate API calls with incrementally increasing offset. The maximum limit is 32,000.

// Request 1
https://data.svk.se/api/action/datastore_search?resource_id=bbe7d8c7-912f-4665-99e0-74493c75f7ef&filters={"start_time_sweden":{"gte":"2026-04-01T00:00:00"}}&sort=start_time_sweden&limit=1000&offset=0

// Request 2
https://data.svk.se/api/action/datastore_search?resource_id=bbe7d8c7-912f-4665-99e0-74493c75f7ef&filters={"start_time_sweden":{"gte":"2026-04-01T00:00:00"}}&sort=start_time_sweden&limit=1000&offset=1000

Response request 1 (excerpt)

"result": {
    "filters": {
        "start_time_sweden": {
        "gte": "2026-04-01T00:00:00"
        }
    },
    "include_next_page": false,
    "include_total": true,
    "limit": 1000,
    "offset": 0,
    "records_format": "objects",
    "resource_id": "bbe7d8c7-912f-4665-99e0-74493c75f7ef",
    "sort": "start_time_sweden",
    "total_estimation_threshold": null,
    "filterops": {
        "op": "gte",
        "field": "start_time_sweden",
        "value": "2026-04-01T00:00:00"
    },
    "records": [
        {
        "_id": 10155,
        "start_time_sweden": "2026-04-01T00:00:00",
        "start_time_utc": "2026-03-31T22:00:00",
        "auction_round": "fcrAuction2",
        "reserve_product": "FCRN",
        "reserve_direction": "symmetric",
        "volume": 134,
        "volume_unit": "MW",
        "soda_hashbyte": "0362de6edbdd46935bb45594a507ca57",
        "soda_identity": 10155
        },
    ...
        {
        "_id": 188646,
        "start_time_sweden": "2026-04-07T22:00:00",
        "start_time_utc": "2026-04-07T20:00:00",
        "auction_round": "fcrAuction1",
        "reserve_product": "FCRD",
        "reserve_direction": "up",
        "volume": 626.4,
        "volume_unit": "MW",
        "soda_hashbyte": "cc901802db003c8660f9146746e27838",
        "soda_identity": 188646
        }

Response request 2 (excerpt)

"result": {
    "filters": {
        "start_time_sweden": {
        "gte": "2026-04-01T00:00:00"
        }
    },
    "include_next_page": false,
    "include_total": true,
    "limit": 1000,
    "offset": 1000,
    "records_format": "objects",
    "resource_id": "bbe7d8c7-912f-4665-99e0-74493c75f7ef",
    "sort": "start_time_sweden",
    "total_estimation_threshold": null,
    "filterops": {
        "op": "gte",
        "field": "start_time_sweden",
        "value": "2026-04-01T00:00:00"
    },
    "records": [
        {
        "_id": 83262,
        "start_time_sweden": "2026-04-07T22:00:00",
        "start_time_utc": "2026-04-07T20:00:00",
        "auction_round": "fcrAuction2",
        "reserve_product": "FCRD",
        "reserve_direction": "down",
        "volume": 236.9,
        "volume_unit": "MW",
        "soda_hashbyte": "e270feb4894f9ff68e98a5e6e9900450",
        "soda_identity": 83262
        },
    ...
        {
        "_id": 171218,
        "start_time_sweden": "2026-04-14T21:00:00",
        "start_time_utc": "2026-04-14T19:00:00",
        "auction_round": "fcrAuction2",
        "reserve_product": "FCRD",
        "reserve_direction": "down",
        "volume": 339.7,
        "volume_unit": "MW",
        "soda_hashbyte": "39fb594643e585e24f287b93bc15353e",
        "soda_identity": 171218
        }

4. 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 statement scans the entire dataset before returning a response. Where our earlier requests return 40–50 KB, this endpoint processes the full dataset and sorts before returning results, meaning the response can be 15+ MB in size.

⚠️ Note: The datastore_search_sql endpoint has been disabled on the portal and can no longer be used for data retrieval. Instead, use the standard API endpoints for filtering and retrieving data.

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 the hasPricePerUnit property.
  • 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 SE1FCRN, 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!