API reference
Restriction requests
Restriction requests for your organisation. Submission, review and approval each require their own scope.
POST/v1/assets/{asset_id}/restriction_requests
Submit Restriction Request
asset.write
Required scopes: asset.write
Submit a new approval request for an asset restriction.
Path parameters
- asset_idREQUIRED
- string
Request body · required
- start_timeREQUIRED
- string<date-time>Start time of the requested interval
- end_time
- string<date-time>Optional end time of the requested interval
- reasonREQUIRED
- enum
maintenancefaultgrid_eventcommercialtestingoperationalotherReason a restriction (unavailability, power limit, energy limit) is being requested. - reason_description
- stringFree-text description of the reason
- action
- stringdefault create
- kind
- stringdefault power_limit
- upper_limit_mw
- numberUpper power limit in MW
- lower_limit_mw
- numberLower power limit in MW
curl -X POST "https://api.ebx.energy/v1/assets/DE_BESS_01/restriction_requests" \
-H "Authorization: Bearer $EBX_TOKEN" \
-H "Content-Type: application/json" \
-d '{"start_time":"2026-10-22T20:30:00Z","end_time":"2026-10-22T20:30:00Z","reason":"maintenance","reason_description":"<string>","action":"create","kind":"power_limit","upper_limit_mw":0,"lower_limit_mw":0}'import httpx
r = httpx.post(
"https://api.ebx.energy/v1/assets/DE_BESS_01/restriction_requests",
headers={"Authorization": f"Bearer {token}"},
json={
"start_time": "2026-10-22T20:30:00Z",
"end_time": "2026-10-22T20:30:00Z",
"reason": "maintenance",
"reason_description": "<string>",
"action": "create",
"kind": "power_limit",
"upper_limit_mw": 0,
"lower_limit_mw": 0,
},
)
print(r.json())const res = await fetch("https://api.ebx.energy/v1/assets/DE_BESS_01/restriction_requests", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"start_time":"2026-10-22T20:30:00Z","end_time":"2026-10-22T20:30:00Z","reason":"maintenance","reason_description":"<string>","action":"create","kind":"power_limit","upper_limit_mw":0,"lower_limit_mw":0}),
});
const data = await res.json();{
"id": "00000000-0000-0000-0000-000000000000",
"asset_id": "<string>",
"organization_id": "<string>",
"kind": "power_limit",
"action": "create",
"status": "pending",
"start_time": "2026-10-22T20:30:00Z",
"end_time": "2026-10-22T20:30:00Z",
"upper_limit_mw": 0,
"lower_limit_mw": 0,
"upper_limit_mwh": 0,
"lower_limit_mwh": 0,
"reason": "maintenance",
"reason_description": "<string>",
"target_start_time": "2026-10-22T20:30:00Z",
"target_end_time": "2026-10-22T20:30:00Z",
"requested_by": "<string>",
"requested_at": "2026-10-22T20:30:00Z",
"decided_by": "<string>",
"decided_at": "2026-10-22T20:30:00Z",
"decision_note": "<string>"
}- 400malformed request
- 401no valid token
- 403scope missing
- 404unknown or not visible
- 409state conflict
- 422validation failed
- 429rate limited
GET/v1/restriction_requests
List Restriction Requests
Required scopes: none (any authenticated caller)
List the restriction requests visible to the caller, newest first.
With restrictions.review: every request of the caller's organizations. With only asset.write: the requests the caller submitted. Without either scope: 403.
Query parameters
- asset_id
- stringFilter by asset
- status
- enum
pendingapprovedrejectedcancelledexpiredFilter by request status - kind
- enum
power_limitenergy_limitunavailabilityFilter by restriction kind
curl "https://api.ebx.energy/v1/restriction_requests" \
-H "Authorization: Bearer $EBX_TOKEN"import httpx
r = httpx.get(
"https://api.ebx.energy/v1/restriction_requests",
headers={"Authorization": f"Bearer {token}"},
)
print(r.json())const res = await fetch("https://api.ebx.energy/v1/restriction_requests", {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
},
});
const data = await res.json();{
"requests": [
{
"id": "00000000-0000-0000-0000-000000000000",
"asset_id": "<string>",
"organization_id": "<string>",
"kind": "power_limit",
"action": "create",
"status": "pending",
"start_time": "2026-10-22T20:30:00Z",
"end_time": "2026-10-22T20:30:00Z",
"upper_limit_mw": 0,
"lower_limit_mw": 0,
"upper_limit_mwh": 0,
"lower_limit_mwh": 0,
"reason": "maintenance",
"reason_description": "<string>",
"target_start_time": "2026-10-22T20:30:00Z",
"target_end_time": "2026-10-22T20:30:00Z",
"requested_by": "<string>",
"requested_at": "2026-10-22T20:30:00Z",
"decided_by": "<string>",
"decided_at": "2026-10-22T20:30:00Z",
"decision_note": "<string>"
}
]
}GET/v1/restriction_requests/{request_id}
Get Restriction Request
Required scopes: none (any authenticated caller)
Get one restriction request: any of the caller's organizations with restrictions.review, or one the caller submitted with asset.write.
Path parameters
- request_idREQUIRED
- string<uuid>
curl "https://api.ebx.energy/v1/restriction_requests/00000000-0000-0000-0000-000000000000" \
-H "Authorization: Bearer $EBX_TOKEN"import httpx
r = httpx.get(
"https://api.ebx.energy/v1/restriction_requests/00000000-0000-0000-0000-000000000000",
headers={"Authorization": f"Bearer {token}"},
)
print(r.json())const res = await fetch("https://api.ebx.energy/v1/restriction_requests/00000000-0000-0000-0000-000000000000", {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
},
});
const data = await res.json();{
"id": "00000000-0000-0000-0000-000000000000",
"asset_id": "<string>",
"organization_id": "<string>",
"kind": "power_limit",
"action": "create",
"status": "pending",
"start_time": "2026-10-22T20:30:00Z",
"end_time": "2026-10-22T20:30:00Z",
"upper_limit_mw": 0,
"lower_limit_mw": 0,
"upper_limit_mwh": 0,
"lower_limit_mwh": 0,
"reason": "maintenance",
"reason_description": "<string>",
"target_start_time": "2026-10-22T20:30:00Z",
"target_end_time": "2026-10-22T20:30:00Z",
"requested_by": "<string>",
"requested_at": "2026-10-22T20:30:00Z",
"decided_by": "<string>",
"decided_at": "2026-10-22T20:30:00Z",
"decision_note": "<string>"
}POST/v1/restriction_requests/{request_id}/approve
Approve Restriction Request
restrictions.approve
Required scopes: restrictions.approve
Approve a pending request and apply its change to live state.
Re-runs validation against the live tables; if validation fails, the request stays PENDING and an error is returned.
Path parameters
- request_idREQUIRED
- string<uuid>
Request body · required
- note
- stringOptional note shown back to the requester
curl -X POST "https://api.ebx.energy/v1/restriction_requests/00000000-0000-0000-0000-000000000000/approve" \
-H "Authorization: Bearer $EBX_TOKEN" \
-H "Content-Type: application/json" \
-d '{"note":"<string>"}'import httpx
r = httpx.post(
"https://api.ebx.energy/v1/restriction_requests/00000000-0000-0000-0000-000000000000/approve",
headers={"Authorization": f"Bearer {token}"},
json={
"note": "<string>",
},
)
print(r.json())const res = await fetch("https://api.ebx.energy/v1/restriction_requests/00000000-0000-0000-0000-000000000000/approve", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"note":"<string>"}),
});
const data = await res.json();{
"id": "00000000-0000-0000-0000-000000000000",
"asset_id": "<string>",
"organization_id": "<string>",
"kind": "power_limit",
"action": "create",
"status": "pending",
"start_time": "2026-10-22T20:30:00Z",
"end_time": "2026-10-22T20:30:00Z",
"upper_limit_mw": 0,
"lower_limit_mw": 0,
"upper_limit_mwh": 0,
"lower_limit_mwh": 0,
"reason": "maintenance",
"reason_description": "<string>",
"target_start_time": "2026-10-22T20:30:00Z",
"target_end_time": "2026-10-22T20:30:00Z",
"requested_by": "<string>",
"requested_at": "2026-10-22T20:30:00Z",
"decided_by": "<string>",
"decided_at": "2026-10-22T20:30:00Z",
"decision_note": "<string>"
}- 400malformed request
- 401no valid token
- 403scope missing
- 404unknown or not visible
- 409state conflict
- 422validation failed
- 429rate limited
POST/v1/restriction_requests/{request_id}/cancel
Cancel Restriction Request
asset.write
Required scopes: asset.write
Cancel a still-pending request. Allowed for the original requester or an EBX admin.
Path parameters
- request_idREQUIRED
- string<uuid>
Request body · required
- note
- stringOptional note shown back to the requester
curl -X POST "https://api.ebx.energy/v1/restriction_requests/00000000-0000-0000-0000-000000000000/cancel" \
-H "Authorization: Bearer $EBX_TOKEN" \
-H "Content-Type: application/json" \
-d '{"note":"<string>"}'import httpx
r = httpx.post(
"https://api.ebx.energy/v1/restriction_requests/00000000-0000-0000-0000-000000000000/cancel",
headers={"Authorization": f"Bearer {token}"},
json={
"note": "<string>",
},
)
print(r.json())const res = await fetch("https://api.ebx.energy/v1/restriction_requests/00000000-0000-0000-0000-000000000000/cancel", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"note":"<string>"}),
});
const data = await res.json();{
"id": "00000000-0000-0000-0000-000000000000",
"asset_id": "<string>",
"organization_id": "<string>",
"kind": "power_limit",
"action": "create",
"status": "pending",
"start_time": "2026-10-22T20:30:00Z",
"end_time": "2026-10-22T20:30:00Z",
"upper_limit_mw": 0,
"lower_limit_mw": 0,
"upper_limit_mwh": 0,
"lower_limit_mwh": 0,
"reason": "maintenance",
"reason_description": "<string>",
"target_start_time": "2026-10-22T20:30:00Z",
"target_end_time": "2026-10-22T20:30:00Z",
"requested_by": "<string>",
"requested_at": "2026-10-22T20:30:00Z",
"decided_by": "<string>",
"decided_at": "2026-10-22T20:30:00Z",
"decision_note": "<string>"
}- 400malformed request
- 401no valid token
- 403scope missing
- 404unknown or not visible
- 409state conflict
- 422validation failed
- 429rate limited
POST/v1/restriction_requests/{request_id}/reject
Reject Restriction Request
restrictions.approve
Required scopes: restrictions.approve
Reject a pending request.
Path parameters
- request_idREQUIRED
- string<uuid>
Request body · required
- note
- stringOptional note shown back to the requester
curl -X POST "https://api.ebx.energy/v1/restriction_requests/00000000-0000-0000-0000-000000000000/reject" \
-H "Authorization: Bearer $EBX_TOKEN" \
-H "Content-Type: application/json" \
-d '{"note":"<string>"}'import httpx
r = httpx.post(
"https://api.ebx.energy/v1/restriction_requests/00000000-0000-0000-0000-000000000000/reject",
headers={"Authorization": f"Bearer {token}"},
json={
"note": "<string>",
},
)
print(r.json())const res = await fetch("https://api.ebx.energy/v1/restriction_requests/00000000-0000-0000-0000-000000000000/reject", {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({"note":"<string>"}),
});
const data = await res.json();{
"id": "00000000-0000-0000-0000-000000000000",
"asset_id": "<string>",
"organization_id": "<string>",
"kind": "power_limit",
"action": "create",
"status": "pending",
"start_time": "2026-10-22T20:30:00Z",
"end_time": "2026-10-22T20:30:00Z",
"upper_limit_mw": 0,
"lower_limit_mw": 0,
"upper_limit_mwh": 0,
"lower_limit_mwh": 0,
"reason": "maintenance",
"reason_description": "<string>",
"target_start_time": "2026-10-22T20:30:00Z",
"target_end_time": "2026-10-22T20:30:00Z",
"requested_by": "<string>",
"requested_at": "2026-10-22T20:30:00Z",
"decided_by": "<string>",
"decided_at": "2026-10-22T20:30:00Z",
"decision_note": "<string>"
}- 400malformed request
- 401no valid token
- 403scope missing
- 404unknown or not visible
- 409state conflict
- 422validation failed
- 429rate limited
GET/v1/restrictions
List Restrictions
asset.read
Required scopes: asset.read
List every unavailability, power limit and energy limit of the caller's assets that overlaps [start_time, end_time).
One item per stored interval: an unavailability (a power limit pinned to 0/0) appears once, as kind=unavailability. The assets are the ones GET /v1/assets lists for the same caller.
Query parameters
- start_timeREQUIRED
- string<date-time>Start of the window (inclusive), in UTC ISO 8601 format
- end_timeREQUIRED
- string<date-time>End of the window (exclusive), in UTC ISO 8601 format; at most 366 days after start_time
curl "https://api.ebx.energy/v1/restrictions?start_time=2026-10-19T00:00:00Z&end_time=2026-11-19T00:00:00Z" \
-H "Authorization: Bearer $EBX_TOKEN"import httpx
r = httpx.get(
"https://api.ebx.energy/v1/restrictions?start_time=2026-10-19T00:00:00Z&end_time=2026-11-19T00:00:00Z",
headers={"Authorization": f"Bearer {token}"},
)
print(r.json())const res = await fetch("https://api.ebx.energy/v1/restrictions?start_time=2026-10-19T00:00:00Z&end_time=2026-11-19T00:00:00Z", {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
},
});
const data = await res.json();{
"restrictions": [
{
"asset_id": "<string>",
"asset_name": "<string>",
"kind": "power_limit",
"start_time": "2026-10-22T20:30:00Z",
"end_time": "2026-10-22T20:30:00Z",
"upper_limit_mw": 0,
"lower_limit_mw": 0,
"upper_limit_mwh": 0,
"lower_limit_mwh": 0,
"reason": "maintenance",
"reason_description": "<string>",
"created_at": "2026-10-22T20:30:00Z",
"created_by": "<string>",
"created_by_email": "<string>",
"created_by_integration": "<string>",
"batch_id": "00000000-0000-0000-0000-000000000000"
}
]
}