# Reporting & settlement

> aFRR dispatch events and performance timeline for an asset, wholesale schedule dispatch events, settlement over a UTC range and the quality gate detail behind it.

API reference

aFRR dispatch events and performance timeline for an asset, wholesale schedule dispatch events, settlement over a UTC range and the quality gate detail behind it.

8 endpoints

· GET · /v1/assets/{asset\_id}/reports/afrr/dispatches

### List aFRR dispatch events for an asset

report.read

Return aFRR dispatch events for this asset within the requested time window.

Each event represents a single dispatcher instruction sent to the asset during a TSO pool activation. Use `outcome` and `filter_reason` to identify issues:

-   `outcome` is `None` when the dispatch was delivered successfully.
-   `filter_reason` is set when the dispatcher skipped the asset.

Defaults to the last 24 hours; maximum window is 90 days.

Path parameters

asset\_id · REQUIRED

string · The ID of the asset

Query parameters

start\_time

string<date-time> · Start time for filtering results

end\_time

string<date-time> · End time for filtering results

limit

integer · default 100

offset

integer · default 0

Example value

cURL:

```bash
curl ·   · "https://api.ebx.energy/v1/assets/DE_BESS_01/reports/afrr/dispatches" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

r = httpx.get(
     · "https://api.ebx.energy/v1/assets/DE_BESS_01/reports/afrr/dispatches" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/assets/DE_BESS_01/reports/afrr/dispatches" · , ·   · { · 
   · method · : ·   · "GET" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
   · }, · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "dispatches" · : ·   · [ · 
     · { · 
       · "event_id" · : ·   · "<string>" · , · 
       · "activation_id" · : ·   · "<string>" · , · 
       · "request_id" · : ·   · "<string>" · , · 
       · "asset_id" · : ·   · "<string>" · , · 
       · "created_at_utc" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "planned_set_power" · : ·   · 0 · , · 
       · "set_power" · : ·   · 0 · , · 
       · "accepted" · : ·   · 0 · , · 
       · "outcome" · : ·   · "<string>" · , · 
       · "filter_reason" · : ·   · "<string>" · , · 
       · "filter_details" · : ·   · "<string>" · , · 
       · "dispatch_category" · : ·   · "<string>" · , · 
       · "dispatch_slot_utc" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "energy_price" · : ·   · 0 · , · 
       · "capacity_price" · : ·   · 0 · 
     · } · 
   · ], · 
   · "total" · : ·   · 0 · , · 
   · "limit" · : ·   · 0 · , · 
   · "offset" · : ·   · 0 · 
 · }
```

Can raise

-   401 · no valid token
-   403 · scope missing
-   404 · unknown or not visible
-   422 · validation failed
-   429 · rate limited

[ALL CODES →](https://docs.ebx.energy/reference/errors.md)

 · GET · /v1/assets/{asset\_id}/reports/afrr/performance

### aFRR performance timeline for an asset

report.read

Return aggregated aFRR dispatch performance metrics for this asset.

Buckets dispatch events by `granularity` (fifteen\_minutes | hourly | daily). `fill_rate_pct` = accepted / set\_power × 100 and is the primary health indicator. A high `filtered_count` relative to `dispatch_count` indicates the asset is regularly skipped.

Defaults to the last 24 hours; maximum window is 90 days.

Path parameters

asset\_id · REQUIRED

string · The ID of the asset

Query parameters

start\_time

string<date-time> · Start time for filtering results

end\_time

string<date-time> · End time for filtering results

granularity

enum · `fifteen_minutes` · `hourly` · `daily`

Example value

cURL:

```bash
curl ·   · "https://api.ebx.energy/v1/assets/DE_BESS_01/reports/afrr/performance" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

r = httpx.get(
     · "https://api.ebx.energy/v1/assets/DE_BESS_01/reports/afrr/performance" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/assets/DE_BESS_01/reports/afrr/performance" · , ·   · { · 
   · method · : ·   · "GET" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
   · }, · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "asset_id" · : ·   · "<string>" · , · 
   · "granularity" · : ·   · "fifteen_minutes" · , · 
   · "periods" · : ·   · [ · 
     · { · 
       · "period_start" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "granularity" · : ·   · "fifteen_minutes" · , · 
       · "dispatch_count" · : ·   · 0 · , · 
       · "dispatched_count" · : ·   · 0 · , · 
       · "filtered_count" · : ·   · 0 · , · 
       · "total_set_power" · : ·   · 0 · , · 
       · "total_accepted" · : ·   · 0 · , · 
       · "fill_rate_pct" · : ·   · 0 · 
     · } · 
   · ] · 
 · }
```

Can raise

-   401 · no valid token
-   403 · scope missing
-   404 · unknown or not visible
-   422 · validation failed
-   429 · rate limited

[ALL CODES →](https://docs.ebx.energy/reference/errors.md)· GET · /v1/assets/{asset\_id}/reports/schedule/dispatches

### List wholesale schedule dispatch events for an asset

report.read

Return wholesale schedule dispatch events for `asset_id` in `[start_time, end_time)`.

Both bounds must be aligned to 15-minute UTC boundaries. The window must be at most **1 hour** wide; longer ranges should be fetched as multiple requests.

Each event reports the `set_power_mw` requested and the `effective_set_power_mw` actually dispatched, plus a derived `status`:

-   `full` — dispatched at the requested setpoint.
-   `clipped` — dispatched at a reduced magnitude due to regulatory headroom limits.
-   `rejected` — not dispatched because the asset was unavailable or an immediate dispatch was overriding the wholesale schedule.
-   `failed` — not dispatched because of an internal dispatcher error.
-   `unknown` — forward-compatibility fallback for any new status this client version doesn't recognise; treat as opaque.

`message` carries a free-form diagnostic from the dispatcher: the clip reason for `clipped` rows, the rejection reason for `rejected` rows, the internal error for `failed` rows. `None` for `full`. `outcome` is the raw dispatcher outcome string ("success", "rejected", "error", ...).

`set_time_utc` is the customer-supplied UTC moment the setpoint was supposed to fire; `created_at_utc` is when the dispatcher actually acted on it. They typically coincide within milliseconds for executed schedules. `set_time_utc` may be null for historical rows emitted before the field was added.

**Ingestion delay**: events become queryable through this endpoint within roughly **5 minutes** of being emitted by the dispatcher.

Path parameters

asset\_id · REQUIRED

string · The ID of the asset

Query parameters

start\_time · REQUIRED

string<date-time> · 15-min aligned UTC start of the window (inclusive)

end\_time · REQUIRED

string<date-time> · 15-min aligned UTC end of the window (exclusive)

Example value

cURL:

```bash
curl ·   · "https://api.ebx.energy/v1/assets/DE_BESS_01/reports/schedule/dispatches?start_time=2026-05-18T10:00:00Z&end_time=2026-05-18T11:00:00Z" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

r = httpx.get(
     · "https://api.ebx.energy/v1/assets/DE_BESS_01/reports/schedule/dispatches?start_time=2026-05-18T10:00:00Z&end_time=2026-05-18T11:00:00Z" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/assets/DE_BESS_01/reports/schedule/dispatches?start_time=2026-05-18T10:00:00Z&end_time=2026-05-18T11:00:00Z" · , ·   · { · 
   · method · : ·   · "GET" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
   · }, · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "dispatches" · : ·   · [ · 
     · { · 
       · "event_id" · : ·   · "<string>" · , · 
       · "request_id" · : ·   · "<string>" · , · 
       · "source_id" · : ·   · "<string>" · , · 
       · "asset_id" · : ·   · "<string>" · , · 
       · "created_at_utc" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "set_time_utc" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "status" · : ·   · "full" · , · 
       · "set_power_mw" · : ·   · 0 · , · 
       · "effective_set_power_mw" · : ·   · 0 · , · 
       · "outcome" · : ·   · "<string>" · , · 
       · "message" · : ·   · "<string>" · 
     · } · 
   · ] · 
 · }
```

Can raise

-   401 · no valid token
-   403 · scope missing
-   404 · unknown or not visible
-   422 · validation failed
-   429 · rate limited

[ALL CODES →](https://docs.ebx.energy/reference/errors.md)

· GET · /v1/balancing-groups/afrr/schedules

### Get day-after aFRR balancing-group schedules for a Berlin delivery day

report.read

Return the day-after aFRR balancing-group schedule volumes for one Berlin delivery day.

EBX nominates 15-minute values derived from assigned assets' afrr\_power\_actual telemetry. Both customer and EBX nominate these same values per TSO zone. TSO reconciliation is separate and never scales these customer values.

The response carries one entry per TSO zone with owned or managed assets. For owner-only views, aggregate\_scope is asset\_only: headers and zone periods are absent, but your own asset nomination series remain available. Otherwise:

-   zone `periods` — **authoritative**: exactly the values EBX nominates, split by the volume sign convention into `volume_pos_mw` (positive aFRR, asset discharge; Verkauf series EBX BK → customer BK) and `volume_neg_mw` (negative aFRR, asset charge; Kauf series customer BK → EBX BK) magnitudes;
-   `assets[]` — informational per-asset disaggregation for imbalance tracking; nominations happen only at zone level, so the per-asset sum is not the contract. `asset_ids` narrows only this list (and which zones appear) — zone `periods` always cover **all** your assets in the zone and match the nomination file regardless of any filter;
-   `nomination_pos` / `nomination_neg` — the header metadata of the two nomination-file series.

`delivery_day` is a Europe/Berlin calendar day; `expected_period_count` is 96 (92 on the spring-forward day, 100 on the fall-back day) and period instants are ISO-8601 UTC. Requesting today or a future day (Berlin) returns 400 — day-after data cannot exist yet.

Periods with no published data are **omitted** (`periods: []` means nothing published, `"0"` means EBX nominated 0 MW). Only successfully exchanged revisions are visible; regeneration alone does not publish.

Query parameters

delivery\_day · REQUIRED

string<date> · The Europe/Berlin delivery day; must be a completed day (before today, Berlin time)

organization\_id

string · Organization to view; must be an organization you are authorized to access. Required for multi-organization callers

tso

enum · `50HZ` · `TNNT` · `AMP` · `TNBW` · Optional TSO zone filter; omit for all zones with in-scope assets

asset\_ids

string · Owned or nomination-managed asset ids; omit for all eligible assets. Filters asset presentation and zones, never the caller's BG aggregate

Example value

cURL:

```bash
curl ·   · "https://api.ebx.energy/v1/balancing-groups/afrr/schedules?delivery_day=2026-07-29" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

r = httpx.get(
     · "https://api.ebx.energy/v1/balancing-groups/afrr/schedules?delivery_day=2026-07-29" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/balancing-groups/afrr/schedules?delivery_day=2026-07-29" · , ·   · { · 
   · method · : ·   · "GET" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
   · }, · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "delivery_day" · : ·   · "2026-07-29" · , · 
   · "day_start" · : ·   · "2026-09-10T13:30:00Z" · , · 
   · "day_end" · : ·   · "2026-09-10T13:30:00Z" · , · 
   · "expected_period_count" · : ·   · 96 · , · 
   · "zones" · : ·   · [ · 
     · { · 
       · "tso" · : ·   · "50HZ" · , · 
       · "aggregate_scope" · : ·   · "balancing_group" · , · 
       · "control_area_eic" · : ·   · "10YDE-VE-------2" · , · 
       · "nomination_pos" · : ·   · { · 
         · "data_exchange_reference" · : ·   · "EBX-Entrix_aFRR_50Hertz_Verkauf_MW" · , · 
         · "source_control_area_eic" · : ·   · "10YDE-VE-------2" · , · 
         · "target_control_area_eic" · : ·   · "10YDE-VE-------2" · , · 
         · "source_balancing_group_eic" · : ·   · "11Y0-0000-3610-H" · , · 
         · "target_balancing_group_eic" · : ·   · "11X0-0000-0685-6" · , · 
         · "unit" · : ·   · "MW" · 
       · }, · 
       · "nomination_neg" · : ·   · { · 
         · "data_exchange_reference" · : ·   · "EBX-Entrix_aFRR_50Hertz_Verkauf_MW" · , · 
         · "source_control_area_eic" · : ·   · "10YDE-VE-------2" · , · 
         · "target_control_area_eic" · : ·   · "10YDE-VE-------2" · , · 
         · "source_balancing_group_eic" · : ·   · "11Y0-0000-3610-H" · , · 
         · "target_balancing_group_eic" · : ·   · "11X0-0000-0685-6" · , · 
         · "unit" · : ·   · "MW" · 
       · }, · 
       · "periods" · : ·   · [ · 
         · { · 
           · "period_start" · : ·   · "2026-09-10T13:30:00Z" · , · 
           · "volume_pos_mw" · : ·   · "1.25" · , · 
           · "volume_neg_mw" · : ·   · "0" · 
         · } · 
       · ], · 
       · "assets" · : ·   · [ · 
         · { · 
           · "asset_id" · : ·   · "DE_50HZ_WEM_PAS_1" · , · 
           · "balancing_group_responsible_org_id" · : ·   · "<string>" · , · 
           · "periods" · : ·   · [ · 
             · { · 
               · "period_start" · : ·   · "2026-09-10T13:30:00Z" · , · 
               · "volume_pos_mw" · : ·   · "1.25" · , · 
               · "volume_neg_mw" · : ·   · "0" · 
             · } · 
           · ] · 
         · } · 
       · ] · 
     · } · 
   · ] · 
 · }
```

Can raise

-   401 · no valid token
-   403 · scope missing
-   422 · validation failed
-   429 · rate limited

[ALL CODES →](https://docs.ebx.energy/reference/errors.md)

· GET · /v1/balancing-groups/afrr/schedules/file

### Download EBX's aFRR balancing-group nomination file (CSV)

report.read

Download the nomination file EBX exchanges for one (zone, direction) series.

The file reproduces exactly what EBX nominates against your balancing group for the requested Berlin delivery day — use it to submit or verify the identical values on your side (any mismatch raises an ANO):

| Row | Content |
| --- | --- |
| 1–5 | `Datenaustauschreferenz`, `Regelzone von/an`, `Bilanzkreis von/an` |
| 6 | `Einheit;MW` |
| 7+ | one row per quarter-hour: Berlin-local `DD.MM.YYYY HH:MM` + MW value |

Format: semicolon-delimited, UTF-8 with BOM, decimal comma. On the fall-back DST day the local labels 02:00–02:45 appear twice (100 rows); the spring-forward day has 92 rows.

`direction=pos` is the Verkauf series (positive aFRR, asset discharge, EBX BK → customer BK), `direction=neg` the Kauf series (negative aFRR, asset charge, customer BK → EBX BK).

Requesting today or a future day (Berlin) returns 400 — day-after data cannot exist yet. A zone in which your organisation manages no nominations returns 404. Cells without published values stay empty — an empty cell means "no value available", never "0 MW".

Query parameters

delivery\_day · REQUIRED

string<date> · The Europe/Berlin delivery day; must be a completed day (before today, Berlin time)

organization\_id

string · Organization to view; must be an organization you are authorized to access. Required for multi-organization callers

tso · REQUIRED

enum · `50HZ` · `TNNT` · `AMP` · `TNBW` · The TSO zone the nomination file covers

direction · REQUIRED

enum · `pos` · `neg` · Series direction: 'pos' (positive aFRR / asset discharge, Verkauf series EBX BK -> customer BK) or 'neg' (negative aFRR / asset charge, Kauf series customer BK -> EBX BK)

Example value

cURL:

```bash
curl ·   · "https://api.ebx.energy/v1/balancing-groups/afrr/schedules/file?delivery_day=2026-07-29&tso=50HZ&direction=pos" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

r = httpx.get(
     · "https://api.ebx.energy/v1/balancing-groups/afrr/schedules/file?delivery_day=2026-07-29&tso=50HZ&direction=pos" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
)
print(r.text)
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/balancing-groups/afrr/schedules/file?delivery_day=2026-07-29&tso=50HZ&direction=pos" · , ·   · { · 
   · method · : ·   · "GET" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
   · }, · 
 · } · );
 · const ·  data =  · await ·  res.text();
```

Example response · 200

```json
"<string>"
```

Can raise

-   401 · no valid token
-   403 · scope missing
-   422 · validation failed
-   429 · rate limited

[ALL CODES →](https://docs.ebx.energy/reference/errors.md)

· GET · /v1/settlements

### Get settlement over a UTC range

invoice.read

Return settlement for the caller's organisation over `[start, end)`.

The response is one envelope: organisation-level per-product totals plus an `assets[]` array, each asset carrying its own totals and 15-minute `blocks`. Every product key is always present; non-applicable components are zero-valued.

Blocks appear only once the underlying data has been published and settled — intervals with no settlement data yet are **omitted** (an in-scope asset with no data has `blocks: []`). Each block's `processed_at` bumps whenever its values are recomputed; an unchanged `processed_at` means byte-identical data.

`status` selects exactly one of the disjoint PRELIMINARY / FINAL sets — to assemble an in-progress month, query both and merge on `block_start`.

Values are preliminary or final per each block's `status`; only `FINAL` is settled. The legal invoice is not issued through this API.

Query parameters

start · REQUIRED

string<date-time> · Range start (inclusive), UTC, 15-min aligned

end · REQUIRED

string<date-time> · Range end (exclusive), UTC, 15-min aligned

status · REQUIRED

enum · `PRELIMINARY` · `FINAL` · Settlement state filter: 'preliminary' or 'final' (case-insensitive)

asset\_ids

string · Comma-separated asset ids; omit for all org assets

Example value

cURL:

```bash
curl ·   · "https://api.ebx.energy/v1/settlements?start=2025-01-01T00:00:00Z&end=2025-02-01T00:00:00Z&status=preliminary" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

r = httpx.get(
     · "https://api.ebx.energy/v1/settlements?start=2025-01-01T00:00:00Z&end=2025-02-01T00:00:00Z&status=preliminary" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/settlements?start=2025-01-01T00:00:00Z&end=2025-02-01T00:00:00Z&status=preliminary" · , ·   · { · 
   · method · : ·   · "GET" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
   · }, · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "fcr" · : ·   · { · 
     · "revenue_total" · : ·   · "12.50" · , · 
     · "backup_fee_total" · : ·   · "0.00" · , · 
     · "penalty_total" · : ·   · "0.00" · 
   · }, · 
   · "fcr_backup" · : ·   · { · 
     · "revenue_total" · : ·   · "12.50" · , · 
     · "penalty_total" · : ·   · "0.00" · 
   · }, · 
   · "afrrc_pos_4h" · : ·   · { · 
     · "revenue_total" · : ·   · "12.50" · , · 
     · "backup_fee_total" · : ·   · "0.00" · , · 
     · "penalty_total" · : ·   · "0.00" · 
   · }, · 
   · "afrrc_neg_4h" · : ·   · { · 
     · "revenue_total" · : ·   · "12.50" · , · 
     · "backup_fee_total" · : ·   · "0.00" · , · 
     · "penalty_total" · : ·   · "0.00" · 
   · }, · 
   · "afrrc_pos_15min" · : ·   · { · 
     · "revenue_total" · : ·   · "12.50" · , · 
     · "backup_fee_total" · : ·   · "0.00" · , · 
     · "penalty_total" · : ·   · "0.00" · 
   · }, · 
   · "afrrc_neg_15min" · : ·   · { · 
     · "revenue_total" · : ·   · "12.50" · , · 
     · "backup_fee_total" · : ·   · "0.00" · , · 
     · "penalty_total" · : ·   · "0.00" · 
   · }, · 
   · "afrre_pos" · : ·   · { · 
     · "revenue_total" · : ·   · "12.50" · , · 
     · "backup_fee_total" · : ·   · "0.00" · , · 
     · "penalty_total" · : ·   · "0.00" · 
   · }, · 
   · "afrre_pos_backup" · : ·   · { · 
     · "revenue_total" · : ·   · "12.50" · , · 
     · "penalty_total" · : ·   · "0.00" · 
   · }, · 
   · "afrre_neg" · : ·   · { · 
     · "revenue_total" · : ·   · "12.50" · , · 
     · "backup_fee_total" · : ·   · "0.00" · , · 
     · "penalty_total" · : ·   · "0.00" · 
   · }, · 
   · "afrre_neg_backup" · : ·   · { · 
     · "revenue_total" · : ·   · "12.50" · , · 
     · "penalty_total" · : ·   · "0.00" · 
   · }, · 
   · "start" · : ·   · "2026-09-10T13:30:00Z" · , · 
   · "end" · : ·   · "2026-09-10T13:30:00Z" · , · 
   · "currency" · : ·   · "EUR" · , · 
   · "assets" · : ·   · [ · 
     · { · 
       · "fcr" · : ·   · { · 
         · "revenue_total" · : ·   · "12.50" · , · 
         · "backup_fee_total" · : ·   · "0.00" · , · 
         · "penalty_total" · : ·   · "0.00" · 
       · }, · 
       · "fcr_backup" · : ·   · { · 
         · "revenue_total" · : ·   · "12.50" · , · 
         · "penalty_total" · : ·   · "0.00" · 
       · }, · 
       · "afrrc_pos_4h" · : ·   · { · 
         · "revenue_total" · : ·   · "12.50" · , · 
         · "backup_fee_total" · : ·   · "0.00" · , · 
         · "penalty_total" · : ·   · "0.00" · 
       · }, · 
       · "afrrc_neg_4h" · : ·   · { · 
         · "revenue_total" · : ·   · "12.50" · , · 
         · "backup_fee_total" · : ·   · "0.00" · , · 
         · "penalty_total" · : ·   · "0.00" · 
       · }, · 
       · "afrrc_pos_15min" · : ·   · { · 
         · "revenue_total" · : ·   · "12.50" · , · 
         · "backup_fee_total" · : ·   · "0.00" · , · 
         · "penalty_total" · : ·   · "0.00" · 
       · }, · 
       · "afrrc_neg_15min" · : ·   · { · 
         · "revenue_total" · : ·   · "12.50" · , · 
         · "backup_fee_total" · : ·   · "0.00" · , · 
         · "penalty_total" · : ·   · "0.00" · 
       · }, · 
       · "afrre_pos" · : ·   · { · 
         · "revenue_total" · : ·   · "12.50" · , · 
         · "backup_fee_total" · : ·   · "0.00" · , · 
         · "penalty_total" · : ·   · "0.00" · 
       · }, · 
       · "afrre_pos_backup" · : ·   · { · 
         · "revenue_total" · : ·   · "12.50" · , · 
         · "penalty_total" · : ·   · "0.00" · 
       · }, · 
       · "afrre_neg" · : ·   · { · 
         · "revenue_total" · : ·   · "12.50" · , · 
         · "backup_fee_total" · : ·   · "0.00" · , · 
         · "penalty_total" · : ·   · "0.00" · 
       · }, · 
       · "afrre_neg_backup" · : ·   · { · 
         · "revenue_total" · : ·   · "12.50" · , · 
         · "penalty_total" · : ·   · "0.00" · 
       · }, · 
       · "asset_id" · : ·   · "<string>" · , · 
       · "blocks" · : ·   · [ · 
         · { · 
           · "block_start" · : ·   · "2026-09-10T13:30:00Z" · , · 
           · "block_end" · : ·   · "2026-09-10T13:30:00Z" · , · 
           · "status" · : ·   · "PRELIMINARY" · , · 
           · "processed_at" · : ·   · "2026-09-10T13:30:00Z" · , · 
           · "fcr" · : ·   · { · 
             · "revenue" · : ·   · { · 
               · "capacity_mw" · : ·   · "1.00" · , · 
               · "price_per_mw" · : ·   · "12.50" · , · 
               · "total" · : ·   · "12.50" · 
             · }, · 
             · "backup_fee" · : ·   · { · 
               · "backup_volume" · : ·   · "0.00" · , · 
               · "volume_unit" · : ·   · "MW" · , · 
               · "duration_seconds" · : ·   · 0 · , · 
               · "price_per_unit_second" · : ·   · "0.00" · , · 
               · "total" · : ·   · "0.00" · 
             · }, · 
             · "penalty" · : ·   · { · 
               · "penalized_volume" · : ·   · "0.00" · , · 
               · "volume_unit" · : ·   · "MWh" · , · 
               · "total" · : ·   · "0.00" · 
             · } · 
           · }, · 
           · "fcr_backup" · : ·   · { · 
             · "revenue" · : ·   · { · 
               · "capacity_mw" · : ·   · "1.00" · , · 
               · "price_per_mw" · : ·   · "12.50" · , · 
               · "total" · : ·   · "12.50" · 
             · }, · 
             · "penalty" · : ·   · { · 
               · "penalized_volume" · : ·   · "0.00" · , · 
               · "volume_unit" · : ·   · "MWh" · , · 
               · "total" · : ·   · "0.00" · 
             · } · 
           · }, · 
           · "afrrc_pos_4h" · : ·   · { · 
             · "revenue" · : ·   · { · 
               · "capacity_mw" · : ·   · "1.00" · , · 
               · "price_per_mw" · : ·   · "12.50" · , · 
               · "total" · : ·   · "12.50" · 
             · }, · 
             · "backup_fee" · : ·   · { · 
               · "backup_volume" · : ·   · "0.00" · , · 
               · "volume_unit" · : ·   · "MW" · , · 
               · "duration_seconds" · : ·   · 0 · , · 
               · "price_per_unit_second" · : ·   · "0.00" · , · 
               · "total" · : ·   · "0.00" · 
             · }, · 
             · "penalty" · : ·   · { · 
               · "penalized_volume" · : ·   · "0.00" · , · 
               · "volume_unit" · : ·   · "MWh" · , · 
               · "total" · : ·   · "0.00" · 
             · } · 
           · }, · 
           · "afrrc_neg_4h" · : ·   · { · 
             · "revenue" · : ·   · { · 
               · "capacity_mw" · : ·   · "1.00" · , · 
               · "price_per_mw" · : ·   · "12.50" · , · 
               · "total" · : ·   · "12.50" · 
             · }, · 
             · "backup_fee" · : ·   · { · 
               · "backup_volume" · : ·   · "0.00" · , · 
               · "volume_unit" · : ·   · "MW" · , · 
               · "duration_seconds" · : ·   · 0 · , · 
               · "price_per_unit_second" · : ·   · "0.00" · , · 
               · "total" · : ·   · "0.00" · 
             · }, · 
             · "penalty" · : ·   · { · 
               · "penalized_volume" · : ·   · "0.00" · , · 
               · "volume_unit" · : ·   · "MWh" · , · 
               · "total" · : ·   · "0.00" · 
             · } · 
           · }, · 
           · "afrrc_pos_15min" · : ·   · { · 
             · "revenue" · : ·   · { · 
               · "capacity_mw" · : ·   · "1.00" · , · 
               · "price_per_mw" · : ·   · "12.50" · , · 
               · "total" · : ·   · "12.50" · 
             · }, · 
             · "backup_fee" · : ·   · { · 
               · "backup_volume" · : ·   · "0.00" · , · 
               · "volume_unit" · : ·   · "MW" · , · 
               · "duration_seconds" · : ·   · 0 · , · 
               · "price_per_unit_second" · : ·   · "0.00" · , · 
               · "total" · : ·   · "0.00" · 
             · }, · 
             · "penalty" · : ·   · { · 
               · "penalized_volume" · : ·   · "0.00" · , · 
               · "volume_unit" · : ·   · "MWh" · , · 
               · "total" · : ·   · "0.00" · 
             · } · 
           · }, · 
           · "afrrc_neg_15min" · : ·   · { · 
             · "revenue" · : ·   · { · 
               · "capacity_mw" · : ·   · "1.00" · , · 
               · "price_per_mw" · : ·   · "12.50" · , · 
               · "total" · : ·   · "12.50" · 
             · }, · 
             · "backup_fee" · : ·   · { · 
               · "backup_volume" · : ·   · "0.00" · , · 
               · "volume_unit" · : ·   · "MW" · , · 
               · "duration_seconds" · : ·   · 0 · , · 
               · "price_per_unit_second" · : ·   · "0.00" · , · 
               · "total" · : ·   · "0.00" · 
             · }, · 
             · "penalty" · : ·   · { · 
               · "penalized_volume" · : ·   · "0.00" · , · 
               · "volume_unit" · : ·   · "MWh" · , · 
               · "total" · : ·   · "0.00" · 
             · } · 
           · }, · 
           · "afrre_pos" · : ·   · { · 
             · "revenue" · : ·   · { · 
               · "energy_mwh" · : ·   · "0.25" · , · 
               · "price_per_mwh" · : ·   · "17.00" · , · 
               · "total" · : ·   · "4.25" · 
             · }, · 
             · "backup_fee" · : ·   · { · 
               · "backup_volume" · : ·   · "0.00" · , · 
               · "volume_unit" · : ·   · "MW" · , · 
               · "duration_seconds" · : ·   · 0 · , · 
               · "price_per_unit_second" · : ·   · "0.00" · , · 
               · "total" · : ·   · "0.00" · 
             · }, · 
             · "penalty" · : ·   · { · 
               · "penalized_volume" · : ·   · "0.00" · , · 
               · "volume_unit" · : ·   · "MWh" · , · 
               · "total" · : ·   · "0.00" · 
             · } · 
           · }, · 
           · "afrre_pos_backup" · : ·   · { · 
             · "revenue" · : ·   · { · 
               · "energy_mwh" · : ·   · "0.25" · , · 
               · "price_per_mwh" · : ·   · "17.00" · , · 
               · "total" · : ·   · "4.25" · 
             · }, · 
             · "penalty" · : ·   · { · 
               · "penalized_volume" · : ·   · "0.00" · , · 
               · "volume_unit" · : ·   · "MWh" · , · 
               · "total" · : ·   · "0.00" · 
             · } · 
           · }, · 
           · "afrre_neg" · : ·   · { · 
             · "revenue" · : ·   · { · 
               · "energy_mwh" · : ·   · "0.25" · , · 
               · "price_per_mwh" · : ·   · "17.00" · , · 
               · "total" · : ·   · "4.25" · 
             · }, · 
             · "backup_fee" · : ·   · { · 
               · "backup_volume" · : ·   · "0.00" · , · 
               · "volume_unit" · : ·   · "MW" · , · 
               · "duration_seconds" · : ·   · 0 · , · 
               · "price_per_unit_second" · : ·   · "0.00" · , · 
               · "total" · : ·   · "0.00" · 
             · }, · 
             · "penalty" · : ·   · { · 
               · "penalized_volume" · : ·   · "0.00" · , · 
               · "volume_unit" · : ·   · "MWh" · , · 
               · "total" · : ·   · "0.00" · 
             · } · 
           · }, · 
           · "afrre_neg_backup" · : ·   · { · 
             · "revenue" · : ·   · { · 
               · "energy_mwh" · : ·   · "0.25" · , · 
               · "price_per_mwh" · : ·   · "17.00" · , · 
               · "total" · : ·   · "4.25" · 
             · }, · 
             · "penalty" · : ·   · { · 
               · "penalized_volume" · : ·   · "0.00" · , · 
               · "volume_unit" · : ·   · "MWh" · , · 
               · "total" · : ·   · "0.00" · 
             · } · 
           · } · 
         · } · 
       · ] · 
     · } · 
   · ] · 
 · }
```

Can raise

-   401 · no valid token
-   403 · scope missing
-   422 · validation failed
-   429 · rate limited

[ALL CODES →](https://docs.ebx.energy/reference/errors.md)

· GET · /v1/settlements/quality

### Quality-gate detail and breach episodes behind the settlement

invoice.read

Return per-block quality-gate detail and quality-break episodes over `[start, end)`.

`gated_energy_mwh` (eligible − paid) is exactly the energy the EBX quality gate withheld from the figures served by `/v1/settlements`; the episodes list explains each withholding (breach kind, setpoint context, Degraded window, P10 baseline). Blocks with no data are omitted; an asset with no data returns empty `blocks` and `episodes`.

Query parameters

start · REQUIRED

string<date-time> · Range start (inclusive), UTC, 15-min aligned

end · REQUIRED

string<date-time> · Range end (exclusive), UTC, 15-min aligned

status · REQUIRED

enum · `PRELIMINARY` · `FINAL` · Settlement state filter: 'preliminary' or 'final' (case-insensitive)

asset\_ids

string · Comma-separated asset ids; omit for all org assets

Example value

cURL:

```bash
curl ·   · "https://api.ebx.energy/v1/settlements/quality?start=2025-01-01T00:00:00Z&end=2025-02-01T00:00:00Z&status=preliminary" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

r = httpx.get(
     · "https://api.ebx.energy/v1/settlements/quality?start=2025-01-01T00:00:00Z&end=2025-02-01T00:00:00Z&status=preliminary" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/settlements/quality?start=2025-01-01T00:00:00Z&end=2025-02-01T00:00:00Z&status=preliminary" · , ·   · { · 
   · method · : ·   · "GET" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
   · }, · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "start" · : ·   · "2026-09-10T13:30:00Z" · , · 
   · "end" · : ·   · "2026-09-10T13:30:00Z" · , · 
   · "assets" · : ·   · [ · 
     · { · 
       · "asset_id" · : ·   · "DE_AMP_TEST_EBX_2" · , · 
       · "afrre_pos" · : ·   · { · 
         · "degraded_seconds" · : ·   · 1200 · , · 
         · "baseline_seconds" · : ·   · 3600 · , · 
         · "breach_seconds" · : ·   · 22 · , · 
         · "stale_seconds" · : ·   · 0 · , · 
         · "substitute_seconds" · : ·   · 42 · , · 
         · "eligible_energy_total_mwh" · : ·   · "22.239000" · , · 
         · "paid_energy_total_mwh" · : ·   · "21.874000" · , · 
         · "gated_energy_total_mwh" · : ·   · "0.365000" · 
       · }, · 
       · "afrre_neg" · : ·   · { · 
         · "degraded_seconds" · : ·   · 1200 · , · 
         · "baseline_seconds" · : ·   · 3600 · , · 
         · "breach_seconds" · : ·   · 22 · , · 
         · "stale_seconds" · : ·   · 0 · , · 
         · "substitute_seconds" · : ·   · 42 · , · 
         · "eligible_energy_total_mwh" · : ·   · "22.239000" · , · 
         · "paid_energy_total_mwh" · : ·   · "21.874000" · , · 
         · "gated_energy_total_mwh" · : ·   · "0.365000" · 
       · }, · 
       · "blocks" · : ·   · [ · 
         · { · 
           · "block_start" · : ·   · "2026-09-10T13:30:00Z" · , · 
           · "block_end" · : ·   · "2026-09-10T13:30:00Z" · , · 
           · "status" · : ·   · "PRELIMINARY" · , · 
           · "processed_at" · : ·   · "2026-09-10T13:30:00Z" · , · 
           · "afrre_pos" · : ·   · { · 
             · "degraded_seconds" · : ·   · 120 · , · 
             · "baseline_seconds" · : ·   · 300 · , · 
             · "breach_seconds" · : ·   · 11 · , · 
             · "stale_seconds" · : ·   · 0 · , · 
             · "substitute_seconds" · : ·   · 3 · , · 
             · "eligible_energy_mwh" · : ·   · "0.250000" · , · 
             · "paid_energy_mwh" · : ·   · "0.245000" · , · 
             · "gated_energy_mwh" · : ·   · "0.005000" · 
           · }, · 
           · "afrre_neg" · : ·   · { · 
             · "degraded_seconds" · : ·   · 120 · , · 
             · "baseline_seconds" · : ·   · 300 · , · 
             · "breach_seconds" · : ·   · 11 · , · 
             · "stale_seconds" · : ·   · 0 · , · 
             · "substitute_seconds" · : ·   · 3 · , · 
             · "eligible_energy_mwh" · : ·   · "0.250000" · , · 
             · "paid_energy_mwh" · : ·   · "0.245000" · , · 
             · "gated_energy_mwh" · : ·   · "0.005000" · 
           · } · 
         · } · 
       · ], · 
       · "episodes" · : ·   · [ · 
         · { · 
           · "direction" · : ·   · "pos" · , · 
           · "kind" · : ·   · "imm" · , · 
           · "start_context" · : ·   · "onset" · , · 
           · "episode_start" · : ·   · "2026-09-10T13:30:00Z" · , · 
           · "episode_end" · : ·   · "2026-09-10T13:30:00Z" · , · 
           · "breach_seconds" · : ·   · 11 · , · 
           · "max_dev_frac" · : ·   · "0.2" · , · 
           · "degraded_until" · : ·   · "2026-09-10T13:30:00Z" · , · 
           · "baseline_kw" · : ·   · "<string>" · , · 
           · "baseline_empty" · : ·   · false · 
         · } · 
       · ] · 
     · } · 
   · ] · 
 · }
```

Can raise

-   401 · no valid token
-   403 · scope missing
-   422 · validation failed
-   429 · rate limited

[ALL CODES →](https://docs.ebx.energy/reference/errors.md)

· GET · /v1/settlements/quality-trace

### Per-second quality trace behind the settlement (chart input)

invoice.read

Return the second-resolution trace behind `/v1/settlements/quality`.

Setpoint against delivered power inside the acceptance channel, each assessed second classified (forgiven / sustained / immediate) and the DEGRADED and BASELINE windows marked — the seconds the block counters aggregate.

Bounded in both window (6 h) and asset count (8), so `asset_ids` is required here unlike on the block endpoints. Points are bucketed to keep the response bounded; `resolution_seconds` says how coarse, and the per-asset `summary` counters stay at one second regardless so the headline numbers never depend on the zoom level.

Query parameters

start · REQUIRED

string<date-time> · Window start (inclusive), UTC

end · REQUIRED

string<date-time> · Window end (exclusive), UTC

status · REQUIRED

enum · `PRELIMINARY` · `FINAL` · Settlement state filter: 'preliminary' or 'final' (case-insensitive)

asset\_ids · REQUIRED

string · Comma-separated asset ids (required; at most 8)

Example value

cURL:

```bash
curl ·   · "https://api.ebx.energy/v1/settlements/quality-trace?start=2026-07-22T01:30:00Z&end=2026-07-22T02:30:00Z&status=preliminary&asset_ids=DE_AMP_TEST_EBX_1,DE_AMP_TEST_EBX_2" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

r = httpx.get(
     · "https://api.ebx.energy/v1/settlements/quality-trace?start=2026-07-22T01:30:00Z&end=2026-07-22T02:30:00Z&status=preliminary&asset_ids=DE_AMP_TEST_EBX_1,DE_AMP_TEST_EBX_2" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/settlements/quality-trace?start=2026-07-22T01:30:00Z&end=2026-07-22T02:30:00Z&status=preliminary&asset_ids=DE_AMP_TEST_EBX_1,DE_AMP_TEST_EBX_2" · , ·   · { · 
   · method · : ·   · "GET" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
   · }, · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "start" · : ·   · "2026-09-10T13:30:00Z" · , · 
   · "end" · : ·   · "2026-09-10T13:30:00Z" · , · 
   · "resolution_seconds" · : ·   · 1 · , · 
   · "assets" · : ·   · [ · 
     · { · 
       · "asset_id" · : ·   · "DE_AMP_TEST_EBX_2" · , · 
       · "summary" · : ·   · { · 
         · "assessed_seconds" · : ·   · 0 · , · 
         · "breach_immediate_seconds" · : ·   · 0 · , · 
         · "breach_sustained_seconds" · : ·   · 0 · , · 
         · "forgiven_seconds" · : ·   · 0 · , · 
         · "degraded_seconds" · : ·   · 0 · , · 
         · "baseline_seconds" · : ·   · 0 · , · 
         · "stale_seconds" · : ·   · 0 · 
       · }, · 
       · "points" · : ·   · [ · 
         · { · 
           · "t" · : ·   · "2026-09-10T13:30:00Z" · , · 
           · "setpoint_kw" · : ·   · 0 · , · 
           · "actual_min_kw" · : ·   · 0 · , · 
           · "actual_max_kw" · : ·   · 0 · , · 
           · "channel_upper_kw" · : ·   · 0 · , · 
           · "channel_lower_kw" · : ·   · 0 · , · 
           · "max_dev_frac" · : ·   · 0 · , · 
           · "breach_sustained" · : ·   · false · , · 
           · "breach_immediate" · : ·   · false · , · 
           · "forgiven" · : ·   · false · , · 
           · "degraded" · : ·   · false · , · 
           · "baseline" · : ·   · false · , · 
           · "stale" · : ·   · false · , · 
           · "substitute" · : ·   · false · , · 
           · "paid_mwh" · : ·   · 0 · , · 
           · "eligible_mwh" · : ·   · 0 · , · 
           · "revenue_eur" · : ·   · 0 · , · 
           · "penalty_eur" · : ·   · 0 · 
         · } · 
       · ] · 
     · } · 
   · ] · 
 · }
```

Can raise

-   401 · no valid token
-   403 · scope missing
-   422 · validation failed
-   429 · rate limited

[ALL CODES →](https://docs.ebx.energy/reference/errors.md)
