EBXv1

API reference

Dispatch

Telling an asset what to do: immediate dispatch and its history, scheduled dispatch and the anticipated dispatch forecast. Immediate dispatch is an unrestricted override, so read its description before using it.

6 endpoints
GET/v1/assets/{asset_id}/dispatch/immediate

Get immediate dispatch history

dispatch.read

Get a history of immediate dispatch issued for an asset.

Time filtering is overlap-based and uses half-open window semantics. With both start_time and end_time, the endpoint returns dispatch intervals that overlap [start_time, end_time).

Boundary behavior:

  • a dispatch ending exactly at start_time is excluded
  • a dispatch starting exactly at end_time is excluded

set_power_mw is the dispatch set point in MW. Positive values correspond to injection into the grid, negative values to absorption from the grid.

History is limited to the last 30 days.

Path parameters

asset_idREQUIRED
string

Query parameters

sort_by
enumstart_timeend_timeField to sort the results by
sort_order
enumascdescOrder to sort the results by, either 'asc' or 'desc'
start_time
string<date-time>Return immediate dispatch intervals whose end_time is strictly after this timestamp. With end_time, the API matches intervals overlapping the half-open window [start_time, end_time).
end_time
string<date-time>Return immediate dispatch intervals whose start_time is strictly before this timestamp. With start_time, the API matches intervals overlapping the half-open window [start_time, end_time).
Example value
curl "https://api.ebx.energy/v1/assets/DE_BESS_01/dispatch/immediate" \
  -H "Authorization: Bearer $EBX_TOKEN"
Example response200
{
  "dispatches": [
    {
      "start_time": "2026-09-10T13:30:00Z",
      "end_time": "2026-09-10T13:30:00Z",
      "set_power_mw": 0
    }
  ]
}
Can raise
  • 401no valid token
  • 403scope missing
  • 404unknown or not visible
  • 422validation failed
  • 429rate limited
ALL CODES →
POST/v1/assets/{asset_id}/dispatch/immediate

Set immediate dispatch power (unrestricted override)

dispatch.write

Override the dispatch of an asset for a bounded window, bypassing every safety safeguard.

Unrestricted emergency override — use with extreme care.

This endpoint deliberately bypasses every platform safeguard: declared unavailabilities, power limits, and regulatory or market restrictions are neither checked nor enforced. The platform attempts to execute the dispatch regardless of the asset's declared state, schedule, or market obligations. Executing it can violate market regulations and cause system imbalances. The caller carries full responsibility for ensuring the requested set point is physically safe for the asset and permissible in the current situation. Use only when strictly necessary, e.g. on explicit TSO instruction or in an emergency.

Behavior:

  • The dispatch becomes active at start_time (defaults to now if omitted) and runs until end_time (required).
  • At end_time, the asset is automatically reset to its currently scheduled wholesale power. Internally, two events are published: an enable at start_time and an automatic reset at end_time that queries the current schedule and dispatches it.
  • While an immediate dispatch is active, conflicting wholesale schedule events for the same asset are rejected by the dispatcher.
  • Submitting a new request while an immediate dispatch is already active will override the existing one.

Constraints (request validation and one plausibility bound — none are safety checks):

  • set_power_mw must not exceed the asset's usable_power_capacity in magnitude (spec ID-04). This is a static sanity bound, not a safety check: it refuses a setpoint the asset could not physically produce under any circumstances — a typo of 500 instead of 50 — and consults nothing about the asset's live state, obligations or restrictions. Until now this endpoint had no magnitude bound at all. While the asset is in phase 1 of the validation rollout (strict_validation false) a breach is reported in warnings and the dispatch is still stored; in phase 2 it is rejected. The historical 2x-capacity bound is always rejected. An asset with no recorded capacity is not refused — the gap is logged instead, since declining an emergency override over a missing parameter would be worse than not bounding it.
  • end_time is required and must be in the future.
  • start_time is optional. If provided, it must not be more than 1 second in the past (this allowance covers round-trip latency only and prevents backdating).
  • The window end_time - start_time must be at least the configured minimum (IMMEDIATE_DISPATCH_MIN_WINDOW_SECONDS, default 10s). Requests with a shorter effective window are rejected with 400.

set_power_mw is the dispatch set point in MW. Positive values correspond to injection into the grid, negative values to absorption from the grid.

Path parameters

asset_idREQUIRED
string

Request body · required

start_time
string<date-time>Optional start time of the dispatch in UTC. Defaults to the server's current time when omitted, and must be within 1s of it — immediate dispatches always start now; there is no future scheduling.
end_timeREQUIRED
string<date-time>End time of the dispatch in UTC. Required.
set_power_mwREQUIRED
numberSet point for the dispatch in MW. Positive corresponds to injection of energy into the grid, negative corresponds to absorption of energy from the grid.
Example value
curl -X POST "https://api.ebx.energy/v1/assets/DE_BESS_01/dispatch/immediate" \
  -H "Authorization: Bearer $EBX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"start_time":"2026-09-10T13:30:00Z","end_time":"2026-09-10T13:30:00Z","set_power_mw":55.1}'
Example response200
{
  "start_time": "2026-09-10T13:30:00Z",
  "end_time": "2026-09-10T13:30:00Z",
  "set_power_mw": 0,
  "warnings": [
    "<string>"
  ]
}
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}/dispatch/immediate/disable

Disable immediate dispatch

dispatch.write

Disable the active immediate dispatch for a specific asset.

Sets the active dispatch's end_time to the current time; the dispatcher derives the reset from the operational-state snapshot and restores the scheduled wholesale power. Returns the now-closed dispatch record. Returns 404 if no dispatch was active.

Path parameters

asset_idREQUIRED
string
Example value
curl -X PUT "https://api.ebx.energy/v1/assets/DE_BESS_01/dispatch/immediate/disable" \
  -H "Authorization: Bearer $EBX_TOKEN"
Example response200
{
  "start_time": "2026-09-10T13:30:00Z",
  "end_time": "2026-09-10T13:30:00Z",
  "set_power_mw": 0
}
Can raise
  • 400malformed request
  • 401no valid token
  • 403scope missing
  • 404unknown or not visible
  • 409state conflict
  • 429rate limited
ALL CODES →
GET/v1/assets/{asset_id}/dispatch/scheduled

Get scheduled dispatch

dispatch.read

Get the current dispatch schedule for an asset.

The schedule is returned for the specified date and time range. If no start or end time is provided, the entire day is considered.

The returned schedule provides a continuous view of the asset's dispatch schedule. For each schedule event, the response includes the power in MW, delivery day, and start time of the delivery. The power is held same until the next schedule event within the same 15-minute block interval.

Deliver DayDelivery Block Start TimeStart TimePower (MW)
2025-01-0100:00:0000:00:000
2025-01-0100:00:0000:09:0010
2025-01-0100:30:0000:30:00-20
2025-01-0100:30:0000:32:00-5
2025-01-0100:45:0000:45:000
2025-01-0101:00:0001:00:0030

At 00:00, the power is 0 MW until 00:09, when it changes to 10 MW. At 00:15, the power is reset to 0 MW as we move to the next 15-minute block. At 00:30, the power changes to -20 MW and remains until 00:32, when it changes to -5 MW. At 00:45, the power is set to 0 MW and held until 01:00, when it changes to 30 MW. At 01:15, the power is reset to 0 MW as we move to the next 15-minute block.

Querying can be done exclusively on 15-minute block intervals (i.e. on 15 minute marks, e.g. between 00:00:00 and 18:45:00, but not between 00:10:00 and 18:32:00).

set_power_mw (deprecated alias of bess_power_mw) is the scheduled BESS power in MW for each delivery time slot. Until per-mode persistence lands, responses report control_mode=bess_only and poc_power_mw=null for all events.

Path parameters

asset_idREQUIRED
string

Query parameters

start_time
string<date-time>Start Time in ISO8601 format
end_time
string<date-time>End Time in ISO8601 format
Example value
curl "https://api.ebx.energy/v1/assets/DE_BESS_01/dispatch/scheduled" \
  -H "Authorization: Bearer $EBX_TOKEN"
Example response200
{
  "schedules": [
    {
      "control_mode": "passive",
      "set_power_mw": 0,
      "bess_power_mw": 0,
      "poc_power_mw": 0,
      "delivery_time": "2026-09-10T13:30:00Z",
      "set_time": "2026-09-10T13:30:00Z"
    }
  ],
  "warnings": [
    "<string>"
  ]
}
Can raise
  • 401no valid token
  • 403scope missing
  • 404unknown or not visible
  • 422validation failed
  • 429rate limited
ALL CODES →
PUT/v1/assets/{asset_id}/dispatch/scheduled

Update scheduled dispatch

dispatch.write

Update the scheduled dispatch for a specific asset.

The schedule is a list of targets: a BESS power in MW (bess_power_mw; the former power_mw is a deprecated alias) and the time from which it applies (delivery_time). The asset's power is steered towards the most recent target at the asset's default ramp rate. Targets can be submitted at up to per-second resolution (sub-second precision is truncated), e.g. to make the asset ramp slower than its default rate.

Control modes (co-located PV+BESS sites): each target carries a control_mode deciding which setpoints apply (sign convention: import/charging negative, export/discharging positive):

control_modebess_power_mwpoc_power_mw
passivemust be null/zeromust be null/zero
bess_only (default when omitted)requiredmust be null/zero
bess_and_pocrequiredrequired — PoC target has priority
poc_onlymust be null/zerorequired

Requests violating this matrix are rejected with 422. pv_power_mw is reserved and must be null. bess_and_poc and poc_only require a co-located asset.

Green co-location: where grid import is not permitted, poc_power_mw must be >= 0 — the battery may only charge from the co-located producer. Because bess_only treats the battery's power as the power reaching the grid, a charging bess_only target is rejected on such an asset: at scheduling time there is no way to show the energy came from the producer rather than the grid. To charge, use bess_and_poc with poc_power_mw=0, which pins the point of connection and therefore guarantees producer-only charging.

In bess_and_poc, bess_power_mw may not exceed poc_power_mw: the co-located producer is a source and cannot absorb a surplus.

Targets may span multiple 15-minute delivery blocks. Every block that a target lands in is overridden in full with the submitted targets; blocks not covered by the request are left untouched. At the start of each block the target resets to 0 MW unless a target is placed exactly at the block start.

The entire request is rejected when:

  1. any target is beyond the end of the next UTC day,
  2. any target lands in a delivery block starting in less than 6 minutes (gate closure),
  3. two targets overlap, i.e. fall within the same second,
  4. any target's magnitude is implausibly large (abs(power) > 2× the asset's usable power capacity) — a loose sanity check, not an availability check.

Note: Targets within the sanity bound are always accepted, even when they exceed the currently available power. During unavailability or power limits they are not rejected — they are clamped to the power available for the duration of the event.

Multi-product delivery: targets are additionally capped to the power available for wholesale: per direction, the asset's available power (including any power limits) reduced by the reserved FCR capacity scaled by the regulatory buffer and by the reserved aFRR capacity.

The dispatch outcome of each target — executed in full, clipped, rejected, or failed — can be reviewed after the fact via GET /assets/{asset_id}/reports/schedule/dispatches.

Path parameters

asset_idREQUIRED
string

Request body · required

schedulesREQUIRED
array[object]List of scheduled power events
Example value
curl -X PUT "https://api.ebx.energy/v1/assets/DE_BESS_01/dispatch/scheduled" \
  -H "Authorization: Bearer $EBX_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"schedules":[{"control_mode":"passive","power_mw":0,"bess_power_mw":0,"poc_power_mw":0,"pv_power_mw":0,"delivery_time":"2026-09-10T13:30:00Z"}]}'
Example response200
{
  "schedules": [
    {
      "control_mode": "passive",
      "set_power_mw": 0,
      "bess_power_mw": 0,
      "poc_power_mw": 0,
      "delivery_time": "2026-09-10T13:30:00Z",
      "set_time": "2026-09-10T13:30:00Z"
    }
  ],
  "warnings": [
    "<string>"
  ]
}
Can raise
  • 400malformed request
  • 401no valid token
  • 403scope missing
  • 404unknown or not visible
  • 409state conflict
  • 422validation failed
  • 429rate limited
ALL CODES →
GET/v1/assets/{asset_id}/forecasts/anticipated_dispatch

Get anticipated dispatch forecast N seconds ahead

dispatch.read

Return the step-interpolated scheduled dispatch power (MW) at a future instant.

Step-interpolation uses the most recent scheduled event with set_time <= target. If no such event exists within the delivery block, the value defaults to 0 MW.

Path parameters

asset_idREQUIRED
string

Query parameters

seconds_into_the_futureREQUIRED
integerForecast horizon in seconds from now (max 1 day / 86_400 s)
Example value
curl "https://api.ebx.energy/v1/assets/DE_BESS_01/forecasts/anticipated_dispatch?seconds_into_the_future=900" \
  -H "Authorization: Bearer $EBX_TOKEN"
Example response200
{
  "set_time": "2026-09-10T13:30:00Z",
  "set_power_mw": 0
}
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