@uk-energy/carbon-intensity
v0.1.1
Published
Typed client for the GB Carbon Intensity API: national and regional intensity, forecasts, generation mix. Part of uk-energy-sdk.
Downloads
135
Maintainers
Readme
@uk-energy/carbon-intensity
Typed client for the GB Carbon Intensity API: national and regional carbon intensity (gCO2/kWh), 48-hour forecasts, and generation mix. No API key.
Carbon Intensity data © National Energy System Operator, licensed CC BY 4.0. Keep this line wherever you show the data.
Python mirror: uk_energy.carbon_intensity in the uk-energy distribution.
pnpm add @uk-energy/carbon-intensityUsage
import { CarbonIntensityClient } from "@uk-energy/carbon-intensity";
const ci = new CarbonIntensityClient();
const now = await ci.intensity.current();
// { from: "2026-10-16T19:30Z", to: "2026-10-16T20:00Z", intensity: { forecast: 125, actual: 134, index: "moderate" } }
const next48h = await ci.intensity.forward48h(new Date());
const cleanest = next48h.reduce((a, b) => (b.intensity.forecast < a.intensity.forecast ? b : a));
const manchester = await ci.regional.forPostcode("M1 1AA"); // outward code is enough
manchester.data[0].intensity.forecast; // 20
manchester.data[0].generationmix; // [{ fuel: "wind", perc: 54.9 }, ...]
const scotland = await ci.regional.forRegion(16, { from: "2026-10-15T00:00Z", span: "fw24h" });
const mix = await ci.generation.current();Every method returns the API's own JSON shape (see types.ts), unwrapped from its { data }
envelope. Field names are the API's; nothing is renamed.
Methods
| | |
| --- | --- |
| intensity.current() | current half hour |
| intensity.forDate(date, period?) | a day's periods, or one settlement period |
| intensity.at(at) | the period containing an instant |
| intensity.between(from, to) | range, max 14 days |
| intensity.forward24h(from) / forward48h / past24h | windows |
| intensity.stats(from, to, blockHours?) | min/avg/max, max 30 days |
| intensity.factors() | gCO2/kWh per generation type |
| generation.current() / between(from, to) / past24h(from) | national generation mix |
| regional.current() | all 18 regions, current half hour |
| regional.series(window) | all regions over a window |
| regional.forRegion(id, window?) | one region (ids in REGIONS) |
| regional.forPostcode(postcode, window?) | region for a postcode |
| regional.england() / scotland() / wales() | nation aggregates |
A window is { from, to } or { from, span: "fw24h" | "fw48h" | "pt24h" }. Dates are Date
or an ISO string the API accepts.
Things the API does that you should know
forDate()uses a local GB day: in BST, 15 October runs from2026-10-14T23:00Z, and settlement period 1 is 23:00Z–23:30Z. ADateis therefore formatted as its Europe/London calendar date. Clock-change days have 46 or 50 periods.- Instant and range endpoints include the period containing
from, so a 24-hour window returns 49 periods andat("…T00:00Z")returns the 23:30Z–00:00Z period. actualisnullfor periods not yet metered; regional data is forecast-only.- Errors come back as
HttpErrorwith the API's{ error: { code, message } }in.body.
Options
Everything from @uk-energy/core's HttpClientOptions except baseUrl. Defaults: 5 requests/s
(burst 10) shared across every client to this host in the process; no cache unless you pass
one, in which case the TTL is 30 minutes (the API's publication cadence).
import { MemoryCache } from "@uk-energy/core";
const ci = new CarbonIntensityClient({ cache: new MemoryCache() });Tests
Fixture-backed, no network: pnpm --filter @uk-energy/carbon-intensity test. Fixtures were
recorded on 16 Oct 2026 and live in fixtures/api.carbonintensity.org.uk/; the Python tests
replay the same files.
