Reference
Every endpoint, runnable
Press Send and watch the real API answer. Looking around needs no key: the calls go through a server-side proxy, capped at ten rows.
Base URL https://api.gridcapacityapi.com/v1 · Bearer auth · full documentation
Try it
The calls a Free key can make, through the proxy: at most ten rows, a 25 km radius, and nothing a paid plan gates.
/v1/capacity/nearbyFreeCapacity records around a point, nearest first, with every dimension, the methodology, both clocks, provenance and access.
Runs against the live API through a server-side proxy. No key needed, capped at ten rows. With your own key there is no cap and no allowlist.
Every operation
Rendered from the API's own OpenAPI document, so this list cannot promise a route or a parameter the API does not have.
GridCapacity APIv1.0.0 · 32 operations, rendered from /v1/openapi.json.
Meta
GET/v1/healthno keyService status
Answers without a key. Reports whether the database is reachable, the build version, and which sign-in methods this deployment offers.
- 200Success
GET/v1/plansno keyPlans, prices and entitlements
Every plan with its price in euros, quotas, limits and capabilities: the same table the API enforces. Enterprise is listed with its "from" price and `self_serve: false`.
- 200Success
GET/v1/keyThe key making this request
Its plan, everything that plan allows, and how much of this month's quota it has used. Metered like any data route, so it is also a smoke test of the whole authentication path.
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
Coverage
GET/v1/coverageno keyCoverage per country
Public and rate limited, no key. Per country: coverage status (computed from the sources, never declared), operators, sources granted and withheld, assets, series and the newest source date; plus dataset totals. Cached for a minute.
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`)
GET/v1/assets.geojsonno keyAsset points as GeoJSON
Public and rate limited, no key. Asset points only — never capacity values — at most 5,000 features; `truncated` says when more matched.
| Parameter | In | Type | Description |
|---|---|---|---|
| bbox | query | string | `min_lon,min_lat,max_lon,max_lat`, WGS84 degrees. |
| country | query | string | ISO 3166-1 alpha-2, comma list. A country with nothing published is `country_not_supported`. |
| operator | query | string | Operator slug or `op_` id, comma list. |
| asset_type | query | string | Asset type, comma list. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`)
- 404Not found (`operator_not_found`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`)
GET/v1/tiles/assets/{z}/{x}/{y}.mvtno keyAsset points as vector tiles
Public and rate limited, no key. A Mapbox vector tile (layer `assets`) of asset points with id, type, name, slug, country, operator, voltage_kv and precision; no values. At most 20,000 points per tile; `X-Feature-Limit-Reached: true` when capped.
| Parameter | In | Type | Description |
|---|---|---|---|
| z* | path | integer | Zoom. |
| x* | path | integer | Tile column. |
| y* | path | integer | Tile row (the URL ends in `.mvt`). |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`)
Catalogue
GET/v1/countriesCountries
Every country in the reference list with its computed coverage status.
| Parameter | In | Type | Description |
|---|---|---|---|
| status | query | live | partial | planned | none | Coverage status. |
| limit | query | integer | Rows per page. The maximum is set by your plan (20 / 100 / 200); asking for more is an error rather than a silent truncation. |
| cursor | query | string | Opaque cursor from `pagination.next_cursor`. Omit for the first page. Bound to the sort it was minted under. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`, `invalid_cursor`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
GET/v1/operatorsOperators
TSOs and DSOs, with their sources and asset counts. `covered` means at least one of their sources has published values we may serve.
| Parameter | In | Type | Description |
|---|---|---|---|
| country | query | string | ISO 3166-1 alpha-2. |
| type | query | TSO | DSO | TSO_DSO | joint | other | Operator type. |
| covered | query | boolean | Only covered (or only uncovered) operators. |
| limit | query | integer | Rows per page. The maximum is set by your plan (20 / 100 / 200); asking for more is an error rather than a silent truncation. |
| cursor | query | string | Opaque cursor from `pagination.next_cursor`. Omit for the first page. Bound to the sort it was minted under. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`, `invalid_cursor`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 404Not found (`country_not_supported`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
GET/v1/operators/{id}One operator
By `op_` id or slug, with its sources.
| Parameter | In | Type | Description |
|---|---|---|---|
| id* | path | string | `op_` id or slug. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 404Not found (`operator_not_found`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
GET/v1/sourcesSources
Every operator publication, registry-only ones included (health `disabled`). `rights_mode` is the effective mode, override included.
| Parameter | In | Type | Description |
|---|---|---|---|
| country | query | string | ISO 3166-1 alpha-2. |
| operator | query | string | Operator slug or `op_` id. |
| rights_mode | query | redistribution_allowed | commercial_use_with_attribution | derived_only | internal_cache_only | link_only | pending_review | blocked | Effective rights mode. |
| health | query | healthy | stale | degraded | failing | disabled | unknown | Health. |
| limit | query | integer | Rows per page. The maximum is set by your plan (20 / 100 / 200); asking for more is an error rather than a silent truncation. |
| cursor | query | string | Opaque cursor from `pagination.next_cursor`. Omit for the first page. Bound to the sort it was minted under. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`, `invalid_cursor`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 404Not found (`country_not_supported`, `operator_not_found`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
GET/v1/sources/{id}One source
The full manifest facts: methodologies, licence, rights evidence (URL, verbatim quote, date) and semantics.
| Parameter | In | Type | Description |
|---|---|---|---|
| id* | path | string | The public id. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 404Not found (`source_not_found`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
GET/v1/sources/{id}/statusSource health and freshness
Health, the last import run and the checks that held it (by name, with how many items each found at fault), and `freshness_seconds`: the age of the data, not of our last fetch.
| Parameter | In | Type | Description |
|---|---|---|---|
| id* | path | string | The public id. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 404Not found (`source_not_found`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
GET/v1/methodologies/{id}One methodology
How one source computes its numbers: basis, network state, what is included, comparability class, disclaimers.
| Parameter | In | Type | Description |
|---|---|---|---|
| id* | path | string | The public id. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 404Not found (`methodology_not_found`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
Assets
GET/v1/substationsGrid assets
Substations and other grid assets, whatever the rights of their sources (names and locations are listed; values are not here). Every asset type unless `asset_type` is given.
| Parameter | In | Type | Description |
|---|---|---|---|
| country | query | string | ISO 3166-1 alpha-2, comma list. A country with nothing published is `country_not_supported`. |
| operator | query | string | Operator slug or `op_` id, comma list. |
| source | query | string | Assets with an identity in these sources. |
| asset_type | query | string | Asset type, comma list. |
| q | query | string | Name search (substring or trigram similarity). |
| slug | query | string | Exact slug, with `country` for the site's asset pages. |
| bbox | query | string | `min_lon,min_lat,max_lon,max_lat`, WGS84 degrees. |
| lat | query | number | Latitude, WGS84. With `lng`. |
| lng | query | number | Longitude, WGS84. With `lat`. |
| radius_km | query | number | Radius around lat/lng on the asset centroid. Default 10 whenever lat/lng are given. Capped per plan (25 / 50 / 250 / 500 / 1000 km): above the cap is `plan_required`. |
| voltage_min_kv | query | number | Lowest nominal voltage, kV. |
| voltage_max_kv | query | number | Highest nominal voltage, kV. |
| has_capacity | query | boolean | Only assets with (or without) active capacity series. |
| sort | query | name | voltage | -voltage | distance | Sort order. Nulls (withheld values, unstated voltages) sort last either way. |
| limit | query | integer | Rows per page. The maximum is set by your plan (20 / 100 / 200); asking for more is an error rather than a silent truncation. |
| cursor | query | string | Opaque cursor from `pagination.next_cursor`. Omit for the first page. Bound to the sort it was minted under. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`, `invalid_cursor`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 403The plan does not include this capability or limit (`plan_required`)
- 404Not found (`country_not_supported`, `operator_not_found`, `operator_not_supported`, `source_not_found`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
GET/v1/substations/{id}One substation
The asset, its source identities, related assets and a capacity summary. A merged asset's id resolves to the asset it was merged into.
| Parameter | In | Type | Description |
|---|---|---|---|
| id* | path | string | A `sub_` id. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 404Not found (`asset_not_found`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
GET/v1/grid-assets/{id}One grid asset of any type
As `/v1/substations/{id}`, for any asset id prefix (`sub_`, `zone_`, `node_`, …).
| Parameter | In | Type | Description |
|---|---|---|---|
| id* | path | string | Any grid-asset id. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 404Not found (`asset_not_found`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
Capacity
GET/v1/substations/{id}/capacityCurrent capacity of a substation
Every current capacity record of the asset (all availability types unless filtered). `as_of` is Pro+.
| Parameter | In | Type | Description |
|---|---|---|---|
| id* | path | string | A `sub_` id. |
| direction | query | string | Direction, comma list. |
| technology | query | string | Technology, comma list. |
| availability_type | query | string | What the number counts, comma list. Search and nearby default to `available`. |
| firmness | query | string | Firmness, comma list. |
| horizon | query | string | `snapshot`, a target year (`2028`) or the operator's label (`Y+2`). |
| curtailment_max_pct | query | number | Largest acceptable curtailment band. Firm series satisfy any value; series of unknown firmness never do. |
| min_capacity_mw | query | number | On `value_mw` only: an MVA figure never satisfies it. Withheld values never satisfy any numeric filter. |
| max_capacity_mw | query | number | On `value_mw` only. |
| unit | query | string | Unit as published, comma list. Nothing is converted. |
| min_capacity | query | number | On `value` in the one unit named by `unit` (required, exactly one): `unit=MVA&min_capacity=50`. |
| max_capacity | query | number | On `value` in the one unit named by `unit`. |
| status | query | string | Categorical status, comma list (unit=status sources). |
| source | query | string | Source id, comma list. Naming only sources that withhold their values is `source_rights_restricted` (451). |
| as_of | query | string | Pro+. RFC 3339 timestamp or date (end of that day, UTC): what the latest published data said then, on our observation clock. |
| include_withheld | query | boolean | Default true: withheld records are listed without their value. false drops them. |
| sort | query | capacity | -capacity | distance | voltage | -voltage | name | source_updated_at | -source_updated_at | observed_at | -observed_at | Sort order. Nulls (withheld values, unstated voltages) sort last either way. |
| limit | query | integer | Rows per page. The maximum is set by your plan (20 / 100 / 200); asking for more is an error rather than a silent truncation. |
| cursor | query | string | Opaque cursor from `pagination.next_cursor`. Omit for the first page. Bound to the sort it was minted under. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`, `invalid_cursor`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 403The plan does not include this capability or limit (`plan_required`)
- 404Not found (`asset_not_found`, `capacity_not_available`, `source_not_found`)
- 409Conflict with the state of the data (`source_not_available`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
- 451Unavailable for legal reasons (rights) (`source_rights_restricted`)
GET/v1/substations/{id}/capacity/historyHistory of a substation's capacity
Pro+. Each series with its observations as intervals `[observed_from, observed_to)` of our observation clock, overlapping `from`..`to`.
| Parameter | In | Type | Description |
|---|---|---|---|
| id* | path | string | A `sub_` id. |
| from | query | string | RFC 3339 or date (start of day). |
| to | query | string | RFC 3339 or date (end of day, exclusive). |
| direction | query | string | Direction, comma list. |
| technology | query | string | Technology, comma list. |
| availability_type | query | string | What the number counts, comma list. Search and nearby default to `available`. |
| firmness | query | string | Firmness, comma list. |
| horizon | query | string | `snapshot`, a target year (`2028`) or the operator's label (`Y+2`). |
| limit | query | integer | Rows per page. The maximum is set by your plan (20 / 100 / 200); asking for more is an error rather than a silent truncation. |
| cursor | query | string | Opaque cursor from `pagination.next_cursor`. Omit for the first page. Bound to the sort it was minted under. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`, `invalid_cursor`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 403The plan does not include this capability or limit (`plan_required`)
- 404Not found (`asset_not_found`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
GET/v1/grid-assets/{id}/capacityCurrent capacity of any grid asset
As `/v1/substations/{id}/capacity`, for any asset type — a Dutch supply area (`zone_`), a Belgian municipality (`area_`), a node. `as_of` is Pro+.
| Parameter | In | Type | Description |
|---|---|---|---|
| id* | path | string | Any grid-asset id. |
| direction | query | string | Direction, comma list. |
| technology | query | string | Technology, comma list. |
| availability_type | query | string | What the number counts, comma list. Search and nearby default to `available`. |
| firmness | query | string | Firmness, comma list. |
| horizon | query | string | `snapshot`, a target year (`2028`) or the operator's label (`Y+2`). |
| curtailment_max_pct | query | number | Largest acceptable curtailment band. Firm series satisfy any value; series of unknown firmness never do. |
| min_capacity_mw | query | number | On `value_mw` only: an MVA figure never satisfies it. Withheld values never satisfy any numeric filter. |
| max_capacity_mw | query | number | On `value_mw` only. |
| unit | query | string | Unit as published, comma list. Nothing is converted. |
| min_capacity | query | number | On `value` in the one unit named by `unit` (required, exactly one): `unit=MVA&min_capacity=50`. |
| max_capacity | query | number | On `value` in the one unit named by `unit`. |
| status | query | string | Categorical status, comma list (unit=status sources). |
| source | query | string | Source id, comma list. Naming only sources that withhold their values is `source_rights_restricted` (451). |
| as_of | query | string | Pro+. RFC 3339 timestamp or date (end of that day, UTC): what the latest published data said then, on our observation clock. |
| include_withheld | query | boolean | Default true: withheld records are listed without their value. false drops them. |
| sort | query | capacity | -capacity | distance | voltage | -voltage | name | source_updated_at | -source_updated_at | observed_at | -observed_at | Sort order. Nulls (withheld values, unstated voltages) sort last either way. |
| limit | query | integer | Rows per page. The maximum is set by your plan (20 / 100 / 200); asking for more is an error rather than a silent truncation. |
| cursor | query | string | Opaque cursor from `pagination.next_cursor`. Omit for the first page. Bound to the sort it was minted under. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`, `invalid_cursor`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 403The plan does not include this capability or limit (`plan_required`)
- 404Not found (`asset_not_found`, `capacity_not_available`, `source_not_found`)
- 409Conflict with the state of the data (`source_not_available`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
- 451Unavailable for legal reasons (rights) (`source_rights_restricted`)
GET/v1/grid-assets/{id}/capacity/historyHistory of any grid asset's capacity
As `/v1/substations/{id}/capacity/history`, for any asset type. Pro+.
| Parameter | In | Type | Description |
|---|---|---|---|
| id* | path | string | Any grid-asset id. |
| from | query | string | RFC 3339 or date (start of day). |
| to | query | string | RFC 3339 or date (end of day, exclusive). |
| direction | query | string | Direction, comma list. |
| technology | query | string | Technology, comma list. |
| availability_type | query | string | What the number counts, comma list. Search and nearby default to `available`. |
| firmness | query | string | Firmness, comma list. |
| horizon | query | string | `snapshot`, a target year (`2028`) or the operator's label (`Y+2`). |
| limit | query | integer | Rows per page. The maximum is set by your plan (20 / 100 / 200); asking for more is an error rather than a silent truncation. |
| cursor | query | string | Opaque cursor from `pagination.next_cursor`. Omit for the first page. Bound to the sort it was minted under. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`, `invalid_cursor`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 403The plan does not include this capability or limit (`plan_required`)
- 404Not found (`asset_not_found`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
GET/v1/capacity/searchSearch capacity records
The central query. Every record carries its dimensions, methodology, freshness, provenance, access and decision context. Withheld values are listed without their number and never satisfy a numeric filter.
| Parameter | In | Type | Description |
|---|---|---|---|
| country | query | string | ISO 3166-1 alpha-2, comma list. A country with nothing published is `country_not_supported`. |
| operator | query | string | Operator slug or `op_` id, comma list. |
| source | query | string | Source id, comma list. Naming only sources that withhold their values is `source_rights_restricted` (451). |
| asset_type | query | string | Asset type, comma list. |
| voltage_min_kv | query | number | Lowest nominal voltage, kV. |
| voltage_max_kv | query | number | Highest nominal voltage, kV. |
| direction | query | string | Direction, comma list. |
| technology | query | string | Technology, comma list. |
| availability_type | query | string | What the number counts, comma list. Search and nearby default to `available`. |
| firmness | query | string | Firmness, comma list. |
| horizon | query | string | `snapshot`, a target year (`2028`) or the operator's label (`Y+2`). |
| curtailment_max_pct | query | number | Largest acceptable curtailment band. Firm series satisfy any value; series of unknown firmness never do. |
| min_capacity_mw | query | number | On `value_mw` only: an MVA figure never satisfies it. Withheld values never satisfy any numeric filter. |
| max_capacity_mw | query | number | On `value_mw` only. |
| unit | query | string | Unit as published, comma list. Nothing is converted. |
| min_capacity | query | number | On `value` in the one unit named by `unit` (required, exactly one): `unit=MVA&min_capacity=50`. |
| max_capacity | query | number | On `value` in the one unit named by `unit`. |
| status | query | string | Categorical status, comma list (unit=status sources). |
| as_of | query | string | Pro+. RFC 3339 timestamp or date (end of that day, UTC): what the latest published data said then, on our observation clock. |
| lat | query | number | Latitude, WGS84. With `lng`. |
| lng | query | number | Longitude, WGS84. With `lat`. |
| radius_km | query | number | Radius around lat/lng on the asset centroid. Default 10 whenever lat/lng are given. Capped per plan (25 / 50 / 250 / 500 / 1000 km): above the cap is `plan_required`. |
| bbox | query | string | `min_lon,min_lat,max_lon,max_lat`, WGS84 degrees. |
| fresh_after | query | string | Only records whose data is at least this recent (source_effective_at, else the source's last change). When records match but none is fresh enough: 409 `source_data_stale` with `details.newest`. |
| comparability | query | strict | best_effort | raw | `best_effort` (default) returns mixed methodology classes with a warning; `strict` answers 422 unless every record shares one class; `raw` also returns records with unknown dimensions. |
| include_withheld | query | boolean | Default true: withheld records are listed without their value. false drops them. |
| sort | query | capacity | -capacity | distance | voltage | -voltage | name | source_updated_at | -source_updated_at | observed_at | -observed_at | Sort order. Nulls (withheld values, unstated voltages) sort last either way. |
| limit | query | integer | Rows per page. The maximum is set by your plan (20 / 100 / 200); asking for more is an error rather than a silent truncation. |
| cursor | query | string | Opaque cursor from `pagination.next_cursor`. Omit for the first page. Bound to the sort it was minted under. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`, `invalid_cursor`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 403The plan does not include this capability or limit (`plan_required`)
- 404Not found (`country_not_supported`, `operator_not_found`, `operator_not_supported`, `source_not_found`)
- 409Conflict with the state of the data (`source_not_available`, `source_data_stale`)
- 422Not comparable (`capacity_semantics_not_comparable`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
- 451Unavailable for legal reasons (rights) (`source_rights_restricted`)
GET/v1/capacity/nearbyCapacity records near a point
As search, around `lat`/`lng` (required) within `radius_km` (default 10, capped per plan), sorted by distance; every asset carries `distance_km`.
| Parameter | In | Type | Description |
|---|---|---|---|
| country | query | string | ISO 3166-1 alpha-2, comma list. A country with nothing published is `country_not_supported`. |
| operator | query | string | Operator slug or `op_` id, comma list. |
| source | query | string | Source id, comma list. Naming only sources that withhold their values is `source_rights_restricted` (451). |
| asset_type | query | string | Asset type, comma list. |
| voltage_min_kv | query | number | Lowest nominal voltage, kV. |
| voltage_max_kv | query | number | Highest nominal voltage, kV. |
| direction | query | string | Direction, comma list. |
| technology | query | string | Technology, comma list. |
| availability_type | query | string | What the number counts, comma list. Search and nearby default to `available`. |
| firmness | query | string | Firmness, comma list. |
| horizon | query | string | `snapshot`, a target year (`2028`) or the operator's label (`Y+2`). |
| curtailment_max_pct | query | number | Largest acceptable curtailment band. Firm series satisfy any value; series of unknown firmness never do. |
| min_capacity_mw | query | number | On `value_mw` only: an MVA figure never satisfies it. Withheld values never satisfy any numeric filter. |
| max_capacity_mw | query | number | On `value_mw` only. |
| unit | query | string | Unit as published, comma list. Nothing is converted. |
| min_capacity | query | number | On `value` in the one unit named by `unit` (required, exactly one): `unit=MVA&min_capacity=50`. |
| max_capacity | query | number | On `value` in the one unit named by `unit`. |
| status | query | string | Categorical status, comma list (unit=status sources). |
| as_of | query | string | Pro+. RFC 3339 timestamp or date (end of that day, UTC): what the latest published data said then, on our observation clock. |
| lat | query | number | Latitude, WGS84. With `lng`. |
| lng | query | number | Longitude, WGS84. With `lat`. |
| radius_km | query | number | Radius around lat/lng on the asset centroid. Default 10 whenever lat/lng are given. Capped per plan (25 / 50 / 250 / 500 / 1000 km): above the cap is `plan_required`. |
| bbox | query | string | `min_lon,min_lat,max_lon,max_lat`, WGS84 degrees. |
| fresh_after | query | string | Only records whose data is at least this recent (source_effective_at, else the source's last change). When records match but none is fresh enough: 409 `source_data_stale` with `details.newest`. |
| comparability | query | strict | best_effort | raw | `best_effort` (default) returns mixed methodology classes with a warning; `strict` answers 422 unless every record shares one class; `raw` also returns records with unknown dimensions. |
| include_withheld | query | boolean | Default true: withheld records are listed without their value. false drops them. |
| sort | query | capacity | -capacity | distance | voltage | -voltage | name | source_updated_at | -source_updated_at | observed_at | -observed_at | Sort order. Nulls (withheld values, unstated voltages) sort last either way. |
| limit | query | integer | Rows per page. The maximum is set by your plan (20 / 100 / 200); asking for more is an error rather than a silent truncation. |
| cursor | query | string | Opaque cursor from `pagination.next_cursor`. Omit for the first page. Bound to the sort it was minted under. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`, `invalid_cursor`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 403The plan does not include this capability or limit (`plan_required`)
- 404Not found (`country_not_supported`, `operator_not_found`, `operator_not_supported`, `source_not_found`)
- 409Conflict with the state of the data (`source_not_available`, `source_data_stale`)
- 422Not comparable (`capacity_semantics_not_comparable`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
- 451Unavailable for legal reasons (rights) (`source_rights_restricted`)
GET/v1/postcodes/{country}/{postcode}Areas serving a postcode
The areas an operator says serve a postcode (the Dutch national map publishes this for every PC6), each with its current capacity records. A mapping is served only from a source whose rights grant its data; mappings from other sources are omitted and counted in `meta.warnings` (`withheld_mappings`), and a postcode only such sources map is `source_rights_restricted`.
| Parameter | In | Type | Description |
|---|---|---|---|
| country* | path | string | ISO 3166-1 alpha-2. |
| postcode* | path | string | As written; whitespace and case are ignored (`1234 ab`). |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 404Not found (`country_not_supported`, `capacity_not_available`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
- 451Unavailable for legal reasons (rights) (`source_rights_restricted`)
Changes
GET/v1/changesThe change feed
Pro+. Every added, changed, removed and restored value, oldest first. The id is the cursor: resume with `since=<last id>` (or `cursor=`). Withheld values are null.
| Parameter | In | Type | Description |
|---|---|---|---|
| since | query | string | A change id, or an RFC 3339 timestamp / date. |
| country | query | string | ISO 3166-1 alpha-2, comma list. A country with nothing published is `country_not_supported`. |
| operator | query | string | Operator slug or `op_` id, comma list. |
| source | query | string | Source id, comma list. Naming only sources that withhold their values is `source_rights_restricted` (451). |
| change_type | query | string | Comma list of added, changed, removed, restored. |
| limit | query | integer | Rows per page. The maximum is set by your plan (20 / 100 / 200); asking for more is an error rather than a silent truncation. |
| cursor | query | string | The last change id seen (`pagination.next_cursor`). |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`, `invalid_cursor`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 403The plan does not include this capability or limit (`plan_required`)
- 404Not found (`country_not_supported`, `operator_not_found`, `source_not_found`)
- 409Conflict with the state of the data (`source_not_available`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
- 451Unavailable for legal reasons (rights) (`source_rights_restricted`)
Exports
GET/v1/exportsYour exports
Business+. Newest first.
| Parameter | In | Type | Description |
|---|---|---|---|
| limit | query | integer | Rows per page. The maximum is set by your plan (20 / 100 / 200); asking for more is an error rather than a silent truncation. |
| cursor | query | string | Opaque cursor from `pagination.next_cursor`. Omit for the first page. Bound to the sort it was minted under. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`, `invalid_cursor`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 403The plan does not include this capability or limit (`plan_required`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
POST/v1/exportsCreate an export
Business+. An asynchronous job: `kind` (capacity_current | capacity_history | substations | changes), `format` (csv | jsonl | geojson — geojson for capacity_current and substations) and `filters`, the matching list route's query parameters as a JSON object. Built by the worker with the same queries and rights as the API; kept 7 days, and expired early if a source's rights change. At most 3 queued or running per account (`export_limit_exceeded`).
- 202Accepted: queued
- 400Invalid parameter or cursor (`invalid_parameter`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 403The plan does not include this capability or limit (`plan_required`)
- 404Not found (`country_not_supported`, `operator_not_found`, `source_not_found`)
- 409Conflict with the state of the data (`source_not_available`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`, `export_limit_exceeded`)
- 451Unavailable for legal reasons (rights) (`source_rights_restricted`)
GET/v1/exports/{id}Export status
Business+. `download_url` is set once it has succeeded.
| Parameter | In | Type | Description |
|---|---|---|---|
| id* | path | string | An `exp_` id. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 403The plan does not include this capability or limit (`plan_required`)
- 404Not found (`export_not_found`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
GET/v1/exports/{id}/downloadDownload an export
Business+. The file, streamed: `text/csv`, `application/x-ndjson` or `application/geo+json`. A few downloads run at once across the service; one more is `download_limit_exceeded` with `Retry-After`.
| Parameter | In | Type | Description |
|---|---|---|---|
| id* | path | string | An `exp_` id. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 403The plan does not include this capability or limit (`plan_required`)
- 404Not found (`export_not_found`)
- 409Conflict with the state of the data (`export_not_ready`)
- 410Gone (`export_expired`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`, `download_limit_exceeded`)
Webhooks
GET/v1/webhooksYour webhooks
Business+. Never includes the secret.
| Parameter | In | Type | Description |
|---|---|---|---|
| limit | query | integer | Rows per page. The maximum is set by your plan (20 / 100 / 200); asking for more is an error rather than a silent truncation. |
| cursor | query | string | Opaque cursor from `pagination.next_cursor`. Omit for the first page. Bound to the sort it was minted under. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`, `invalid_cursor`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 403The plan does not include this capability or limit (`plan_required`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
POST/v1/webhooksCreate a webhook
Business+. `url` must be https and public. Deliveries are POSTed JSON with `GridCapacity-Signature: t=<unix>,v1=<hex HMAC-SHA256 of "<t>.<body>">`. The secret is returned here once.
- 201Created
- 400Invalid parameter or cursor (`invalid_parameter`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 403The plan does not include this capability or limit (`plan_required`)
- 404Not found (`country_not_supported`, `operator_not_found`, `source_not_found`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
DELETE/v1/webhooks/{id}Delete a webhook
Business+. Pending deliveries are dropped.
| Parameter | In | Type | Description |
|---|---|---|---|
| id* | path | string | A `wh_` id. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 403The plan does not include this capability or limit (`plan_required`)
- 404Not found (`webhook_not_found`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
POST/v1/webhooks/{id}/rotateRotate a webhook secret
Business+. The new secret is returned once and signs every later delivery; the old one stops at once.
| Parameter | In | Type | Description |
|---|---|---|---|
| id* | path | string | A `wh_` id. |
- 200Success
- 400Invalid parameter or cursor (`invalid_parameter`)
- 401Missing, malformed or revoked API key (`unauthorized`)
- 403The plan does not include this capability or limit (`plan_required`)
- 404Not found (`webhook_not_found`)
- 429Rate limit or monthly quota exceeded (`rate_limit_exceeded`, `quota_exceeded`)
The contract
What is true of every endpoint, so you only have to learn it once.
One envelope
Lists return { data, pagination, meta }, one object { data, meta }. Errors return { error: { code, message, request_id, details } }. Branch on code; it will not change.
Cursor pagination
limit and cursor. Keyed on the sort value plus a tiebreaker id, so page 2,000 costs what page 1 costs.
Every field present
A value that does not apply is null, never omitted, so a row has the same keys on every page.
Provenance and rights
Every figure carries the publication it was read from, its methodology and its access status. A value the licence withholds is listed with value null.
Capabilities, not plan names
A refused call names the capability and the cheapest plan that would have answered it.
RateLimit headers
Every keyed response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset, so you can see the wall coming.