# Markets · aFRR

> Capacity and energy bids are separate resources, each with valid bid intervals, updates, bulk delete and results. Backup market defaults and bid overrides are set per asset.

API reference

Capacity and energy bids are separate resources, each with valid bid intervals, updates, bulk delete and results. Backup market defaults and bid overrides are set per asset.

19 endpoints

· GET · /v1/assets/{asset\_id}/backup\_markets/afrr/bids

### List backup-market bid overrides for the asset

asset.read

Path parameters

asset\_id · REQUIRED

string

Query parameters

product

enum · `pos` · `neg` · `na` · Return only overrides for this direction (pos/neg). Null returns both directions. Only pos/neg are supported for afrr.

start\_time

string<date-time> · Return bid overrides whose end\_time is strictly after this timestamp. With end\_time, the API matches intervals overlapping \[start\_time, end\_time).

end\_time

string<date-time> · Return bid overrides whose start\_time is strictly before this timestamp. With start\_time, the API matches intervals overlapping \[start\_time, end\_time).

Example value

cURL:

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

Python:

```python
import ·  httpx

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

TypeScript:

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

Example response · 200

```json
{ · 
   · "bids" · : ·   · [ · 
     · { · 
       · "id" · : ·   · "00000000-0000-0000-0000-000000000000" · , · 
       · "asset_id" · : ·   · "<string>" · , · 
       · "product" · : ·   · "pos" · , · 
       · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "end_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "price" · : ·   · "<string>" · , · 
       · "max_capacity_mw" · : ·   · 0 · , · 
       · "note" · : ·   · "<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)

 · POST · /v1/assets/{asset\_id}/backup\_markets/afrr/bids

### Submit a backup-market bid override for a window

asset.write

Times must be aligned to 15-minute delivery blocks; minimum window is one block. Set max\_capacity\_mw=0 to mark the asset unavailable for backup-market dispatch in the window. Mutations are subject to a 10-second gate closure before each 15-minute delivery block.

Path parameters

asset\_id · REQUIRED

string

Request body · required

product · REQUIRED

enum · `pos` · `neg` · `na` · Direction an IC config/override applies to. aFRR is directional (`pos`/`neg`); `na` is the symmetric placeholder used by FCR collateralization.

start\_time · REQUIRED

string<date-time> · Start time of the bid override interval (UTC, 15-min-aligned).

end\_time · REQUIRED

string<date-time> · End time of the bid override interval (UTC, 15-min-aligned, exclusive).

price

number | string · Override price for the window (EUR/MWh). Null falls back to the default price.

max\_capacity\_mw

number · Override max backup-market dispatch capacity for the window (MW). The value is the absolute (unsigned) magnitude — the dispatcher applies it symmetrically to both positive and negative directions. Set to 0 to mark the asset unavailable in this window. Null falls back to the default cap.

note

string · Free-text note attached to the bid override (e.g. reason for unavailability).

Example value

cURL:

```bash
curl ·   · -X ·  POST  · "https://api.ebx.energy/v1/assets/DE_BESS_01/backup_markets/afrr/bids" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN" ·  \
   · -H ·   · "Content-Type: application/json" ·  \
   · -d ·   · '{"product":"pos","start_time":"2026-09-10T13:30:00Z","end_time":"2026-09-10T13:30:00Z","price":80,"max_capacity_mw":0,"note":"<string>"}'
```

Python:

```python
import ·  httpx

r = httpx.post(
     · "https://api.ebx.energy/v1/assets/DE_BESS_01/backup_markets/afrr/bids" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
    json= · { · 
         · "product" · : ·   · "pos" · , · 
         · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
         · "end_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
         · "price" · : ·   · 80 · , · 
         · "max_capacity_mw" · : ·   · 0 · , · 
         · "note" · : ·   · "<string>" · , · 
     · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/assets/DE_BESS_01/backup_markets/afrr/bids" · , ·   · { · 
   · method · : ·   · "POST" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
     · "Content-Type" · : ·   · "application/json" · , · 
   · }, · 
   · body · : ·  JSON.stringify( · { · "product" · : · "pos" · , · "start_time" · : · "2026-09-10T13:30:00Z" · , · "end_time" · : · "2026-09-10T13:30:00Z" · , · "price" · : · 80 · , · "max_capacity_mw" · : · 0 · , · "note" · : · "<string>" · } · ) · , · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 201

```json
{ · 
   · "id" · : ·   · "00000000-0000-0000-0000-000000000000" · , · 
   · "asset_id" · : ·   · "<string>" · , · 
   · "product" · : ·   · "pos" · , · 
   · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
   · "end_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
   · "price" · : ·   · "<string>" · , · 
   · "max_capacity_mw" · : ·   · 0 · , · 
   · "note" · : ·   · "<string>" · 
 · }
```

Can raise

-   400 · malformed request
-   401 · no valid token
-   403 · scope missing
-   404 · unknown or not visible
-   409 · state conflict
-   422 · validation failed
-   429 · rate limited

[ALL CODES →](https://docs.ebx.energy/reference/errors.md)· DELETE · /v1/assets/{asset\_id}/backup\_markets/afrr/bids/{bid\_id}

### Cancel a future backup-market bid override

asset.write

Mutations are subject to a 10-second gate closure before each 15-minute delivery block.

Path parameters

asset\_id · REQUIRED

string

bid\_id · REQUIRED

string<uuid>

Example value

cURL:

```bash
curl ·   · -X ·  DELETE  · "https://api.ebx.energy/v1/assets/DE_BESS_01/backup_markets/afrr/bids/00000000-0000-0000-0000-000000000000" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

r = httpx.delete(
     · "https://api.ebx.energy/v1/assets/DE_BESS_01/backup_markets/afrr/bids/00000000-0000-0000-0000-000000000000" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
)
print(r.status_code)
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/assets/DE_BESS_01/backup_markets/afrr/bids/00000000-0000-0000-0000-000000000000" · , ·   · { · 
   · method · : ·   · "DELETE" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
   · }, · 
 · } · );
```

Returns 204 with no body.

Can raise

-   400 · malformed request
-   401 · no valid token
-   403 · scope missing
-   404 · unknown or not visible
-   409 · state conflict
-   429 · rate limited

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

· GET · /v1/assets/{asset\_id}/backup\_markets/afrr/default

### Get the asset's current backup-market default

asset.read

Path parameters

asset\_id · REQUIRED

string

Query parameters

product · REQUIRED

enum · `pos` · `neg` · `na`

Example value

cURL:

```bash
curl ·   · "https://api.ebx.energy/v1/assets/DE_BESS_01/backup_markets/afrr/default?product=pos" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

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

TypeScript:

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

Example response · 200

```json
{ · 
   · "asset_id" · : ·   · "<string>" · , · 
   · "product" · : ·   · "pos" · , · 
   · "default_price" · : ·   · "<string>" · , · 
   · "default_max_capacity_mw" · : ·   · 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)

· PUT · /v1/assets/{asset\_id}/backup\_markets/afrr/default

### Set the asset's default backup-market price/capacity

asset.write

Use to change the asset's baseline backup-market price/capacity from now on. For temporary changes, use POST /bids. Existing bid overrides keep their explicit values; only overrides that did not set a value pick up the new default. Mutations are subject to a 10-second gate closure before each 15-minute delivery block.

Path parameters

asset\_id · REQUIRED

string

Request body · required

product · REQUIRED

enum · `pos` · `neg` · `na` · Direction an IC config/override applies to. aFRR is directional (`pos`/`neg`); `na` is the symmetric placeholder used by FCR collateralization.

default\_price · REQUIRED

number | string · Default backup-market price in EUR/MWh. Applied from the next delivery block onwards.

default\_max\_capacity\_mw

number · Optional default cap on backup-market dispatch capacity (MW). The value is the absolute (unsigned) magnitude — the dispatcher applies it symmetrically to both positive and negative directions. Null means no cap.

Example value

cURL:

```bash
curl ·   · -X ·  PUT  · "https://api.ebx.energy/v1/assets/DE_BESS_01/backup_markets/afrr/default" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN" ·  \
   · -H ·   · "Content-Type: application/json" ·  \
   · -d ·   · '{"product":"pos","default_price":40,"default_max_capacity_mw":2}'
```

Python:

```python
import ·  httpx

r = httpx.put(
     · "https://api.ebx.energy/v1/assets/DE_BESS_01/backup_markets/afrr/default" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
    json= · { · 
         · "product" · : ·   · "pos" · , · 
         · "default_price" · : ·   · 40 · , · 
         · "default_max_capacity_mw" · : ·   · 2 · , · 
     · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/assets/DE_BESS_01/backup_markets/afrr/default" · , ·   · { · 
   · method · : ·   · "PUT" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
     · "Content-Type" · : ·   · "application/json" · , · 
   · }, · 
   · body · : ·  JSON.stringify( · { · "product" · : · "pos" · , · "default_price" · : · 40 · , · "default_max_capacity_mw" · : · 2 · } · ) · , · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "asset_id" · : ·   · "<string>" · , · 
   · "product" · : ·   · "pos" · , · 
   · "default_price" · : ·   · "<string>" · , · 
   · "default_max_capacity_mw" · : ·   · 0 · 
 · }
```

Can raise

-   400 · malformed request
-   401 · no valid token
-   403 · scope missing
-   404 · unknown or not visible
-   409 · state conflict
-   422 · validation failed
-   429 · rate limited

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

· GET · /v1/assets/{asset\_id}/markets/afrr/capacity/bids

### Get aFRR capacity bids

market.read

Get bids currently placed in the Automatic Frequency Restoration Reserve (aFRR) capacity market.

Use `start_time` and/or `end_time` to filter bids by interval overlap. With both values, the endpoint returns bids overlapping the half-open window `[start_time, end_time)`. Bids do not need to be fully contained in the window.

Boundary behavior:

-   a bid ending exactly at `start_time` is excluded
-   a bid starting exactly at `end_time` is excluded

`product` narrows the result set further by bid direction. If no parameters are provided, it returns all bids for the asset.

Product can be either `pos` or `neg`. `pos` is positive reserve (inject power into the grid), `neg` is negative reserve (absorb power from the grid).

Bids can be retrieved for the last 30 days.

Path parameters

asset\_id · REQUIRED

string

Query parameters

start\_time

string<date-time> · Return bids whose end\_time is strictly after this timestamp. With end\_time, the API matches bids overlapping the half-open window \[start\_time, end\_time). Bids do not need to be fully contained in the window.

end\_time

string<date-time> · Return bids whose start\_time is strictly before this timestamp.

product

enum · `pos` · `neg` · Filter by product. Provide a single value: `pos` (aFRR+) or `neg` (aFRR-).

Example value

cURL:

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

Python:

```python
import ·  httpx

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

TypeScript:

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

Example response · 200

```json
{ · 
   · "bids" · : ·   · [ · 
     · { · 
       · "id" · : ·   · "00000000-0000-0000-0000-000000000000" · , · 
       · "idempotency_key" · : ·   · "<string>" · , · 
       · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "end_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "product" · : ·   · "pos" · , · 
       · "capacity_price_eur_per_mw" · : ·   · 50.1 · , · 
       · "energy_price_eur_per_mwh" · : ·   · 35.8 · , · 
       · "offered_power_mw" · : ·   · 100 · , · 
       · "last_edit_attempt" · : ·   · { · 
         · "edit_type" · : ·   · "MODIFY" · , · 
         · "status" · : ·   · "PENDING_RESYNC" · , · 
         · "attempted_at" · : ·   · "2026-09-10T13:30:00Z" · , · 
         · "requested_values" · : ·   · "<string>" · , · 
         · "failure_reason" · : ·   · "<string>" · , · 
         · "failure_detail" · : ·   · "<string>" · 
       · } · 
     · } · 
   · ], · 
   · "market" · : ·   · "capacity" · 
 · }
```

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)

· POST · /v1/assets/{asset\_id}/markets/afrr/capacity/bids

### Submit aFRR capacity bids

market.write

Post a bid in the Automatic Frequency Restoration Reserve (aFRR) capacity market.

This endpoint supports two modes:

-   `mode=CREATE` inserts bids.
-   `mode=REPLACE` deletes all pending bids fully contained in `replace_scope` and inserts only the provided bids.

In `REPLACE` mode, `replace_scope` defines the window to clear. Each bid in `bids` must be fully contained within that window. If `replace_scope.product` is omitted, both `pos` and `neg` bids in the window are deleted before recreating only the provided bids. Missing blocks or product combinations inside the scope remain deleted.

For capacity bids, provide `start_time`, `end_time`, `product`, `capacity_price_eur_per_mw`, `energy_price_eur_per_mwh`, and `offered_power_mw`.

Time intervals are validated against the market calendar to ensure they match valid Regelleistung tender intervals. This correctly handles DST transitions.

Example request:

Worked example · bash

```bash
curl -X POST "https://api.ebx.energy/v1/assets/{asset_id}/markets/afrr/capacity/bids" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer <access_token>" \
    -d '{
        "mode": "REPLACE",
        "replace_scope": {
            "start_time": "2025-01-02T23:00:00Z",
            "end_time": "2025-01-03T23:00:00Z",
            "product": "pos"
        },
        "bids": [
            {
                "capacity_price_eur_per_mw": 100.0,
                "energy_price_eur_per_mwh": 50.0,
                "offered_power_mw": 120,
                "start_time": "2025-01-02T23:00:00Z",
                "end_time": "2025-01-03T03:00:00Z",
                "product": "pos",
                "idempotency_key": "example-idempotency-key"
            },
            {
                "capacity_price_eur_per_mw": 95.0,
                "energy_price_eur_per_mwh": 45.0,
                "offered_power_mw": 100,
                "start_time": "2025-01-03T03:00:00Z",
                "end_time": "2025-01-03T07:00:00Z",
                "product": "pos",
                "idempotency_key": "example-idempotency-key-2"
            }
        ]
    }'
```

In the example above, all pending `pos` aFRR capacity bids inside the full-day scope are deleted first. Only the two provided blocks are recreated. Any other `pos` block in that scope remains deleted.

Idempotency is per bid using `idempotency_key` on each bid object. Scope is defined by the endpoint plus bid interval/product (`start_time`, `end_time`, `product`). Retrying the same key in the same scope returns the originally stored bid and no overwrite occurs. Reusing the same key for a different interval or product is treated as a different bid scope.

Bids for the `capacity` market are accepted from 10:00 AM CET/CEST one week before delivery day (i.e. D-7).

**Gate Closure Times:**

-   **EBX deadline (recommended)**: D-1 08:30 CET — submitting before this gives us a buffer to forward your bid to the market.
-   **Regelleistung gate (enforced)**: D-1 09:00 CET — submissions or updates for a delivery day after this time are rejected with HTTP 409.

Submissions or updates between the EBX deadline and the Regelleistung gate are accepted but **not guaranteed** to be forwarded to the market in time.

**Prequalified capacity ceiling (enforced):** For each 15-minute delivery period and each direction (`pos`/`neg`), the power in this request plus the power already committed by your other bids in the **same market** must not exceed the asset's prequalified aFRR capacity. Bids with status `PENDING`, `SUBMITTED`, `SUCCESSFUL` or `FALLBACK` count as committed; `REJECTED`, `FAILED` and `CANCELLED` bids release their capacity. The capacity and energy markets are checked independently of one another.

If any period would be exceeded, the **entire request** is rejected with HTTP 409 and error code `AFRR_PREQUALIFIED_CAPACITY_EXCEEDED` — nothing is stored, including the bids that would have fit. The response detail lists every breached period with its direction, the total committed power, the ceiling, and the overshoot. In `mode=REPLACE`, the bids this request would delete are not counted against it — but note the clear has _not_ happened when the request is rejected, so a 409 leaves the existing bids in the scope exactly as they were. A prequalified capacity of `0` in a direction is enforced as a real limit of zero: no power may be committed in that direction, and every such bid is rejected. If you believe your asset's recorded prequalified capacity is wrong, contact EBX to have it corrected — the API will not bid past it.

`offered_power_mw` is in megawatts (MW). `capacity_price_eur_per_mw` is in EUR/MW, and must be between 0 and 15,000 EUR/MW. `energy_price_eur_per_mwh` is in EUR/MWh, and must be between -15,000 and 15,000 EUR/MWh. It follows the following cashflow convention:

-   `energy_price_eur_per_mwh < 0`: provider pays grid/TSO
-   `energy_price_eur_per_mwh >= 0`: provider receives money from grid/TSO

Bids are stored with status=PENDING and will be submitted to the market before gate closure. Once submitted, status moves to SUBMITTED and then to SUCCESSFUL or REJECTED based on the auction outcome. If a bid never reaches the market (e.g. an outage spanning gate closure) and the auction window has passed, it is marked FAILED. For aFRR energy specifically, if the auction itself fails to clear (RAM Fallback), the bid is marked FALLBACK and the TSO Ersatzpreis applies.

Path parameters

asset\_id · REQUIRED

string

Request body · required

bids · REQUIRED

array\[object\] · List of bids for the capacity AFRR market.

mode

enum · default CREATE · `CREATE` · `REPLACE` · CREATE inserts bids. REPLACE deletes all pending bids fully contained in replace\_scope and then inserts only the provided bids.

replace\_scope

object · Required when mode=REPLACE. Defines the replacement window to clear before recreating the provided bids.

Example value

cURL:

```bash
curl ·   · -X ·  POST  · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/capacity/bids" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN" ·  \
   · -H ·   · "Content-Type: application/json" ·  \
   · -d ·   · '{"bids":[{"idempotency_key":"<string>","start_time":"2026-09-10T13:30:00Z","end_time":"2026-09-10T13:30:00Z","product":"pos","capacity_price_eur_per_mw":50.1,"energy_price_eur_per_mwh":35.8,"offered_power_mw":100}],"mode":"CREATE","replace_scope":{"start_time":"2026-09-10T13:30:00Z","end_time":"2026-09-10T13:30:00Z","product":"pos"}}'
```

Python:

```python
import ·  httpx

r = httpx.post(
     · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/capacity/bids" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
    json= · { · 
         · "bids" · : ·   · [ · 
             · { · 
                 · "idempotency_key" · : ·   · "<string>" · , · 
                 · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
                 · "end_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
                 · "product" · : ·   · "pos" · , · 
                 · "capacity_price_eur_per_mw" · : ·   · 50.1 · , · 
                 · "energy_price_eur_per_mwh" · : ·   · 35.8 · , · 
                 · "offered_power_mw" · : ·   · 100 · , · 
             · }, · 
         · ], · 
         · "mode" · : ·   · "CREATE" · , · 
         · "replace_scope" · : ·   · { · 
             · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
             · "end_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
             · "product" · : ·   · "pos" · , · 
         · }, · 
     · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/capacity/bids" · , ·   · { · 
   · method · : ·   · "POST" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
     · "Content-Type" · : ·   · "application/json" · , · 
   · }, · 
   · body · : ·  JSON.stringify( · { · "bids" · :[{ · "idempotency_key" · : · "<string>" · , · "start_time" · : · "2026-09-10T13:30:00Z" · , · "end_time" · : · "2026-09-10T13:30:00Z" · , · "product" · : · "pos" · , · "capacity_price_eur_per_mw" · : · 50.1 · , · "energy_price_eur_per_mwh" · : · 35.8 · , · "offered_power_mw" · : · 100 · }], · "mode" · : · "CREATE" · , · "replace_scope" · :{ · "start_time" · : · "2026-09-10T13:30:00Z" · , · "end_time" · : · "2026-09-10T13:30:00Z" · , · "product" · : · "pos" · }} · ) · , · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 201

```json
{ · 
   · "bids" · : ·   · [ · 
     · { · 
       · "id" · : ·   · "00000000-0000-0000-0000-000000000000" · , · 
       · "idempotency_key" · : ·   · "<string>" · , · 
       · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "end_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "product" · : ·   · "pos" · , · 
       · "capacity_price_eur_per_mw" · : ·   · 50.1 · , · 
       · "energy_price_eur_per_mwh" · : ·   · 35.8 · , · 
       · "offered_power_mw" · : ·   · 100 · , · 
       · "last_edit_attempt" · : ·   · { · 
         · "edit_type" · : ·   · "MODIFY" · , · 
         · "status" · : ·   · "PENDING_RESYNC" · , · 
         · "attempted_at" · : ·   · "2026-09-10T13:30:00Z" · , · 
         · "requested_values" · : ·   · "<string>" · , · 
         · "failure_reason" · : ·   · "<string>" · , · 
         · "failure_detail" · : ·   · "<string>" · 
       · } · 
     · } · 
   · ], · 
   · "created_count" · : ·   · 0 · , · 
   · "deleted_count" · : ·   · 0 · , · 
   · "deleted_bid_ids" · : ·   · [ · 
     · "00000000-0000-0000-0000-000000000000" · 
   · ], · 
   · "updated_count" · : ·   · 0 · , · 
   · "warnings" · : ·   · [ · 
     · "<string>" · 
   · ], · 
   · "market" · : ·   · "capacity" · 
 · }
```

Can raise

-   400 · malformed request
-   401 · no valid token
-   403 · scope missing
-   404 · unknown or not visible
-   409 · state conflict
-   422 · validation failed
-   429 · rate limited

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

· DELETE · /v1/assets/{asset\_id}/markets/afrr/capacity/bids

### Bulk delete aFRR capacity bids by interval

market.write

Bulk delete bids in the Automatic Frequency Restoration Reserve (aFRR) capacity market by exact interval.

Matching is strict: only bids with exactly the same `start_time` and `end_time` are deleted. If `product` is omitted, both `pos` and `neg` bids are deleted.

**Gate Closure Times:**

-   **EBX deadline (recommended)**: D-1 08:30 CET — deleting before this gives us a buffer to forward your deletion to the market.
-   **Regelleistung gate (enforced)**: D-1 09:00 CET — deletions for a delivery day after this time are rejected with HTTP 409.

Deletions submitted between the EBX deadline and the Regelleistung gate are accepted but **not guaranteed** to be forwarded to the market in time.

Only bids with status=PENDING can be deleted. Once a bid has been submitted to the market, it cannot be deleted through this API.

Path parameters

asset\_id · REQUIRED

string

Query parameters

start\_time · REQUIRED

string<date-time> · Exact interval start for deletion (UTC).

end\_time · REQUIRED

string<date-time> · Exact interval end for deletion (UTC).

product

enum · `pos` · `neg` · Optional direction filter.

Example value

cURL:

```bash
curl ·   · -X ·  DELETE  · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/capacity/bids?start_time=2026-02-03T00:00:00Z&end_time=2026-02-04T00:00:00Z" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

r = httpx.delete(
     · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/capacity/bids?start_time=2026-02-03T00:00:00Z&end_time=2026-02-04T00: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/markets/afrr/capacity/bids?start_time=2026-02-03T00:00:00Z&end_time=2026-02-04T00:00:00Z" · , ·   · { · 
   · method · : ·   · "DELETE" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
   · }, · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "deleted_count" · : ·   · 0 · , · 
   · "deleted_bid_ids" · : ·   · [ · 
     · "00000000-0000-0000-0000-000000000000" · 
   · ] · 
 · }
```

Can raise

-   400 · malformed request
-   401 · no valid token
-   403 · scope missing
-   404 · unknown or not visible
-   409 · state conflict
-   422 · validation failed
-   429 · rate limited

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

· PUT · /v1/assets/{asset\_id}/markets/afrr/capacity/bids/{bid\_id}

### Update an aFRR capacity bid

market.write

Update bids in the Automatic Frequency Restoration Reserve (aFRR) capacity market.

This endpoint allows you to modify existing bids for a specific market, date, time, and product.

You can update the bid by providing the `bid_id` in the URL path. This ID is obtained when the bid was created.

**Gate Closure Times:**

-   **EBX deadline (recommended)**: D-1 08:30 CET — updating before this gives us a buffer to forward your update to the market.
-   **Regelleistung gate (enforced)**: D-1 09:00 CET — updates for a delivery day after this time are rejected with HTTP 409.

**Late edits (PENDING vs SUBMITTED bids):**

-   PENDING bids — the change is applied directly before the bid is submitted to the market. The response shows the updated bid with `last_edit_attempt=null`.
-   SUBMITTED bids (already in market, before the Regelleistung gate) — the bid row in the response keeps showing what Regelleistung currently has; the requested change is captured in `last_edit_attempt` with status `PENDING_RESYNC`. The market-operations-service forwards it to Regelleistung within ~1 minute. If the gate closes before the forwarding succeeds, `last_edit_attempt.status` becomes `FAILED_LATE_EDIT` and the original bid stays in the market.

`start_time`, `end_time`, and `product` cannot be changed after a bid has been submitted (the tender would change). Only `offered_power_mw`, `capacity_price_eur_per_mw`, and `energy_price_eur_per_mwh` can be modified on a SUBMITTED bid.

For PENDING bids, a changed `start_time`/`end_time` must match a valid bidding window in the market calendar — otherwise the request is rejected with HTTP 422 and suggested valid intervals, exactly as on bid creation.

**Prequalified capacity ceiling (enforced):** Raising `offered_power_mw` is rejected with HTTP 409 and error code `AFRR_PREQUALIFIED_CAPACITY_EXCEEDED` if the new value would push the total committed capacity-market power above the asset's prequalified aFRR capacity in any 15-minute delivery period for this bid's direction. This bid's own current power is not counted against the request, so a bid may always be raised to consume the headroom it already holds. Nothing is written when the check fails — for a SUBMITTED bid, no edit attempt is recorded either. A prequalified capacity of `0` in a direction is enforced as a real limit of zero, so no power may be committed in that direction at all.

Specifying the `idempotency_key` will overwrite the existing idempotency key for the bid (PENDING bids only).

Path parameters

asset\_id · REQUIRED

string

bid\_id · REQUIRED

string<uuid> · Bid ID to update

Request body · required

idempotency\_key

string · Optional idempotency key. Deduplication is scoped to the bid delivery scope within the endpoint (start/end interval, and product for aFRR).

start\_time · REQUIRED

string<date-time> · The start time for the time window for the bids in ISO 8601 format (UTC, 15-minute aligned)

end\_time · REQUIRED

string<date-time> · The end time for the time window for the bids in ISO 8601 format (UTC, 15-minute aligned)

product · REQUIRED

enum · `pos` · `neg`

capacity\_price\_eur\_per\_mw · REQUIRED

number | string · The price of the offered capacity in EUR/MW (max 2 decimal places). Rejected with 422 `PRICE_OUT_OF_RANGE` above the configured market maximum (15000 EUR/MW by default).

energy\_price\_eur\_per\_mwh · REQUIRED

number | string · The price of the offered energy in EUR/MWh (max 2 decimal places). May be negative — paying to absorb energy is a legitimate offer. Rejected with 422 `PRICE_OUT_OF_RANGE` outside the configured market range (-15000 to 15000 EUR/MWh by default).

offered\_power\_mw · REQUIRED

integer · The amount of power offered in MW (integer values only, min 1 MW)

Example value

cURL:

```bash
curl ·   · -X ·  PUT  · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/capacity/bids/00000000-0000-0000-0000-000000000000" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN" ·  \
   · -H ·   · "Content-Type: application/json" ·  \
   · -d ·   · '{"idempotency_key":"<string>","start_time":"2026-09-10T13:30:00Z","end_time":"2026-09-10T13:30:00Z","product":"pos","capacity_price_eur_per_mw":50.1,"energy_price_eur_per_mwh":35.8,"offered_power_mw":100}'
```

Python:

```python
import ·  httpx

r = httpx.put(
     · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/capacity/bids/00000000-0000-0000-0000-000000000000" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
    json= · { · 
         · "idempotency_key" · : ·   · "<string>" · , · 
         · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
         · "end_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
         · "product" · : ·   · "pos" · , · 
         · "capacity_price_eur_per_mw" · : ·   · 50.1 · , · 
         · "energy_price_eur_per_mwh" · : ·   · 35.8 · , · 
         · "offered_power_mw" · : ·   · 100 · , · 
     · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/capacity/bids/00000000-0000-0000-0000-000000000000" · , ·   · { · 
   · method · : ·   · "PUT" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
     · "Content-Type" · : ·   · "application/json" · , · 
   · }, · 
   · body · : ·  JSON.stringify( · { · "idempotency_key" · : · "<string>" · , · "start_time" · : · "2026-09-10T13:30:00Z" · , · "end_time" · : · "2026-09-10T13:30:00Z" · , · "product" · : · "pos" · , · "capacity_price_eur_per_mw" · : · 50.1 · , · "energy_price_eur_per_mwh" · : · 35.8 · , · "offered_power_mw" · : · 100 · } · ) · , · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "bids" · : ·   · [ · 
     · { · 
       · "id" · : ·   · "00000000-0000-0000-0000-000000000000" · , · 
       · "idempotency_key" · : ·   · "<string>" · , · 
       · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "end_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "product" · : ·   · "pos" · , · 
       · "capacity_price_eur_per_mw" · : ·   · 50.1 · , · 
       · "energy_price_eur_per_mwh" · : ·   · 35.8 · , · 
       · "offered_power_mw" · : ·   · 100 · , · 
       · "last_edit_attempt" · : ·   · { · 
         · "edit_type" · : ·   · "MODIFY" · , · 
         · "status" · : ·   · "PENDING_RESYNC" · , · 
         · "attempted_at" · : ·   · "2026-09-10T13:30:00Z" · , · 
         · "requested_values" · : ·   · "<string>" · , · 
         · "failure_reason" · : ·   · "<string>" · , · 
         · "failure_detail" · : ·   · "<string>" · 
       · } · 
     · } · 
   · ], · 
   · "warnings" · : ·   · [ · 
     · "<string>" · 
   · ], · 
   · "market" · : ·   · "capacity" · 
 · }
```

Can raise

-   400 · malformed request
-   401 · no valid token
-   403 · scope missing
-   404 · unknown or not visible
-   409 · state conflict
-   422 · validation failed
-   429 · rate limited

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

· DELETE · /v1/assets/{asset\_id}/markets/afrr/capacity/bids/{bid\_id}

### Delete aFRR capacity bid by ID

market.write

Delete a bid in the Automatic Frequency Restoration Reserve (aFRR) capacity market.

Use the bid ID that was returned when the bids were placed to delete a specific bid.

**Gate Closure Times:**

-   **EBX deadline (recommended)**: D-1 08:30 CET — deleting before this gives us a buffer to forward your deletion to the market.
-   **Regelleistung gate (enforced)**: D-1 09:00 CET — deletions for a delivery day after this time are rejected with HTTP 409.

**Late deletes (PENDING vs SUBMITTED bids):**

-   PENDING bids — the row is removed from the database. Response: `deleted=true`, `last_edit_attempt=null`.
-   SUBMITTED bids (already in market, before the Regelleistung gate) — the bid stays in the database (it mirrors what Regelleistung currently has) and a deletion attempt is queued. Response: `deleted=false`, `last_edit_attempt.status=PENDING_RESYNC`. The market-operations-service forwards the deletion to Regelleistung within ~1 minute. If the gate closes before the forwarding succeeds, `last_edit_attempt.status` becomes `FAILED_LATE_EDIT` and the original bid stays in the market.

Path parameters

asset\_id · REQUIRED

string

bid\_id · REQUIRED

string<uuid> · Bid ID to delete

Example value

cURL:

```bash
curl ·   · -X ·  DELETE  · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/capacity/bids/00000000-0000-0000-0000-000000000000" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

r = httpx.delete(
     · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/capacity/bids/00000000-0000-0000-0000-000000000000" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/capacity/bids/00000000-0000-0000-0000-000000000000" · , ·   · { · 
   · method · : ·   · "DELETE" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
   · }, · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "bid_id" · : ·   · "00000000-0000-0000-0000-000000000000" · , · 
   · "deleted" · : ·   · false · , · 
   · "last_edit_attempt" · : ·   · { · 
     · "edit_type" · : ·   · "MODIFY" · , · 
     · "status" · : ·   · "PENDING_RESYNC" · , · 
     · "attempted_at" · : ·   · "2026-09-10T13:30:00Z" · , · 
     · "requested_values" · : ·   · "<string>" · , · 
     · "failure_reason" · : ·   · "<string>" · , · 
     · "failure_detail" · : ·   · "<string>" · 
   · } · 
 · }
```

Can raise

-   400 · malformed request
-   401 · no valid token
-   403 · scope missing
-   404 · unknown or not visible
-   409 · state conflict
-   429 · rate limited

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

· GET · /v1/assets/{asset\_id}/markets/afrr/capacity/bids/intervals

### Get valid aFRR capacity bid intervals

market.read

Discover valid bid intervals for aFRR capacity market.

Returns a list of time intervals during which capacity bids can be submitted. Use this endpoint to find valid `start_time` and `end_time` values for your bid submissions.

**Important: Daylight Saving Time (DST) Handling**

Bid intervals are always specified in UTC. During DST transitions, the duration of market blocks may vary:

-   **Spring forward** (last Sunday of March): A "4-hour local block" (e.g., 00:00-04:00 CET) may be only 3 hours in UTC (e.g., 23:00Z to 02:00Z).

-   **Fall back** (last Sunday of October): A "4-hour local block" may be 5 hours in UTC (e.g., 22:00Z to 03:00Z).

Always use this discovery endpoint to find the correct intervals, especially around DST transition dates.

**Query Parameters:**

-   `date`: Filter by delivery date (YYYY-MM-DD). If not provided, returns intervals for the next 7 days.

Path parameters

asset\_id · REQUIRED

string

Query parameters

date

string<date> · Filter intervals by delivery date (YYYY-MM-DD). If not provided, returns intervals for the next 7 days.

Example value

cURL:

```bash
curl ·   · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/capacity/bids/intervals" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

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

TypeScript:

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

Example response · 200

```json
{ · 
   · "intervals" · : ·   · [ · 
     · { · 
       · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "end_time" · : ·   · "2026-09-10T13:30:00Z" · 
     · } · 
   · ] · 
 · }
```

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}/markets/afrr/capacity/results

### Get aFRR capacity results

market.read

Get aFRR results in the capacity market.

Use `start_time` and/or `end_time` (UTC ISO8601) for overlap-based time filtering. With both values, the endpoint returns result rows whose bid interval overlaps the half-open window `[start_time, end_time)`. Results do not need to be fully contained in the window.

Boundary behavior:

-   a result ending exactly at `start_time` is excluded
-   a result starting exactly at `end_time` is excluded

If neither `start_time` nor `end_time` is provided, results default to the current UTC day (`00:00:00Z` to `00:00:00Z` next day).

**Status values:**

-   `PENDING` — bid created but not yet submitted to market
-   `SUBMITTED` — bid sent to market, awaiting results
-   `REJECTED` — bid was rejected by the market
-   `SUCCESSFUL` — bid was accepted by the market
-   `FAILED` — bid never reached the market (e.g. an outage spanning gate closure) and the auction window has passed; this is a terminal state with no settlement implication
-   `CANCELLED` — the bid was withdrawn before the market closed, either by you or because the asset could no longer back it; it holds no prequalified capacity and has no settlement implication

In Germany, aFRR capacity is remunerated pay-as-bid. The `capacity_price_eur_per_mw` field is the customer's offered and settlement-relevant capacity price for awarded MW. The response therefore does not expose a separate market `clearing_price`.

The `energy_price_eur_per_mwh` field is the balancing-energy offer linked to the capacity bid. It is included for reference but is not a capacity-market settlement field.

`accepted_power_mw` and `offered_power_mw` are in MW.

Path parameters

asset\_id · REQUIRED

string

Query parameters

start\_time

string<date-time> · Return results whose bid end\_time is strictly after this timestamp. With end\_time, the API matches result intervals overlapping the half-open window \[start\_time, end\_time). Results do not need to be fully contained in the window.

end\_time

string<date-time> · Return results whose bid start\_time is strictly before this timestamp. With start\_time, the API matches result intervals overlapping the half-open window \[start\_time, end\_time).

product

enum · `pos` · `neg` · Filter by product. Provide a single value: `pos` (aFRR+) or `neg` (aFRR-).

status

enum · `PENDING` · `SUBMITTED` · `REJECTED` · `SUCCESSFUL` · `FAILED` · `FALLBACK` · `CANCELLED` · Filter by bid status. Valid values: `pending`, `submitted`, `successful`, `rejected`, `failed`, `cancelled`.

Example value

cURL:

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

Python:

```python
import ·  httpx

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

TypeScript:

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

Example response · 200

```json
{ · 
   · "results" · : ·   · [ · 
     · { · 
       · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "end_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "product" · : ·   · "pos" · , · 
       · "status" · : ·   · "PENDING" · , · 
       · "accepted_power_mw" · : ·   · 100 · , · 
       · "capacity_price_eur_per_mw" · : ·   · 50.1 · , · 
       · "energy_price_eur_per_mwh" · : ·   · 35.8 · , · 
       · "offered_power_mw" · : ·   · 100 · , · 
       · "external_origin" · : ·   · false · 
     · } · 
   · ] · 
 · }
```

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}/markets/afrr/energy/bids

### Get aFRR energy bids

market.read

Get bids currently placed in the Automatic Frequency Restoration Reserve (aFRR) energy market.

Use `start_time` and/or `end_time` to filter bids by interval overlap. With both values, the endpoint returns bids overlapping the half-open window `[start_time, end_time)`. Bids do not need to be fully contained in the window.

Boundary behavior:

-   a bid ending exactly at `start_time` is excluded
-   a bid starting exactly at `end_time` is excluded

`product` narrows the result set further by bid direction. If no parameters are provided, it returns all bids for the asset.

Product can be either `pos` or `neg`. `pos` is positive reserve (inject power into the grid), `neg` is negative reserve (absorb power from the grid).

Bids can be retrieved for the last 30 days.

Path parameters

asset\_id · REQUIRED

string

Query parameters

start\_time

string<date-time> · Return bids whose end\_time is strictly after this timestamp. With end\_time, the API matches bids overlapping the half-open window \[start\_time, end\_time). Bids do not need to be fully contained in the window.

end\_time

string<date-time> · Return bids whose start\_time is strictly before this timestamp.

product

enum · `pos` · `neg` · Filter by product. Provide a single value: `pos` (aFRR+) or `neg` (aFRR-).

Example value

cURL:

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

Python:

```python
import ·  httpx

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

TypeScript:

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

Example response · 200

```json
{ · 
   · "bids" · : ·   · [ · 
     · { · 
       · "id" · : ·   · "00000000-0000-0000-0000-000000000000" · , · 
       · "idempotency_key" · : ·   · "<string>" · , · 
       · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "end_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "product" · : ·   · "pos" · , · 
       · "energy_price_eur_per_mwh" · : ·   · 35.8 · , · 
       · "offered_power_mw" · : ·   · 100 · , · 
       · "last_edit_attempt" · : ·   · { · 
         · "edit_type" · : ·   · "MODIFY" · , · 
         · "status" · : ·   · "PENDING_RESYNC" · , · 
         · "attempted_at" · : ·   · "2026-09-10T13:30:00Z" · , · 
         · "requested_values" · : ·   · "<string>" · , · 
         · "failure_reason" · : ·   · "<string>" · , · 
         · "failure_detail" · : ·   · "<string>" · 
       · } · 
     · } · 
   · ], · 
   · "market" · : ·   · "capacity" · 
 · }
```

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)

· POST · /v1/assets/{asset\_id}/markets/afrr/energy/bids

### Submit aFRR energy bids

market.write

Post a bid in the Automatic Frequency Restoration Reserve (aFRR) energy market.

This endpoint supports two modes:

-   `mode=CREATE` inserts bids.
-   `mode=REPLACE` deletes all pending bids fully contained in `replace_scope` and inserts only the provided bids.

In `REPLACE` mode, `replace_scope` defines the window to clear. Each bid in `bids` must be fully contained within that window. If `replace_scope.product` is omitted, both `pos` and `neg` bids in the window are deleted before recreating only the provided bids. Missing quarter-hours or product combinations inside the scope remain deleted.

For energy bids, provide `start_time`, `end_time`, `product`, `energy_price_eur_per_mwh`, and `offered_power_mw`.

Time intervals are validated against the market calendar to ensure they match valid Regelleistung tender intervals. This correctly handles DST transitions where quarter-hour counts may vary.

Example request:

Worked example · bash

```bash
curl -X POST "https://api.ebx.energy/v1/assets/{asset_id}/markets/afrr/energy/bids" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer <access_token>" \
    -d '{
        "mode": "REPLACE",
        "replace_scope": {
            "start_time": "2025-01-03T10:00:00Z",
            "end_time": "2025-01-03T11:00:00Z",
            "product": "pos"
        },
        "bids": [
            {
                "energy_price_eur_per_mwh": -100.0,
                "offered_power_mw": 120,
                "start_time": "2025-01-03T10:00:00Z",
                "end_time": "2025-01-03T10:15:00Z",
                "product": "pos",
                "idempotency_key": "example-idempotency-key"
            },
            {
                "energy_price_eur_per_mwh": -95.0,
                "offered_power_mw": 110,
                "start_time": "2025-01-03T10:15:00Z",
                "end_time": "2025-01-03T10:30:00Z",
                "product": "pos",
                "idempotency_key": "example-idempotency-key-2"
            }
        ]
    }'
```

In the example above, all pending `pos` aFRR energy bids inside the one-hour scope are deleted first. Only the two provided quarter-hours are recreated. Any other quarter-hour in that scope remains deleted.

Idempotency is per bid using `idempotency_key` on each bid object. Scope is defined by the endpoint plus bid interval/product (`start_time`, `end_time`, `product`). Retrying the same key in the same scope returns the originally stored bid and no overwrite occurs. Reusing the same key for a different interval or product is treated as a different bid scope.

Bids for the energy market are accepted after the capacity market results are available (c.a. 09:30 AM CET/CEST) one day before delivery (D-1).

**Gate Closure Times:**

-   **EBX deadline (recommended)**: T-30 min before MTU — submitting before this gives us a buffer to forward your bid to the market.
-   **Regelleistung gate (enforced)**: T-25 min before MTU — submissions or updates for an MTU after this time are rejected with HTTP 409.

Submissions or updates between the EBX deadline and the Regelleistung gate are accepted but **not guaranteed** to be forwarded to the market in time.

**Prequalified capacity ceiling (enforced):** For each 15-minute delivery period and each direction (`pos`/`neg`), the power in this request plus the power already committed by your other **energy-market** bids must not exceed the asset's prequalified aFRR capacity. Bids with status `PENDING`, `SUBMITTED`, `SUCCESSFUL` or `FALLBACK` count as committed; `REJECTED`, `FAILED` and `CANCELLED` bids release their capacity. Capacity-market bids are counted separately and do not consume energy-market headroom.

If any period would be exceeded, the **entire request** is rejected with HTTP 409 and error code `AFRR_PREQUALIFIED_CAPACITY_EXCEEDED` — nothing is stored, including the bids that would have fit. The response detail lists every breached period with its direction, the total committed power, the ceiling, and the overshoot. In `mode=REPLACE`, the bids this request would delete are not counted against it — but note the clear has _not_ happened when the request is rejected, so a 409 leaves the existing bids in the scope exactly as they were. A prequalified capacity of `0` in a direction is enforced as a real limit of zero: no power may be committed in that direction, and every such bid is rejected. If you believe your asset's recorded prequalified capacity is wrong, contact EBX to have it corrected — the API will not bid past it.

`offered_power_mw` is in megawatts (MW). `energy_price_eur_per_mwh` is in EUR/MWh, and must be between -15,000 and 15,000 EUR/MWh. It follows the following cashflow convention:

-   `energy_price_eur_per_mwh < 0`: provider pays grid/TSO
-   `energy_price_eur_per_mwh >= 0`: provider receives money from grid/TSO

Bids are stored with status=PENDING and will be submitted to the market before gate closure. Once submitted, status moves to SUBMITTED and then to SUCCESSFUL or REJECTED based on the auction outcome. If a bid never reaches the market (e.g. an outage spanning gate closure) and the auction window has passed, it is marked FAILED. For aFRR energy specifically, if the auction itself fails to clear (RAM Fallback), the bid is marked FALLBACK and the TSO Ersatzpreis applies.

Path parameters

asset\_id · REQUIRED

string

Request body · required

bids · REQUIRED

array\[object\] · List of bids for the energy AFRR market.

mode

enum · default CREATE · `CREATE` · `REPLACE` · CREATE inserts bids. REPLACE deletes all pending bids fully contained in replace\_scope and then inserts only the provided bids.

replace\_scope

object · Required when mode=REPLACE. Defines the replacement window to clear before recreating the provided bids.

Example value

cURL:

```bash
curl ·   · -X ·  POST  · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/energy/bids" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN" ·  \
   · -H ·   · "Content-Type: application/json" ·  \
   · -d ·   · '{"bids":[{"idempotency_key":"<string>","start_time":"2026-09-10T13:30:00Z","end_time":"2026-09-10T13:30:00Z","product":"pos","energy_price_eur_per_mwh":35.8,"offered_power_mw":100}],"mode":"CREATE","replace_scope":{"start_time":"2026-09-10T13:30:00Z","end_time":"2026-09-10T13:30:00Z","product":"pos"}}'
```

Python:

```python
import ·  httpx

r = httpx.post(
     · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/energy/bids" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
    json= · { · 
         · "bids" · : ·   · [ · 
             · { · 
                 · "idempotency_key" · : ·   · "<string>" · , · 
                 · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
                 · "end_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
                 · "product" · : ·   · "pos" · , · 
                 · "energy_price_eur_per_mwh" · : ·   · 35.8 · , · 
                 · "offered_power_mw" · : ·   · 100 · , · 
             · }, · 
         · ], · 
         · "mode" · : ·   · "CREATE" · , · 
         · "replace_scope" · : ·   · { · 
             · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
             · "end_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
             · "product" · : ·   · "pos" · , · 
         · }, · 
     · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/energy/bids" · , ·   · { · 
   · method · : ·   · "POST" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
     · "Content-Type" · : ·   · "application/json" · , · 
   · }, · 
   · body · : ·  JSON.stringify( · { · "bids" · :[{ · "idempotency_key" · : · "<string>" · , · "start_time" · : · "2026-09-10T13:30:00Z" · , · "end_time" · : · "2026-09-10T13:30:00Z" · , · "product" · : · "pos" · , · "energy_price_eur_per_mwh" · : · 35.8 · , · "offered_power_mw" · : · 100 · }], · "mode" · : · "CREATE" · , · "replace_scope" · :{ · "start_time" · : · "2026-09-10T13:30:00Z" · , · "end_time" · : · "2026-09-10T13:30:00Z" · , · "product" · : · "pos" · }} · ) · , · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 201

```json
{ · 
   · "bids" · : ·   · [ · 
     · { · 
       · "id" · : ·   · "00000000-0000-0000-0000-000000000000" · , · 
       · "idempotency_key" · : ·   · "<string>" · , · 
       · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "end_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "product" · : ·   · "pos" · , · 
       · "energy_price_eur_per_mwh" · : ·   · 35.8 · , · 
       · "offered_power_mw" · : ·   · 100 · , · 
       · "last_edit_attempt" · : ·   · { · 
         · "edit_type" · : ·   · "MODIFY" · , · 
         · "status" · : ·   · "PENDING_RESYNC" · , · 
         · "attempted_at" · : ·   · "2026-09-10T13:30:00Z" · , · 
         · "requested_values" · : ·   · "<string>" · , · 
         · "failure_reason" · : ·   · "<string>" · , · 
         · "failure_detail" · : ·   · "<string>" · 
       · } · 
     · } · 
   · ], · 
   · "created_count" · : ·   · 0 · , · 
   · "deleted_count" · : ·   · 0 · , · 
   · "deleted_bid_ids" · : ·   · [ · 
     · "00000000-0000-0000-0000-000000000000" · 
   · ], · 
   · "updated_count" · : ·   · 0 · , · 
   · "warnings" · : ·   · [ · 
     · "<string>" · 
   · ], · 
   · "market" · : ·   · "capacity" · 
 · }
```

Can raise

-   400 · malformed request
-   401 · no valid token
-   403 · scope missing
-   404 · unknown or not visible
-   409 · state conflict
-   422 · validation failed
-   429 · rate limited

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

· DELETE · /v1/assets/{asset\_id}/markets/afrr/energy/bids

### Bulk delete aFRR energy bids by interval

market.write

Bulk delete bids in the Automatic Frequency Restoration Reserve (aFRR) energy market by exact interval.

Matching is strict: only bids with exactly the same `start_time` and `end_time` are deleted. If `product` is omitted, both `pos` and `neg` bids are deleted.

**Gate Closure Times:**

-   **EBX deadline (recommended)**: T-30 min before MTU — deleting before this gives us a buffer to forward your deletion to the market.
-   **Regelleistung gate (enforced)**: T-25 min before MTU — deletions for an MTU after this time are rejected with HTTP 409.

Deletions submitted between the EBX deadline and the Regelleistung gate are accepted but **not guaranteed** to be forwarded to the market in time.

Only bids with status=PENDING can be deleted. Once a bid has been submitted to the market, it cannot be deleted through this API.

Path parameters

asset\_id · REQUIRED

string

Query parameters

start\_time · REQUIRED

string<date-time> · Exact interval start for deletion (UTC).

end\_time · REQUIRED

string<date-time> · Exact interval end for deletion (UTC).

product

enum · `pos` · `neg` · Optional direction filter.

Example value

cURL:

```bash
curl ·   · -X ·  DELETE  · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/energy/bids?start_time=2026-02-03T00:00:00Z&end_time=2026-02-04T00:00:00Z" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

r = httpx.delete(
     · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/energy/bids?start_time=2026-02-03T00:00:00Z&end_time=2026-02-04T00: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/markets/afrr/energy/bids?start_time=2026-02-03T00:00:00Z&end_time=2026-02-04T00:00:00Z" · , ·   · { · 
   · method · : ·   · "DELETE" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
   · }, · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "deleted_count" · : ·   · 0 · , · 
   · "deleted_bid_ids" · : ·   · [ · 
     · "00000000-0000-0000-0000-000000000000" · 
   · ] · 
 · }
```

Can raise

-   400 · malformed request
-   401 · no valid token
-   403 · scope missing
-   404 · unknown or not visible
-   409 · state conflict
-   422 · validation failed
-   429 · rate limited

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

· PUT · /v1/assets/{asset\_id}/markets/afrr/energy/bids/{bid\_id}

### Update an aFRR energy bid

market.write

Update bids in the Automatic Frequency Restoration Reserve (aFRR) energy market.

This endpoint allows you to modify existing bids for a specific market, date, time, and product.

You can update the bid by providing the `bid_id` in the URL path. This ID is obtained when the bid was created.

**Gate Closure Times:**

-   **EBX deadline (recommended)**: T-30 min before MTU — updating before this gives us a buffer to forward your update to the market.
-   **Regelleistung gate (enforced)**: T-25 min before MTU — updates for an MTU after this time are rejected with HTTP 409.

**Late edits (PENDING vs SUBMITTED bids):**

-   PENDING bids — the change is applied directly before the bid is submitted to the market. The response shows the updated bid with `last_edit_attempt=null`.
-   SUBMITTED bids (already in market, before the Regelleistung gate) — the bid row in the response keeps showing what Regelleistung currently has; the requested change is captured in `last_edit_attempt` with status `PENDING_RESYNC`. The market-operations-service forwards it to Regelleistung within ~1 minute. If the gate closes before the forwarding succeeds, `last_edit_attempt.status` becomes `FAILED_LATE_EDIT` and the original bid stays in the market.

`start_time`, `end_time`, and `product` cannot be changed after a bid has been submitted (the tender would change). Only `offered_power_mw` and `energy_price_eur_per_mwh` can be modified on a SUBMITTED bid.

For PENDING bids, a changed `start_time`/`end_time` must match a valid bidding window in the market calendar — otherwise the request is rejected with HTTP 422 and suggested valid intervals, exactly as on bid creation.

**Prequalified capacity ceiling (enforced):** Raising `offered_power_mw` is rejected with HTTP 409 and error code `AFRR_PREQUALIFIED_CAPACITY_EXCEEDED` if the new value would push the total committed energy-market power above the asset's prequalified aFRR capacity for this bid's direction and delivery period. This bid's own current power is not counted against the request, so a bid may always be raised to consume the headroom it already holds. Nothing is written when the check fails — for a SUBMITTED bid, no edit attempt is recorded either. The check is skipped when the asset's prequalified capacity for that direction is `0`, meaning it has not been recorded.

Specifying the `idempotency_key` will overwrite the existing idempotency key for the bid (PENDING bids only).

Path parameters

asset\_id · REQUIRED

string

bid\_id · REQUIRED

string<uuid> · Bid ID to update

Request body · required

idempotency\_key

string · Optional idempotency key. Deduplication is scoped to the bid delivery scope within the endpoint (start/end interval, and product for aFRR).

start\_time · REQUIRED

string<date-time> · The start time for the time window for the bids in ISO 8601 format (UTC, 15-minute aligned)

end\_time · REQUIRED

string<date-time> · The end time for the time window for the bids in ISO 8601 format (UTC, 15-minute aligned)

product · REQUIRED

enum · `pos` · `neg`

energy\_price\_eur\_per\_mwh · REQUIRED

number | string · The price of the offered energy in EUR/MWh (max 2 decimal places). May be negative — paying to absorb energy is a legitimate offer. Rejected with 422 `PRICE_OUT_OF_RANGE` outside the configured market range (-15000 to 15000 EUR/MWh by default).

offered\_power\_mw · REQUIRED

integer · The power offered in MW (integer values only, min 1 MW). While this is an energy market, bids specify power capacity available for activation.

Example value

cURL:

```bash
curl ·   · -X ·  PUT  · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/energy/bids/00000000-0000-0000-0000-000000000000" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN" ·  \
   · -H ·   · "Content-Type: application/json" ·  \
   · -d ·   · '{"idempotency_key":"<string>","start_time":"2026-09-10T13:30:00Z","end_time":"2026-09-10T13:30:00Z","product":"pos","energy_price_eur_per_mwh":35.8,"offered_power_mw":100}'
```

Python:

```python
import ·  httpx

r = httpx.put(
     · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/energy/bids/00000000-0000-0000-0000-000000000000" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
    json= · { · 
         · "idempotency_key" · : ·   · "<string>" · , · 
         · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
         · "end_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
         · "product" · : ·   · "pos" · , · 
         · "energy_price_eur_per_mwh" · : ·   · 35.8 · , · 
         · "offered_power_mw" · : ·   · 100 · , · 
     · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/energy/bids/00000000-0000-0000-0000-000000000000" · , ·   · { · 
   · method · : ·   · "PUT" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
     · "Content-Type" · : ·   · "application/json" · , · 
   · }, · 
   · body · : ·  JSON.stringify( · { · "idempotency_key" · : · "<string>" · , · "start_time" · : · "2026-09-10T13:30:00Z" · , · "end_time" · : · "2026-09-10T13:30:00Z" · , · "product" · : · "pos" · , · "energy_price_eur_per_mwh" · : · 35.8 · , · "offered_power_mw" · : · 100 · } · ) · , · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "bids" · : ·   · [ · 
     · { · 
       · "id" · : ·   · "00000000-0000-0000-0000-000000000000" · , · 
       · "idempotency_key" · : ·   · "<string>" · , · 
       · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "end_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "product" · : ·   · "pos" · , · 
       · "energy_price_eur_per_mwh" · : ·   · 35.8 · , · 
       · "offered_power_mw" · : ·   · 100 · , · 
       · "last_edit_attempt" · : ·   · { · 
         · "edit_type" · : ·   · "MODIFY" · , · 
         · "status" · : ·   · "PENDING_RESYNC" · , · 
         · "attempted_at" · : ·   · "2026-09-10T13:30:00Z" · , · 
         · "requested_values" · : ·   · "<string>" · , · 
         · "failure_reason" · : ·   · "<string>" · , · 
         · "failure_detail" · : ·   · "<string>" · 
       · } · 
     · } · 
   · ], · 
   · "warnings" · : ·   · [ · 
     · "<string>" · 
   · ], · 
   · "market" · : ·   · "capacity" · 
 · }
```

Can raise

-   400 · malformed request
-   401 · no valid token
-   403 · scope missing
-   404 · unknown or not visible
-   409 · state conflict
-   422 · validation failed
-   429 · rate limited

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

· DELETE · /v1/assets/{asset\_id}/markets/afrr/energy/bids/{bid\_id}

### Delete aFRR energy bid by ID

market.write

Delete a bid in the Automatic Frequency Restoration Reserve (aFRR) energy market.

Use the bid ID that was returned when the bids were placed to delete a specific bid.

**Gate Closure Times:**

-   **EBX deadline (recommended)**: T-30 min before MTU — deleting before this gives us a buffer to forward your deletion to the market.
-   **Regelleistung gate (enforced)**: T-25 min before MTU — deletions for an MTU after this time are rejected with HTTP 409.

**Late deletes (PENDING vs SUBMITTED bids):**

-   PENDING bids — the row is removed from the database. Response: `deleted=true`, `last_edit_attempt=null`.
-   SUBMITTED bids (already in market, before the Regelleistung gate) — the bid stays in the database (it mirrors what Regelleistung currently has) and a deletion attempt is queued. Response: `deleted=false`, `last_edit_attempt.status=PENDING_RESYNC`. The market-operations-service forwards the deletion to Regelleistung within ~1 minute. If the gate closes before the forwarding succeeds, `last_edit_attempt.status` becomes `FAILED_LATE_EDIT` and the original bid stays in the market.

Path parameters

asset\_id · REQUIRED

string

bid\_id · REQUIRED

string<uuid> · Bid ID to delete

Example value

cURL:

```bash
curl ·   · -X ·  DELETE  · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/energy/bids/00000000-0000-0000-0000-000000000000" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

r = httpx.delete(
     · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/energy/bids/00000000-0000-0000-0000-000000000000" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/afrr/energy/bids/00000000-0000-0000-0000-000000000000" · , ·   · { · 
   · method · : ·   · "DELETE" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
   · }, · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "bid_id" · : ·   · "00000000-0000-0000-0000-000000000000" · , · 
   · "deleted" · : ·   · false · , · 
   · "last_edit_attempt" · : ·   · { · 
     · "edit_type" · : ·   · "MODIFY" · , · 
     · "status" · : ·   · "PENDING_RESYNC" · , · 
     · "attempted_at" · : ·   · "2026-09-10T13:30:00Z" · , · 
     · "requested_values" · : ·   · "<string>" · , · 
     · "failure_reason" · : ·   · "<string>" · , · 
     · "failure_detail" · : ·   · "<string>" · 
   · } · 
 · }
```

Can raise

-   400 · malformed request
-   401 · no valid token
-   403 · scope missing
-   404 · unknown or not visible
-   409 · state conflict
-   429 · rate limited

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

· GET · /v1/assets/{asset\_id}/markets/afrr/energy/bids/intervals

### Get valid aFRR energy bid intervals

market.read

Discover valid bid intervals for aFRR energy market.

Returns a list of time intervals during which energy bids can be submitted. Use this endpoint to find valid `start_time` and `end_time` values for your bid submissions.

**Important: Daylight Saving Time (DST) Handling**

Bid intervals are always specified in UTC. During DST transitions, the number of quarter-hour periods in a day may vary:

-   **Spring forward**: The day has 92 quarter-hours instead of 96.
-   **Fall back**: The day has 100 quarter-hours instead of 96.

Always use this discovery endpoint to find the correct intervals, especially around DST transition dates.

**Query Parameters:**

-   `date`: Filter by delivery date (YYYY-MM-DD). If not provided, returns intervals for the next 48 hours.

Path parameters

asset\_id · REQUIRED

string

Query parameters

date

string<date> · Filter intervals by delivery date (YYYY-MM-DD). If not provided, returns intervals for the next 7 days.

Example value

cURL:

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

Python:

```python
import ·  httpx

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

TypeScript:

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

Example response · 200

```json
{ · 
   · "intervals" · : ·   · [ · 
     · { · 
       · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "end_time" · : ·   · "2026-09-10T13:30:00Z" · 
     · } · 
   · ] · 
 · }
```

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}/markets/afrr/energy/results

### Get aFRR energy results

market.read

Get aFRR results in the energy market.

Use `start_time` and/or `end_time` (UTC ISO8601) for overlap-based time filtering. With both values, the endpoint returns result rows whose bid interval overlaps the half-open window `[start_time, end_time)`. Results do not need to be fully contained in the window.

Boundary behavior:

-   a result ending exactly at `start_time` is excluded
-   a result starting exactly at `end_time` is excluded

If neither `start_time` nor `end_time` is provided, results default to the current UTC day (`00:00:00Z` to `00:00:00Z` next day).

**Status values:**

-   `PENDING` — bid created but not yet submitted to market
-   `SUBMITTED` — bid sent to market, awaiting results
-   `REJECTED` — bid was rejected by the market
-   `SUCCESSFUL` — bid was accepted by the market
-   `FAILED` — bid never reached the market (e.g. an outage spanning gate closure) and the auction window has passed; this is a terminal state with no settlement implication
-   `FALLBACK` — the market failed to clear (RAM Fallback) and the TSO Ersatzpreis applies for the delivery period
-   `CANCELLED` — the bid was withdrawn before the market closed, either by you or because the asset could no longer back it; it holds no capacity and has no settlement implication

The aFRR energy market is activation-based. The `energy_price_eur_per_mwh` field is the submitted offer price in EUR/MWh, while financial settlement is determined after delivery from the actual activated energy. This response exposes awarded/activated power and the submitted offer, not a final settlement price.

`accepted_power_mw` and `offered_power_mw` are in MW.

Path parameters

asset\_id · REQUIRED

string

Query parameters

start\_time

string<date-time> · Return results whose bid end\_time is strictly after this timestamp. With end\_time, the API matches result intervals overlapping the half-open window \[start\_time, end\_time). Results do not need to be fully contained in the window.

end\_time

string<date-time> · Return results whose bid start\_time is strictly before this timestamp. With start\_time, the API matches result intervals overlapping the half-open window \[start\_time, end\_time).

product

enum · `pos` · `neg` · Filter by product. Provide a single value: `pos` (aFRR+) or `neg` (aFRR-).

status

enum · `PENDING` · `SUBMITTED` · `REJECTED` · `SUCCESSFUL` · `FAILED` · `FALLBACK` · `CANCELLED` · Filter by bid status. Valid values: `pending`, `submitted`, `successful`, `rejected`, `failed`, `fallback`, `cancelled`.

Example value

cURL:

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

Python:

```python
import ·  httpx

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

TypeScript:

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

Example response · 200

```json
{ · 
   · "results" · : ·   · [ · 
     · { · 
       · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "end_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
       · "product" · : ·   · "pos" · , · 
       · "status" · : ·   · "PENDING" · , · 
       · "accepted_power_mw" · : ·   · 100 · , · 
       · "energy_price_eur_per_mwh" · : ·   · 35.8 · , · 
       · "offered_power_mw" · : ·   · 100 · , · 
       · "external_origin" · : ·   · false · 
     · } · 
   · ] · 
 · }
```

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)
