# Sweden Electricity Prices: Nord Pool Spot Prices SE1-SE4 (`nightwave-owner/sweden-electricity-prices`) Actor

Returns Swedish day-ahead electricity spot prices (Nord Pool) for bidding zones SE1-SE4 in SEK and EUR per kWh, hourly or per 15 minutes, with daily min, max and average. Supports onlyNew for scheduled runs.

- **URL**: https://apify.com/nightwave-owner/sweden-electricity-prices.md
- **Developed by:** [Viktor Wiberg](https://apify.com/nightwave-owner) (community)
- **Categories:** Developer tools, Automation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 price rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Sweden Electricity Prices: Nord Pool Spot Prices SE1-SE4

Day-ahead electricity spot prices for the four Swedish bidding zones, in SEK and EUR per kWh. You get one row per 15 minute period (or per hour if you ask for hourly averages). You can also get one summary row per zone and day with the lowest, highest and average price and the cheapest and most expensive hour.

The data comes from the open API at [Elpriset just nu.se](https://www.elprisetjustnu.se), which publishes the Nord Pool day-ahead prices as reported to the ENTSO-E Transparency Platform (entsoe.eu).

### Bidding zones

| Zone | Area | Largest city |
|---|---|---|
| SE1 | Northern Sweden | Luleå |
| SE2 | Northern central Sweden | Sundsvall |
| SE3 | Southern central Sweden | Stockholm |
| SE4 | Southern Sweden | Malmö |

### Example from a real run

This is the input and the first rows of a run on the Apify platform on 3 October 2026 (run `vSkdLSjFe6yGAAH12`, 25 rows in total). Nothing is edited except that only the first rows are shown.

Input:

```json
{
  "areas": [
    "SE3"
  ],
  "resolution": "hour",
  "includeDailySummary": true,
  "currency": "both",
  "onlyNew": false,
  "maxResults": 50
}
```

Output (excerpt):

```json
[
  {
    "area": "SE3",
    "date": "2026-10-03",
    "timeStart": "2026-10-03T00:00:00+02:00",
    "timeEnd": "2026-10-03T01:00:00+02:00",
    "resolution": "hour",
    "priceSekPerKwh": 0.69154,
    "priceEurPerKwh": 0.0612,
    "exchangeRateEurSek": 11.299657,
    "source": "elprisetjustnu.se"
  },
  {
    "area": "SE3",
    "date": "2026-10-03",
    "timeStart": "2026-10-03T01:00:00+02:00",
    "timeEnd": "2026-10-03T02:00:00+02:00",
    "resolution": "hour",
    "priceSekPerKwh": 0.65259,
    "priceEurPerKwh": 0.05775,
    "exchangeRateEurSek": 11.299657,
    "source": "elprisetjustnu.se"
  },
  {
    "type": "dailySummary",
    "area": "SE3",
    "date": "2026-10-03",
    "min": {
      "sekPerKwh": 0.05599,
      "eurPerKwh": 0.00496
    },
    "max": {
      "sekPerKwh": 1.04321,
      "eurPerKwh": 0.09232
    },
    "average": {
      "sekPerKwh": 0.59225,
      "eurPerKwh": 0.05241
    },
    "cheapestHourStart": "2026-10-03T23:00:00+02:00",
    "mostExpensiveHourStart": "2026-10-03T18:00:00+02:00",
    "hours": 24,
    "exchangeRateEurSek": 11.299657,
    "source": "elprisetjustnu.se"
  }
]
```

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `areas` | array | `["SE3"]` | Zones to fetch: `SE1`, `SE2`, `SE3`, `SE4`. |
| `startDate` | string | today | First day, `YYYY-MM-DD` in Swedish time. Data is available from 2022-11-01. |
| `endDate` | string | start date or today | Last day (inclusive). Can be tomorrow. At most 366 days per run. |
| `resolution` | string | `hour` | `hour` gives the hourly average of the quarter prices, rounded to 5 decimals. `quarter` gives the 15 minute prices as published. |
| `includeDailySummary` | boolean | `true` | Adds one summary row per zone and day. |
| `currency` | string | `both` | `SEK`, `EUR` or `both`. Controls which price fields are included. |
| `onlyNew` | boolean | `false` | Return only rows that earlier runs with the same input did not deliver. See "Monitoring and scheduling". |
| `maxResults` | integer | `50` | Maximum number of rows, summary rows included. 1 to 100 000. |

A run with empty input returns today's hourly prices for SE3 (Stockholm) and one daily summary: 25 rows.

Example input:

```json
{
  "areas": ["SE3", "SE4"],
  "startDate": "2026-10-02",
  "endDate": "2026-10-03",
  "resolution": "quarter",
  "includeDailySummary": true,
  "currency": "both",
  "maxResults": 500
}
```

### Output

#### Price rows

| Field | Description |
|---|---|
| `area` | `SE1`, `SE2`, `SE3` or `SE4` |
| `date` | Delivery day, `YYYY-MM-DD` in Swedish time (Europe/Stockholm) |
| `timeStart`, `timeEnd` | ISO 8601 with the Swedish UTC offset, for example `2026-10-03T00:00:00+02:00` |
| `resolution` | `quarter` or `hour` |
| `priceSekPerKwh` | Price in SEK per kWh (left out if `currency` is `EUR`) |
| `priceEurPerKwh` | Price in EUR per kWh (left out if `currency` is `SEK`) |
| `exchangeRateEurSek` | The EUR/SEK rate the source used for the day |
| `source` | Always `elprisetjustnu.se` |

```json
{
  "area": "SE3",
  "date": "2026-10-03",
  "timeStart": "2026-10-03T00:00:00+02:00",
  "timeEnd": "2026-10-03T00:15:00+02:00",
  "resolution": "quarter",
  "priceSekPerKwh": 0.80081,
  "priceEurPerKwh": 0.07087,
  "exchangeRateEurSek": 11.299657,
  "source": "elprisetjustnu.se"
}
```

#### Daily summary rows

Added when `includeDailySummary` is `true`. `min`, `max`, `cheapestHourStart` and `mostExpensiveHourStart` are based on hourly averages, so a single cheap 15 minute period does not decide the cheapest hour. `average` is the mean of all prices for the day. `hours` is the number of hours in the day (23 or 25 on daylight saving days).

```json
{
  "type": "dailySummary",
  "area": "SE3",
  "date": "2026-10-03",
  "min": { "sekPerKwh": 0.05599, "eurPerKwh": 0.00496 },
  "max": { "sekPerKwh": 1.04321, "eurPerKwh": 0.09232 },
  "average": { "sekPerKwh": 0.59225, "eurPerKwh": 0.05241 },
  "cheapestHourStart": "2026-10-03T23:00:00+02:00",
  "mostExpensiveHourStart": "2026-10-03T18:00:00+02:00",
  "hours": 24,
  "exchangeRateEurSek": 11.299657,
  "source": "elprisetjustnu.se"
}
```

| Field | Description |
|---|---|
| `type` | Always `dailySummary` |
| `area`, `date` | Zone and delivery day, as for price rows |
| `min`, `max` | Lowest and highest hourly average of the day, as `{ "sekPerKwh", "eurPerKwh" }` |
| `average` | Mean of all prices of the day, same format |
| `cheapestHourStart`, `mostExpensiveHourStart` | Start of the cheapest and the most expensive hour, ISO 8601 with UTC offset |
| `hours` | Number of hours in the day (23, 24 or 25) |
| `exchangeRateEurSek`, `source` | As for price rows |

Price rows have no `type` field, so you can filter summaries with `type = "dailySummary"`.

### Monitoring and scheduling

Set `onlyNew` to `true` to use the actor for recurring monitoring. The actor then remembers which rows it has delivered for the same input, in a named key-value store in your Apify account (`nightwave-state-sweden-electricity-prices`, one record per input). Each run returns and charges only rows that earlier runs did not deliver. The first run returns everything in the selection. A run without news finishes successfully with 0 rows.

A row is identified by zone and start time, and a summary row by zone and day. The input below has no dates, so each run covers the current day in Swedish time. If your client builds the input, set `endDate` to tomorrow's date and schedule a run after 13:00 to get tomorrow's prices as soon as they are published: with `onlyNew` the next run skips the hours you already have.

`onlyNew` and `maxResults` are not part of the remembered input, so you can change them without starting over. Changing any other field starts a fresh state. To start over with the same input, delete the record in the key-value store.

Example: a daily run at 00:30 Swedish time that returns the new day's hourly prices for all four zones. In Apify Console, open **Schedules**, create a schedule with the cron expression `30 0 * * *` and add this actor with the input below.

```json
{
  "areas": ["SE1", "SE2", "SE3", "SE4"],
  "resolution": "hour",
  "includeDailySummary": true,
  "onlyNew": true,
  "maxResults": 200
}
```

The same schedule through the Apify API:

```sh
curl -X POST "https://api.apify.com/v2/schedules?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"name": "daily-sweden-electricity-prices", "cronExpression": "30 0 * * *", "timezone": "Europe/Stockholm", "isEnabled": true, "isExclusive": true,
       "actions": [{"type": "RUN_ACTOR", "actorId": "nightwave-owner~sweden-electricity-prices",
                    "runInput": {"contentType": "application/json; charset=utf-8", "body": "<the input above as a JSON string>"}}]}'
```

Connect a webhook or an integration (Slack, e-mail, Google Sheets) to the actor in Apify Console if you want the new rows sent somewhere when the run finishes.

### Good to know

- **Prices exclude VAT, energy tax, grid fees and supplier mark-ups.** They are the wholesale spot price only.
- **Tomorrow's prices are published after about 13:00 Swedish time.** If you ask for tomorrow before that, the day is skipped with a log message and the run still succeeds.
- Since 1 October 2025 the day-ahead market uses 15 minute periods, so a normal day has 96 rows per zone. Before that the source has hourly prices (24 rows), which are returned as they are.
- Daylight saving days have 92 or 100 quarter rows (23 or 25 hours). On the autumn day the repeated hour 02:00 appears twice, once with `+02:00` and once with `+01:00`.
- Failed requests are retried three times. If the source returns data in an unexpected format the run fails with a clear message instead of storing broken rows.

### Use cases

- Shift flexible loads such as EV charging, heat pumps or batteries to the cheapest hours of tomorrow, using `cheapestHourStart` and the quarter prices.
- Show today's and tomorrow's spot price per zone in an app, a dashboard or a Home Assistant setup without running your own Nord Pool integration.
- Compare price spreads between SE1 and SE4 over a season by running with `startDate` and `endDate` and exporting the rows to CSV or Excel.
- Recalculate a variable electricity contract or an energy report with the actual hourly spot price per zone.
- Feed a forecasting or trading model with clean, time zone correct history back to November 2022.

### FAQ

**How often is the data updated?**
Nord Pool publishes the next day's day-ahead prices once a day, normally around 13:00 Swedish time. Every run reads the source live, so a run after that time can include tomorrow.

**What does 1 000 rows cost?**
2 USD (0.002 USD per row, event `price-row`). Platform usage is included. One zone for one day is 25 rows at hourly resolution with a summary, so a year of daily runs for one zone is about 9 000 rows.

**Can I schedule it?**
Yes. Use an Apify schedule with `onlyNew: true` and you get only the rows you have not received before. See "Monitoring and scheduling" above.

**Can I use the data commercially?**
The source states the data is free to use for any purpose and asks for attribution to Elpriset just nu.se when you show it publicly. See "Data source and license".

### Data source and license

Prices are fetched from the Elpriset just nu.se API. According to [elprisetjustnu.se/elpris-api](https://www.elprisetjustnu.se/elpris-api) the data is free to use by anyone for any purpose. The source asks for attribution when the data is shown publicly, so please credit "Elpriset just nu.se" with a link if you publish the data. The underlying data comes from the ENTSO-E Transparency Platform. The dataset contains no personal data.

This actor is not affiliated with Elpriset just nu.se, Nord Pool or ENTSO-E.

### Pricing

Pay per result: 0.002 USD per row returned (event `price-row`), which is 2 USD per 1 000 price rows. Platform usage is included, so you pay only per result. `maxResults` caps how many rows a run returns, so you always know the highest possible cost.

Rows are delivered only after they have been charged. If you set a maximum cost per run (maxTotalChargeUsd), the run stops there and its status message says how many rows were delivered.

### Contact

Built and maintained by Nightwave AB. Questions, bugs and feature requests: kontakt@nightwave.se

### På svenska

Actorn hämtar dagen-före-priser på el (Nord Pool) för elområdena SE1-SE4 i kronor och euro per kWh, per kvart eller som timmedel, med en valfri dygnssammanställning (lägsta, högsta och genomsnittligt pris samt billigaste och dyraste timmen).

- Priserna är spotpriser **exklusive moms, energiskatt, nätavgift och elhandlarens påslag**.
- Morgondagens priser publiceras efter cirka 13:00 svensk tid. Före det hoppas dagen över med en loggrad.
- Datum och dygnsgränser följer svensk tid. Dagar med sommartidsomställning har 23 eller 25 timmar.
- Källa: [Elpriset just nu.se](https://www.elprisetjustnu.se) (data från ENTSO-E). Fri att använda, med önskemål om hänvisning till Elpriset just nu.se när datan visas publikt.
- Med `onlyNew: true` levereras bara rader som tidigare körningar med samma input inte har levererat. Det passar för schemalagda körningar i Apify (se "Monitoring and scheduling").
- Tom input ger dagens timpriser för SE3 och en dygnssammanställning, 25 rader. `maxResults` är som standard 50.
- Pris: 0,002 USD per rad (2 USD per 1 000 rader). Plattformsanvändningen ingår.
- Kontakt: kontakt@nightwave.se

# Actor input Schema

## `areas` (type: `array`):

Swedish bidding zones to fetch, for example \["SE3"]. SE1 is Luleå, SE2 Sundsvall, SE3 Stockholm and SE4 Malmö. Defaults to SE3.

## `startDate` (type: `string`):

First day to fetch, YYYY-MM-DD in Swedish time, for example "2026-10-03". Defaults to today. Data is available from 2022-11-01.

## `endDate` (type: `string`):

Last day to fetch (inclusive), YYYY-MM-DD in Swedish time, for example "2026-10-04". Defaults to the start date or today. Can be tomorrow: tomorrow's prices are published after about 13:00 Swedish time, and an unpublished day is skipped with a log message. At most 366 days per run.

## `resolution` (type: `string`):

"hour" returns hourly averages of the quarter prices, rounded to 5 decimals (24 rows per zone and day). "quarter" returns the 15 minute prices as published (96 rows per zone and day). Defaults to hour.

## `includeDailySummary` (type: `boolean`):

Adds one row per zone and day with min, max and average price and the cheapest and most expensive hour (based on hourly averages), for example true. Defaults to true.

## `currency` (type: `string`):

Which price fields to include: "SEK", "EUR" or "both", for example "SEK". The EUR/SEK exchange rate is always included. Defaults to both.

## `onlyNew` (type: `boolean`):

For scheduled runs. When true, rows that an earlier run with the same input already delivered are skipped and not charged, so each run returns only new prices (for example tomorrow's prices once they are published). The first run returns everything. Defaults to false.

## `maxResults` (type: `integer`):

Maximum number of rows to return, including summary rows, for example 50. One zone for one day at hourly resolution with a summary is 25 rows. Each row is one billable result. Defaults to 50.

## Actor input object example

```json
{
  "areas": [
    "SE3",
    "SE4"
  ],
  "startDate": "2026-10-03",
  "endDate": "2026-10-04",
  "resolution": "hour",
  "includeDailySummary": true,
  "currency": "SEK",
  "onlyNew": true,
  "maxResults": 25
}
```

# Actor output Schema

## `results` (type: `string`):

All rows produced by the run, as JSON. Open in Apify Console or download via the dataset API.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "areas": [
        "SE3"
    ],
    "resolution": "hour",
    "includeDailySummary": true,
    "currency": "both",
    "onlyNew": false,
    "maxResults": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("nightwave-owner/sweden-electricity-prices").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "areas": ["SE3"],
    "resolution": "hour",
    "includeDailySummary": True,
    "currency": "both",
    "onlyNew": False,
    "maxResults": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("nightwave-owner/sweden-electricity-prices").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "areas": [
    "SE3"
  ],
  "resolution": "hour",
  "includeDailySummary": true,
  "currency": "both",
  "onlyNew": false,
  "maxResults": 50
}' |
apify call nightwave-owner/sweden-electricity-prices --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nightwave-owner/sweden-electricity-prices"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/MdcaAUVejT3lI4VII/builds/amJTFEE2cUtXdD7Ze/openapi.json
