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. The maximum value forlimitis 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:
- 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. 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 UTCstart_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
limitparameter 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
offsetvalues in a single request. To retrieve multiple pages of data, you must make separate API calls with incrementally increasingoffset. The maximumlimitis 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 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.
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 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!