# GB Balancing Auctions – Dynamic Containment, Reserve & FFR (`ukopendatatools/gb-balancing-services-auctions`) Actor

Daily unit-level results of NESO balancing auctions: Dynamic Containment, Moderation and Regulation, Quick, Slow and Balancing Reserve, Static FFR, STOR. Provider, unit, technology, MW, clearing price. Open data.

- **URL**: https://apify.com/ukopendatatools/gb-balancing-services-auctions.md
- **Developed by:** [UK Open Data Tools](https://apify.com/ukopendatatools) (community)
- **Categories:** Business, Developer tools, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

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

## GB Balancing Auctions – Dynamic Containment, Reserve, FFR & STOR Results (NESO)

**Get unit-level results of NESO's daily balancing services auctions as clean JSON, CSV or Excel.** It covers the **Enduring Auction Capability (EAC)**: Dynamic Containment, Dynamic Moderation and Dynamic Regulation (DCH, DCL, DMH, DML, DRH, DRL), Positive/Negative Quick Reserve, Slow Reserve and Balancing Reserve. It also covers the historic **Static FFR** and **STOR** auction results. Each row gives the provider, unit, technology, delivery window, accepted MW, clearing price (£/MW/h) and postcode district. Results for tomorrow's auctions are available the same day, from NESO's official open-data API.

### What data does it return?

- **Market and product:** market (EAC, SFFR, STOR), service, product code and name (e.g. DCL = Dynamic Containment Low)
- **Who:** participant (provider company), unit ID, technology (batteries, load response…), postcode district
- **When:** delivery start and end, EFA block, tender round
- **Result:** status, tendered MW, accepted MW, bid price, clearing price and price unit

### Who is it for?

- **Battery (BESS) owners, optimisers and route-to-market providers:** daily ancillary-service revenue and clearing-price history
- **Aggregators and VPPs:** competitor volumes by unit and provider
- **Traders, analysts and investors:** price and volume trends for frequency response and reserve products
- **Consultants:** revenue stacking models with real accepted volumes

### How to use it

1. Click **Try for free** / **Start**.
2. Pick markets and products (e.g. `DCH`, `DCL`) and a delivery window (e.g. last 1 day, or a date range). You can also filter by participant, unit or technology.
3. Set **Max results** to cap the run and your cost.
4. Run it, then export as JSON, CSV or Excel, or read the results through the Apify API. Schedule it daily for a running price history.

### Input example

```json
{"markets": ["EAC"], "products": ["DCH", "DCL"], "lastDays": 1, "participantKeywords": ["Zenobe"]}
```

### Input reference

| Field | Description |
|---|---|
| markets | `EAC` (default), `SFFR`, `STOR`. |
| products | EAC product codes, e.g. `["DCH","DCL","PQR"]`. Empty = all. |
| lastDays / dateFrom / dateTo | Delivery window (default last 7 days). |
| participantKeywords | e.g. "Zenobe", "Habitat", "Flexitricity". |
| units | Exact unit IDs. |
| technologyKeywords | e.g. "Battery", "Load Response". |
| acceptedOnly | Only rows with accepted volume (default on). |
| maxItems | Stop after N rows (default 1000). |

### Output example

One dataset item per accepted unit result. This record is from a real test run:

```json
{
  "market": "EAC",
  "sourceUrl": "https://www.neso.energy/data-portal/eac-auction-results",
  "priceUnit": "GBP/MW/h",
  "attribution": "Supported by National Energy SO Open Data",
  "license": "National Energy SO Open Data Licence v1.0 (https://www.neso.energy/data-portal/neso-open-licence)",
  "service": "Response",
  "product": "DCL",
  "productName": "Dynamic Containment Low",
  "participant": "UK POWER RESERVE LIMITED",
  "unit": "AFFR-1",
  "technology": "Batteries",
  "deliveryStart": "2026-10-29T19:00:00",
  "deliveryEnd": "2026-10-29T23:00:00",
  "efaBlock": null,
  "status": "Accepted",
  "tenderedMw": null,
  "acceptedMw": 18,
  "price": null,
  "clearingPrice": 4.65,
  "postcodeDistrict": "LE14",
  "recordId": "2945#||#125#||#DCL#||#219102",
  "tenderRound": null,
  "scrapedAt": "2026-10-29T12:05:45.429Z"
}
```

The same schema is used across all three markets. Newest delivery first.

### How much does it cost?

Pay per result: **$0.001 per auction-result row ($1 per 1,000)**. Filtering happens server-side, so you only pay for matching rows. Set a max charge per run and the Actor stops cleanly when it is reached.

| Result rows | Cost |
|---|---|
| 100 | $0.10 |
| 1,000 | $1.00 |
| 10,000 | $10.00 |

### Coverage

EAC unit results (NESO "EAC Auction Results by Unit", from Nov 2023, updated daily), Static FFR auction results and STOR auction results as published on the NESO Data Portal.

### Legal and data protection

Source: the [NESO Data Portal](https://www.neso.energy/data-portal) (National Energy System Operator), published under the **NESO Open Data Licence v1.0** (based on the Open Government Licence v3.0): *"You are free to: copy, publish, distribute and transmit the Information; adapt the Information; exploit the Information commercially and non-commercially for example, by combining it with other Information, or by including it in your own product or application."* Every record carries the required attribution **"Supported by National Energy SO Open Data"** and a link to the source dataset. This Actor is not affiliated with or endorsed by NESO.

The Actor uses NESO's official CKAN API only (no scraping, no login) and follows NESO's rate guidance (at most two datastore requests per minute), so multi-source runs take ~30 s per extra query.

**Organisation data only:** providers are companies/units; site postcodes are reduced to the postcode **district** (outward code).

### FAQ

- **What is an EFA block?** One of six 4-hour blocks of the electricity day (23:00–03:00 = block 1).
- **Why can a big run be slow?** NESO asks API users to make at most two datastore queries per minute, and the Actor respects that.
- **Is NESO the same as National Grid ESO?** Yes. The Electricity System Operator became the National Energy System Operator (NESO) in October 2024.
- **Can I build a clearing-price history?** Yes. Schedule a daily run with `lastDays: 1` and append the results, or set `dateFrom`/`dateTo` for a backfill.
- **Need another product or dataset?** Open an issue on the Actor page.

# Actor input Schema

## `markets` (type: `array`):

Which auction results to fetch.

## `products` (type: `array`):

Empty = all EAC products.

## `lastDays` (type: `integer`):

Delivery window ending now. Ignored if a date is set.

## `dateFrom` (type: `string`):

Optional.

## `dateTo` (type: `string`):

Optional, exclusive.

## `participantKeywords` (type: `array`):

e.g. "Zenobe", "Habitat", "Flexitricity".

## `units` (type: `array`):

Exact unit IDs.

## `technologyKeywords` (type: `array`):

e.g. "Battery", "Load Response", "Diesel".

## `acceptedOnly` (type: `boolean`):

Accepted volume only.

## `maxItems` (type: `integer`):

Stop after this many rows (0 = up to 32,000 per market). You are charged per result.

## Actor input object example

```json
{
  "markets": [
    "EAC"
  ],
  "lastDays": 7,
  "acceptedOnly": true,
  "maxItems": 1000
}
```

# Actor output Schema

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

All results in the default dataset, shown with the Overview table view by default.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("ukopendatatools/gb-balancing-services-auctions").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("ukopendatatools/gb-balancing-services-auctions").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 '{}' |
apify call ukopendatatools/gb-balancing-services-auctions --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ukopendatatools/gb-balancing-services-auctions"
        }
    }
}
```

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/gQ5lSMv0rBlsnEMHP/builds/RMwNB2eT2bziYf3xD/openapi.json
