# SiteVerdict — UK Grid Carbon Intensity & Best Times (`siteverdict/siteverdict-uk-energy-carbon`) Actor

48-hour carbon intensity forecasts for any GB postcode or region (NESO Carbon Intensity API), the cleanest windows to run EV charging, batch or ML jobs with CO2 saved, live generation mix and wholesale price indicators from Elexon BMRS, alerts and CSV. Free open data, no key.

- **URL**: https://apify.com/siteverdict/siteverdict-uk-energy-carbon.md
- **Developed by:** [Aman Thakran](https://apify.com/siteverdict) (community)
- **Categories:** Business, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

## SiteVerdict — UK Grid Carbon Intensity & Best Times

**Know when Great Britain's electricity is cleanest in your region over the next 48 hours, and schedule EV charging, batch jobs, ML training or heat pumps into those windows. Includes the live generation mix and wholesale price indicators from Elexon.**

Free official open data from the NESO **Carbon Intensity API** (CC BY 4.0) and **Elexon BMRS** (Insights Solution). No key, no scraping.

### What you get

- 🌍 **Location forecasts** for `national`, any GB postcode/outcode or region: the current intensity (gCO2/kWh, index *very low* to *very high*, regional fuel mix), the 48-hour min/avg/max, the cleanest half-hour, and every half-hour slot (optional).
- ⏱️ **Best windows per job**: for each job (duration, optional *must finish within N hours*, optional kWh) the top non-overlapping windows with average intensity, **% less CO2 than starting now** and than the 48 h average, and **kg CO2 saved**.
- ⚡ **Grid snapshot** (one row): national intensity and mix, latest Elexon generation by fuel (MW) with low-carbon / fossil / imports / storage shares on one documented denominator (with fuel coverage; shares are withheld rather than guessed when a domestic fuel type is missing), the last 24 h **market index price** (latest, avg, min, max, negative periods) and yesterday's **system sell price** stats.
- 🔔 **Clean-window alerts** to Slack/webhook when a job's best window is below your threshold and starts soon.
- 📄 `forecast-slots.csv` and an optional **AI scheduling brief** using your own Anthropic/OpenAI key.

### Who it is for

- **Data/ML and DevOps teams** running carbon-aware batch jobs and CI pipelines (Green Software Foundation style).
- **EV fleet and home-energy apps** picking charging windows by region.
- **Sustainability/ESG teams** reporting location-based emissions and load shifting.
- **Energy traders and analysts** wanting a quick daily fuel-mix and price readout.
- **AI agents** via the MCP tool `uk_grid_carbon`.

### Quick start

1. Locations: `national`, `PL4 7LG`, `London`, `region:16`.
2. Jobs: `[{"name":"EV charge","durationHours":4,"deadlineHours":14,"energyKwh":28}]`.
3. Run. For alerts, schedule hourly with `alertMaxIntensity` (e.g. 120 gCO2/kWh).

Try **Sample mode** first (real API responses recorded on 11 Oct 2026; no network, free).

#### Example output (sample mode: real responses recorded 11 Oct 2026 16:14 UTC, abridged)

```json
{ "recordType": "location-forecast", "location": "PL4 7LG", "regionName": "South West England",
  "current": { "forecast": 279, "index": "very high", "mix": { "gas": 70.9, "wind": 16.1, "solar": 13 } },
  "horizon": { "slots": 97, "min": 67, "avg": 283, "max": 360, "cleanestSlot": "2026-10-13T12:30Z", "lowOrVeryLowSlots": 6 },
  "jobs": [{ "name": "ML training batch (2 h)", "runNowAvgIntensity": 324,
             "bestWindows": [{ "start": "2026-10-13T11:30Z", "end": "2026-10-13T13:30Z", "avgIntensity": 73, "vsRunNowPct": 77.5, "startsInHours": 43.3 }],
             "recommendation": "Start at 2026-10-13T11:30Z (in ~43.3 h): 77.5% less CO2 than starting now.", "energyKwh": 50, "kgCo2Saved": 12.55 }] }

{ "recordType": "grid-snapshot",
  "carbon": { "forecast": 191, "actual": 190, "index": "high", "mix": { "gas": 38.1, "imports": 20.3, "nuclear": 14.7, "biomass": 11.6, "solar": 9.2, "wind": 6.1 } },
  "generation": { "totalMw": 30516, "lowCarbonPct": 30.1, "fossilPct": 36, "importsPct": 26.2, "storageMw": 980, "storagePct": 3.2, "sharesComplete": true,
                  "coverage": { "fuelsReported": 20, "fuelsExpected": 20, "missingFuels": [], "missingRequiredFuels": [] }, "negativeMw": {}, "note": null },
  "marketIndex": { "periods": 48, "latestGbpMwh": 200.74, "avgGbpMwh": 152.2, "minGbpMwh": 112.19, "maxGbpMwh": 200.74, "negativePeriods": 0 },
  "systemPrices": { "settlementDate": "2026-10-10", "avgSellGbpMwh": 82.39, "minSellGbpMwh": -13.3, "maxSellGbpMwh": 219.8 } }
```

On a windless autumn evening the best 4-hour EV window before a 16-hour deadline was simply "run now"; with a longer deadline the Actor points to the cleaner slots (the 48 h minimum here was 67 gCO2/kWh, around midday on 13 Oct).

### Pricing (pay per event)

| Event | Price | When |
|---|---|---|
| `location-forecast` | $0.01 | one location with 48 h forecast and best windows for all jobs |
| `grid-snapshot` | $0.01 | one national mix + wholesale indicators row |
| `window-alert` | $0.005 | one clean-window alert |
| `ai-brief` | $0.05 | only when your own AI key returns a brief |

Examples: 3 locations + snapshot once a day = $0.04/day ≈ **$1.20/month**. Hourly alerting for one region ≈ $0.24/day. Errors and sample mode are free.

### FAQ

**Does it cover Northern Ireland?** No. The Carbon Intensity API and BMRS cover the GB grid only.

**Are these forecasts reliable?** They are NESO's published model forecasts, refreshed every half hour; regional forecasts carry more uncertainty than national ones.

**Is the market index price my tariff?** No. MID and system prices are wholesale/imbalance indicators (£/MWh), useful for trends and negative-price periods, not retail bills.

### Limits

- 50 locations and 10 jobs per run, jobs up to 24 h, horizon 48 h.
- Elexon generation outturn is the latest 5-minute outturn point that reports the full set of fuel types (usually 10-20 minutes behind real time). It is not a settled half-hour figure and can be revised.
- Generation shares (`lowCarbonPct`, `fossilPct`, `importsPct`, `storagePct`) all use one denominator, `totalMw` = **total GB supply in that 5-minute point**: every positive domestic output (including pumped-storage discharge) plus positive interconnector imports. This matches the supply basis of the NESO Carbon Intensity generation mix in the same row, which also counts imports as a share. Exports and pumping are excluded: they show as 0 in `byFuelMw` and keep their raw negative MW in `negativeMw`.
- **Low-carbon** = nuclear + wind + hydro (NPSHYD, non-pumped) + biomass (+ solar if reported; the Elexon outturn feed does not include embedded solar). Biomass counts as low-carbon/renewable as in DESNZ Energy Trends. **Pumped storage is not counted as low-carbon or renewable**: it re-releases electricity taken from the grid earlier, so it is shown separately as `storageMw` / `storagePct` (`null` when Elexon did not report PS for that point, usually because it was pumping). Fossil = CCGT + OCGT + coal + oil; imports = all INT\* interconnectors; the rest is `OTHER`. Each % is rounded to 0.1, so the five groups may total 99.9-100.1.
- `coverage` lists the fuel types reported vs the 20 the feed can report. Interconnectors and pumped storage are often absent while exporting/pumping; that does not change the shares of supply. If a domestic fuel type (e.g. WIND, CCGT) is missing from every point in the window, `sharesComplete` is `false`, the % fields are `null` and `note` says which fuel is missing. A grid snapshot with only such incomplete generation (no carbon or market data) is not charged.

### Sources & compliance

- **Carbon Intensity API**: https://api.carbonintensity.org.uk (NESO with University of Oxford / WWF), licensed **CC BY 4.0** (https://carbonintensity.org.uk/, checked 11 Oct 2026). Attribution in every row.
- **Elexon BMRS / Insights Solution API**: https://data.elexon.co.uk/bmrs/api/v1 — BMRS data licence permits commercial use with the statement "Contains BMRS data © Elexon Limited copyright and database right \[year]" and no implied endorsement (https://www.elexon.co.uk/bsc/data/balancing-mechanism-reporting-agent/copyright-licence-bmrs-data/, checked 11 Oct 2026).
- Polite use: ~10 requests per run, ≥ 300 ms between requests, honest user agent `SiteVerdict/uk-energy-carbon (+hello@webrevenuescan.com)`.
- No personal data. Not endorsed by NESO or Elexon. Not financial or trading advice.

# Changelog

This Actor's version history is a separate document: https://apify.com/siteverdict/siteverdict-uk-energy-carbon/changelog.md

# Actor input Schema

## `locations` (type: `array`):

One per line: <code>national</code>, a GB postcode or outcode (<code>PL4 7LG</code>, <code>SW1A</code>), <code>region:13</code> or a region name (<code>London</code>, <code>South West England</code>, <code>North Scotland</code>...). Max 50.

## `jobs` (type: `array`):

Energy-heavy tasks to place in the cleanest window: <code>\[{"name":"EV charge","durationHours":4,"deadlineHours":14,"energyKwh":28}]</code>. deadlineHours = must finish within N hours; energyKwh adds kg CO2 saved.

## `windowsPerJob` (type: `integer`):

Best non-overlapping windows returned per job.

## `includeSlots` (type: `boolean`):

Adds all ~96 half-hour slots (with regional generation mix) to each location row.

## `includeGridSnapshot` (type: `boolean`):

One extra row: national intensity and mix, latest Elexon generation by fuel (MW, low-carbon %), last-24 h market index price and yesterday's system prices.

## `alertMaxIntensity` (type: `integer`):

Optional. Alerts when a job's best window averages at or below this and starts within the time below. Schedule the Actor hourly for timely alerts.

## `alertWithinHours` (type: `integer`):

Only alert when the clean window starts within this many hours.

## `webhookUrl` (type: `string`):

JSON digest of alerts. Stored encrypted, never logged.

## `slackWebhookUrl` (type: `string`):

https://hooks.slack.com/services/... Stored encrypted, never logged.

## `exportCsv` (type: `boolean`):

Save a CSV export to the run key-value store.

## `aiProvider` (type: `string`):

A short plain-English scheduling brief written by your own Anthropic or OpenAI account. Off by default.

## `aiApiKey` (type: `string`):

Your own key. Stored encrypted, never logged or output.

## `aiModel` (type: `string`):

Default: claude-sonnet-5-5 (Anthropic) or gpt-4.1-mini (OpenAI).

## `sampleMode` (type: `boolean`):

Replays real API responses recorded on 11 Oct 2026. Nothing is charged.

## Actor input object example

```json
{
  "locations": [
    "national",
    "SW1A 1AA"
  ],
  "jobs": [
    {
      "name": "EV charge",
      "durationHours": 4,
      "deadlineHours": 14,
      "energyKwh": 28
    },
    {
      "name": "2-hour batch job",
      "durationHours": 2
    }
  ],
  "windowsPerJob": 3,
  "includeSlots": true,
  "includeGridSnapshot": true,
  "alertWithinHours": 6,
  "exportCsv": true,
  "aiProvider": "none",
  "sampleMode": false
}
```

# Actor output Schema

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

No description

## `output` (type: `string`):

No description

## `files` (type: `string`):

No description

# 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 = {
    "locations": [
        "national",
        "SW1A 1AA"
    ],
    "jobs": [
        {
            "name": "EV charge",
            "durationHours": 4,
            "deadlineHours": 14,
            "energyKwh": 28
        },
        {
            "name": "2-hour batch job",
            "durationHours": 2
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("siteverdict/siteverdict-uk-energy-carbon").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 = {
    "locations": [
        "national",
        "SW1A 1AA",
    ],
    "jobs": [
        {
            "name": "EV charge",
            "durationHours": 4,
            "deadlineHours": 14,
            "energyKwh": 28,
        },
        {
            "name": "2-hour batch job",
            "durationHours": 2,
        },
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("siteverdict/siteverdict-uk-energy-carbon").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 '{
  "locations": [
    "national",
    "SW1A 1AA"
  ],
  "jobs": [
    {
      "name": "EV charge",
      "durationHours": 4,
      "deadlineHours": 14,
      "energyKwh": 28
    },
    {
      "name": "2-hour batch job",
      "durationHours": 2
    }
  ]
}' |
apify call siteverdict/siteverdict-uk-energy-carbon --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,siteverdict/siteverdict-uk-energy-carbon"
        }
    }
}
```

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/9Cq2U5ktaauPpSEt9/builds/hT2HitkbQrfsQ84gy/openapi.json
