API reference
Authentication
The API is protected by OpenID Connect. Machine to machine integrations exchange a client ID and secret for an access token, and send that token as a bearer token on every request.
- Token endpoint
- https://auth.ebx.energy/oauth2/token
- Client auth
- client_secret_basic · client_secret_post
Get a token
You need two things before your first call: credentials you create once, and a short-lived access token you exchange them for. No request works without the token.
- 01
Create client credentials
In the Control Center under Organisation → Integrations, or via
POST /v1/integrations, create a machine-to-machine integration and copy its client ID and secret. The secret is shown once; an integration holds two secrets at a time so it can be rotated without downtime.No Control Center access yet? Ask your EBX contact, or request test access for instant test credentials.
- 02
Exchange them for an access token
POST the
client_credentialsgrant to the token endpoint. Bothclient_secret_basic(shown) andclient_secret_postare accepted.Token requestcurl -X POST "https://auth.ebx.energy/oauth2/token" \ -u "$EBX_CLIENT_ID:$EBX_CLIENT_SECRET" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=client_credentials"import httpx res = httpx.post( "https://auth.ebx.energy/oauth2/token", auth=(client_id, client_secret), data={"grant_type": "client_credentials"}, ) token = res.json()["access_token"]const res = await fetch("https://auth.ebx.energy/oauth2/token", { method: "POST", headers: { Authorization: `Basic ${btoa(`${clientId}:${clientSecret}`)}`, "Content-Type": "application/x-www-form-urlencoded", }, body: new URLSearchParams({ grant_type: "client_credentials" }), }); const { access_token } = await res.json();Token response{ "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjNiZTk...", "token_type": "Bearer", "expires_in": 3600, "scope": "asset.read dispatch.read dispatch.write" } - 03
Cache it and reuse it
The token is valid for 60 minutes. Cache it and send it on every request until it expires, then exchange again. Don't request a token per call.
Call the API
Send the access token in the Authorization header. A token only ever reaches the assets of its own organisation. Every endpoint in the reference states the scope it requires: a valid token missing that scope is rejected with 403, a missing or expired token with 401.
curl "https://api.ebx.energy/v1/users/me" \
-H "Authorization: Bearer $EBX_TOKEN"import httpx
res = httpx.get(
"https://api.ebx.energy/v1/users/me",
headers={"Authorization": f"Bearer {token}"},
)
print(res.json())const res = await fetch("https://api.ebx.energy/v1/users/me", {
headers: { Authorization: `Bearer ${token}` },
});
const me = await res.json();Scopes
Scopes are granted per integration in the Control Center and returned on the token. What each group unlocks:
Assets
asset.read · asset.write
Assets and their virtual segmentation, unavailability, power and energy limits, and backup-market defaults and bids.
Dispatch
dispatch.read · dispatch.write
Asset state and state history, and immediate or scheduled dispatch.
Markets
market.read · market.write
FCR and aFRR bids, the valid bid intervals and the auction results.
Restrictions
restrictions.review · restrictions.approve · restrictions.write_direct
Reviewing and approving restriction requests. write_direct applies a restriction without going through approval.
Alarms
alarm.read · alarm.write
Alarm history, active alarms and the rule catalogue; acknowledging and muting.
Onboarding
onboarding.read · onboarding.write
Onboarding workflows and their tasks: gates, DPL rows, RfI fields, documents and prequalification submission.
Reporting
report.read · invoice.read
Dispatch and performance reports, settlement over a range, and invoices.
Organisation
users.read · users.write · clients.read · clients.write
Users in your organisation and their scopes, and machine-to-machine integrations and their secrets.
Pools
pool.read · pool.write
Organisation pools and pool state. Beta.