EBXv1

API reference

Markets · FCR

FCR bids for an asset, the valid bid intervals, and the auction results.

7 endpoints
GET/v1/assets/{asset_id}/markets/fcr/bids

Get FCR bids

market.read

Get bids for FCR (Frequency Containment Reserve) for a specific asset.

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

If no filters are provided, all bids will be returned.

Since FCR is symmetric, the product is not specified. The bids are for both positive and negative reserve.

Bids for the last 30 days can be retrieved.

Path parameters

asset_idREQUIRED
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. With start_time, the API matches bids overlapping the half-open window [start_time, end_time).
Example value
curl "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/fcr/bids" \
  -H "Authorization: Bearer $EBX_TOKEN"
Example response200
{
  "bids": [
    {
      "id": "00000000-0000-0000-0000-000000000000",
      "idempotency_key": "<string>",
      "start_time": "2026-09-10T13:30:00Z",
      "end_time": "2026-09-10T13:30:00Z",
      "capacity_price_eur_per_mw": 50.1,
      "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>"
      }
    }
  ]
}
Can raise
  • 401no valid token
  • 403scope missing
  • 404unknown or not visible
  • 422validation failed
  • 429rate limited
ALL CODES →
POST/v1/assets/{asset_id}/markets/fcr/bids

Submit FCR bids

market.write

Post bids for FCR (Frequency Containment Reserve) for a specific asset.

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, but does not need to match the entire window. Any block inside replace_scope that is not present in bids remains deleted.

Bids in the FCR market are symmetric, meaning that the same bid can be used for both positive and negative reserve.

Bids can be placed from 11:00 AM CET/CEST one week before the delivery day (i.e. D-7).

Gate Closure Times:

  • EBX deadline (recommended): D-1 07:30 CET — submitting before this gives us a buffer to forward your bid to the market.
  • Regelleistung gate (enforced): D-1 08: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.

The start_time and end_time fields are required in UTC format (ISO 8601). Time intervals are validated against the market calendar to ensure they match valid Regelleistung tender intervals. This correctly handles DST transitions.

Example request:

Worked examplebash
curl -X POST "https://api.ebx.energy/v1/assets/{asset_id}/markets/fcr/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"
    },
    "bids": [
        {
            "start_time": "2025-01-02T23:00:00Z",
            "end_time": "2025-01-03T03:00:00Z",
            "capacity_price_eur_per_mw": 50.10,
            "offered_power_mw": 100
        },
        {
            "start_time": "2025-01-03T03:00:00Z",
            "end_time": "2025-01-03T07:00:00Z",
            "capacity_price_eur_per_mw": 50.10,
            "offered_power_mw": 100
        }
    ]
}'

In the example above, all pending FCR bids between 2025-01-02T23:00:00Z and 2025-01-03T23:00:00Z are deleted first. Only the two provided blocks are recreated. Any other block in that window remains deleted.

Idempotency is per bid using idempotency_key on each bid object. Scope is defined by the endpoint and the bid interval (start_time, end_time). 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 is treated as a different bid scope.

When placing bids, the API validates that each bid interval matches a known tender from the market calendar. If the interval does not match, a 422 error is returned with suggested valid intervals.

Prequalified capacity ceiling (enforced): For each 15-minute delivery period, the power in this request plus the power already committed by your other FCR bids must not exceed the asset's prequalified FCR capacity, which is a single symmetric figure covering both directions. Bids with status PENDING, SUBMITTED, SUCCESSFUL or FALLBACK count as committed; REJECTED, FAILED and CANCELLED bids release their capacity. A partially awarded SUCCESSFUL bid counts only at the power it won.

If any period would be exceeded, the entire request is rejected with HTTP 409 and error code FCR_PREQUALIFIED_CAPACITY_EXCEEDED — nothing is stored, including the bids that would have fit. The response detail lists every breached period with 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 is enforced as a real limit of zero: no power may be committed at all, and every 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.

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 — query the result endpoints to inspect terminal status.

Path parameters

asset_idREQUIRED
string

Request body · required

bidsREQUIRED
array[object]
mode
enumdefault CREATECREATEREPLACECREATE inserts bids. REPLACE deletes all pending bids fully contained in replace_scope and then inserts only the provided bids.
replace_scope
objectRequired when mode=REPLACE. Defines the replacement window to clear before recreating the provided bids.
Example value
curl -X POST "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/fcr/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","capacity_price_eur_per_mw":50.1,"offered_power_mw":100}],"mode":"CREATE","replace_scope":{"start_time":"2026-09-10T13:30:00Z","end_time":"2026-09-10T13:30:00Z"}}'
Example response201
{
  "bids": [
    {
      "id": "00000000-0000-0000-0000-000000000000",
      "idempotency_key": "<string>",
      "start_time": "2026-09-10T13:30:00Z",
      "end_time": "2026-09-10T13:30:00Z",
      "capacity_price_eur_per_mw": 50.1,
      "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"
  ],
  "warnings": [
    "<string>"
  ],
  "updated_count": 0
}
Can raise
  • 400malformed request
  • 401no valid token
  • 403scope missing
  • 404unknown or not visible
  • 409state conflict
  • 422validation failed
  • 429rate limited
ALL CODES →
DELETE/v1/assets/{asset_id}/markets/fcr/bids

Delete FCR bids by time range

market.write

Delete bids for FCR (Frequency Containment Reserve) for a specific asset by time range.

Use the start_time and end_time fields to specify which bids to delete. Matching is strict: only bids with exactly the same start/end interval are deleted.

Gate Closure Times:

  • EBX deadline (recommended): D-1 07:30 CET — deleting before this gives us a buffer to forward your deletion to the market.
  • Regelleistung gate (enforced): D-1 08: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_idREQUIRED
string

Query parameters

start_time
string<date-time>Start time for filtering results
end_time
string<date-time>End time for filtering results
Example value
curl -X DELETE "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/fcr/bids" \
  -H "Authorization: Bearer $EBX_TOKEN"
Example response200
{
  "deleted_count": 0,
  "deleted_bid_ids": [
    "00000000-0000-0000-0000-000000000000"
  ]
}
Can raise
  • 400malformed request
  • 401no valid token
  • 403scope missing
  • 404unknown or not visible
  • 409state conflict
  • 422validation failed
  • 429rate limited
ALL CODES →
PUT/v1/assets/{asset_id}/markets/fcr/bids/{bid_id}

Update an FCR bid

market.write

Update bids in the Frequency Containment Reserve (FCR) 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 07:30 CET — updating before this gives us a buffer to forward your update to the market.
  • Regelleistung gate (enforced): D-1 08: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 to the bid before it 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 cannot be changed after a bid has been submitted (the tender would change). Only offered_power_mw and capacity_price_eur_per_mw 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 FCR_PREQUALIFIED_CAPACITY_EXCEEDED if the new value would push the total committed FCR power above the asset's prequalified FCR capacity in any 15-minute 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. A prequalified capacity of 0 is enforced as a real limit of zero, so no power may be committed at all.

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

Path parameters

asset_idREQUIRED
string
bid_idREQUIRED
string<uuid>Bid ID to update

Request body · required

idempotency_key
stringOptional idempotency key. Deduplication is scoped to the bid delivery scope within the endpoint (start/end interval, and product for aFRR).
start_timeREQUIRED
string<date-time>The start time for the bid in ISO 8601 format (UTC, 15-minute aligned)
end_timeREQUIRED
string<date-time>The end time for the bid in ISO 8601 format (UTC, 15-minute aligned)
capacity_price_eur_per_mwREQUIRED
number | stringThe 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); the limit is configuration, not part of this schema, so it can track the market.
offered_power_mwREQUIRED
integerThe amount of power offered in MW (integer values only, min 1 MW)
Example value
curl -X PUT "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/fcr/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","capacity_price_eur_per_mw":50.1,"offered_power_mw":100}'
Example response200
{
  "bids": [
    {
      "id": "00000000-0000-0000-0000-000000000000",
      "idempotency_key": "<string>",
      "start_time": "2026-09-10T13:30:00Z",
      "end_time": "2026-09-10T13:30:00Z",
      "capacity_price_eur_per_mw": 50.1,
      "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>"
  ]
}
Can raise
  • 400malformed request
  • 401no valid token
  • 403scope missing
  • 404unknown or not visible
  • 409state conflict
  • 422validation failed
  • 429rate limited
ALL CODES →
DELETE/v1/assets/{asset_id}/markets/fcr/bids/{bid_id}

Delete an FCR bid by ID

market.write

Delete bids for FCR (Frequency Containment Reserve) for a specific asset.

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 07:30 CET — deleting before this gives us a buffer to forward your deletion to the market.
  • Regelleistung gate (enforced): D-1 08: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_idREQUIRED
string
bid_idREQUIRED
string<uuid>Bid ID to delete
Example value
curl -X DELETE "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/fcr/bids/00000000-0000-0000-0000-000000000000" \
  -H "Authorization: Bearer $EBX_TOKEN"
Example response200
{
  "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
  • 400malformed request
  • 401no valid token
  • 403scope missing
  • 404unknown or not visible
  • 409state conflict
  • 429rate limited
ALL CODES →
GET/v1/assets/{asset_id}/markets/fcr/bids/intervals

Get valid FCR bid intervals

market.read

Discover valid bid intervals for FCR (Frequency Containment Reserve).

Returns a list of time intervals during which 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_idREQUIRED
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 "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/fcr/bids/intervals" \
  -H "Authorization: Bearer $EBX_TOKEN"
Example response200
{
  "intervals": [
    {
      "start_time": "2026-09-10T13:30:00Z",
      "end_time": "2026-09-10T13:30:00Z"
    }
  ]
}
Can raise
  • 401no valid token
  • 403scope missing
  • 404unknown or not visible
  • 422validation failed
  • 429rate limited
ALL CODES →
GET/v1/assets/{asset_id}/markets/fcr/results

Get FCR results

market.read

Get the results for FCR (Frequency Containment Reserve) for a specific asset for a specific date.

Results for the bids are available c.a. 08:30AM CET/CEST one day before delivery day (i.e. D - 1). It cannot be guaranteed that results will be available at this time, as some results may be delayed due to external factors.

Use start_time and/or end_time to filter results by interval overlap. 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

You can additionally filter by bid_id or status. If no filters are provided, all results will be returned.

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

The response contains a list of results for the bids. The status field indicates whether the bid was accepted. The accepted_power_mw field indicates the amount of power that was accepted in MW. The capacity_price_eur_per_mw field indicates the offered bid price in EUR/MW. The offered_power_mw field indicates the amount of power that was offered in MW. The clearing_price_eur_per_mw field indicates the FCR clearing price in EUR/MW for the accepted power.

In Germany, FCR capacity is settled pay-as-clear. The capacity_price_eur_per_mw field is the customer's offered bid price, while the clearing_price_eur_per_mw field is the settlement-relevant market clearing price for awarded capacity.

FCR has no separate balancing-energy settlement in this API response. Remuneration is represented via the awarded capacity and its clearing price.

The top-level start_time and end_time in the response describe the span of the returned result intervals, not necessarily the exact query window.

Path parameters

asset_idREQUIRED
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).
bid_id
string<uuid>Unique identifier for the bid
status
enumPENDINGSUBMITTEDREJECTEDSUCCESSFULFAILEDFALLBACKCANCELLEDFilter by bid status. Valid values: pending, submitted, successful, rejected, failed, cancelled.
Example value
curl "https://api.ebx.energy/v1/assets/DE_BESS_01/markets/fcr/results" \
  -H "Authorization: Bearer $EBX_TOKEN"
Example response200
{
  "start_time": "2026-09-10T13:30:00Z",
  "end_time": "2026-09-10T13:30:00Z",
  "results": [
    {
      "start_time": "2026-09-10T13:30:00Z",
      "end_time": "2026-09-10T13:30:00Z",
      "status": "PENDING",
      "accepted_power_mw": 100,
      "capacity_price_eur_per_mw": 50.1,
      "offered_power_mw": 100,
      "clearing_price_eur_per_mw": 50.1,
      "external_origin": false
    }
  ]
}
Can raise
  • 401no valid token
  • 403scope missing
  • 404unknown or not visible
  • 422validation failed
  • 429rate limited
ALL CODES →

Send feedback

This goes straight to the docs team on Slack, with the page you are on. It is not attributed to you, so say who you are if you would like an answer.

0/2000