# Alarms

> Alarm history and active alarms per asset and per organisation, acknowledgement and muting, and the alarm rule catalogue.

API reference

Alarm history and active alarms per asset and per organisation, acknowledgement and muting, and the alarm rule catalogue.

13 endpoints

· GET · /v1/alarm-rules

### Get alarm-rule metadata catalog

alarm.read

This endpoint takes no parameters.

Example value

cURL:

```bash
curl ·   · "https://api.ebx.energy/v1/alarm-rules" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

r = httpx.get(
     · "https://api.ebx.energy/v1/alarm-rules" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
)
print(r.json())
```

TypeScript:

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

Example response · 200

```json
{ · 
   · "catalog_version" · : ·   · "<string>" · , · 
   · "generated_at" · : ·   · "<string>" · , · 
   · "rule_count" · : ·   · 0 · , · 
   · "rules" · : ·   · "<string>" · 
 · }
```

Can raise

-   401 · no valid token
-   403 · scope missing
-   429 · rate limited

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

 · GET · /v1/alarms

### List alarm history for an organization

alarm.read

Get alarm history for all assets in an organization.

Returns a paginated list of alarm events across all assets belonging to the organization. Results are ordered by timestamp (most recent first).

**Query Parameters:**

-   `start_time`: Start of the time range (required, ISO 8601 format)
-   `end_time`: End of the time range (required, ISO 8601 format)
-   `organization_id`: Target organization. Optional for users that map to exactly one organization — required for EBX admins and multi-org users.
-   `severity`: Filter by severity levels (optional, can specify multiple)
-   `event_type`: Filter by event types (optional, can specify multiple)
-   `limit`: Maximum number of alarms to return (default: 100, max: 1000)
-   `offset`: Offset for pagination (default: 0)

**Event Types:**

-   `alarm.opened`: New alarm opened
-   `alarm.resolved`: Alarm resolved (condition cleared)
-   `alarm.acknowledged`: Alarm acknowledged by user
-   `alarm.muted`: Alarm muted by user
-   `alarm.unmuted`: Alarm unmuted by user

**Performance Notes:**

-   Historical queries via Athena typically take 2-5 seconds
-   Queries across many assets may take longer
-   Use date ranges efficiently for better performance

Query parameters

start\_time · REQUIRED

string<date-time> · Start time for filtering results (ISO 8601 format)

end\_time · REQUIRED

string<date-time> · End time for filtering results (ISO 8601 format)

organization\_id

string · Target organization. Optional for single-org users; required for EBX admins and multi-org users.

severity

array\[enum\] · Filter by severity levels (can specify multiple)

event\_type

array\[enum\] · Filter by event types (e.g., alarm.opened, alarm.resolved)

limit

integer · default 100 · Maximum number of alarms to return

offset

integer · default 0 · Offset for pagination

Example value

cURL:

```bash
curl ·   · "https://api.ebx.energy/v1/alarms?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.get(
     · "https://api.ebx.energy/v1/alarms?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/alarms?start_time=2026-02-03T00:00:00Z&end_time=2026-02-04T00:00:00Z" · , ·   · { · 
   · method · : ·   · "GET" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
   · }, · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "alarms" · : ·   · [ · 
     · { · 
       · "event_id" · : ·   · "<string>" · , · 
       · "event_type" · : ·   · "alarm.opened" · , · 
       · "alarm_id" · : ·   · "<string>" · , · 
       · "alarm_key" · : ·   · "<string>" · , · 
       · "asset_id" · : ·   · "<string>" · , · 
       · "rule_id" · : ·   · "TELEMETRY-001" · , · 
       · "alarm_type" · : ·   · "<string>" · , · 
       · "severity" · : ·   · "INFO" · , · 
       · "message" · : ·   · "<string>" · , · 
       · "evidence" · : ·   · "<string>" · , · 
       · "timestamp" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "opened_at" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "resolved_at" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "date_partition" · : ·   · "<string>" · , · 
       · "muted" · : ·   · false · , · 
       · "acknowledged" · : ·   · false · , · 
       · "acknowledged_by" · : ·   · "<string>" · , · 
       · "acknowledged_at" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "user_id" · : ·   · "<string>" · , · 
       · "user_email" · : ·   · "<string>" · , · 
       · "notes" · : ·   · "<string>" · , · 
       · "mute_reason" · : ·   · "<string>" · , · 
       · "mute_expires_at" · : ·   · "2026-01-01T00:00:00Z" · 
     · } · 
   · ], · 
   · "total" · : ·   · 0 · , · 
   · "limit" · : ·   · 0 · , · 
   · "offset" · : ·   · 0 · 
 · }
```

Can raise

-   401 · no valid token
-   403 · scope missing
-   422 · validation failed
-   429 · rate limited

[ALL CODES →](https://docs.ebx.energy/reference/errors.md)· PUT · /v1/alarms/{alarm\_key}/acknowledge

### Acknowledge an alarm

alarm.write

Acknowledge an alarm.

**Path Parameters:**

-   `alarm_key`: The alarm key in format `asset_id:rule_id`

**Request Body:**

-   `notes`: Optional notes about the acknowledgment

**Note:** The acknowledge action is asynchronous. The state update will be reflected in subsequent queries and WebSocket updates.

Path parameters

alarm\_key · REQUIRED

string · Alarm key in format 'asset\_id:rule\_id'

Request body · required

notes

string · Optional notes about the acknowledgment.

Example value

cURL:

```bash
curl ·   · -X ·  PUT  · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/acknowledge" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN" ·  \
   · -H ·   · "Content-Type: application/json" ·  \
   · -d ·   · '{"notes":"<string>"}'
```

Python:

```python
import ·  httpx

r = httpx.put(
     · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/acknowledge" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
    json= · { · 
         · "notes" · : ·   · "<string>" · , · 
     · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/acknowledge" · , ·   · { · 
   · method · : ·   · "PUT" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
     · "Content-Type" · : ·   · "application/json" · , · 
   · }, · 
   · body · : ·  JSON.stringify( · { · "notes" · : · "<string>" · } · ) · , · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "event_id" · : ·   · "<string>" · , · 
   · "alarm_key" · : ·   · "<string>" · , · 
   · "acknowledged" · : ·   · true · , · 
   · "acknowledged_by" · : ·   · "<string>" · , · 
   · "acknowledged_at" · : ·   · "2026-01-01T00:00:00Z" · 
 · }
```

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)

· POST · /v1/alarms/{alarm\_key}/declare-asset-fault

### Declare an asset/EMS fault

alarm.write

Declare a clear asset/EMS fault for an open alarm.

A `notification` is accepted from human operators only: the L0 agent's machine identity may declare without one and is refused (403) otherwise — LLM text goes out only after a human reviewed it.

Effects, in order:

1.  The `asset_fault_notification` record is inserted (`pending`).
2.  The asset is set **unavailable** (reason `fault`) — synchronous and authoritative, committed together with the record. The window ends at `notification.unavailability_end` (the deadline the reviewed text states) or, without a notification, 8 hours from now.
3.  Events go out via EventBridge, fire-and-forget: one `partner.fault_notification` per selected contact _channel_ (email and/or Slack, resolved server-side from the contact directory; the reviewed `subject`/`body` are sent verbatim — one delivery per event), plus one `partner.fault_declared` audit event, always.
4.  The record's status is finalised.

Callable by an EBX operator (Cognito, `alarm.write`) or the autonomous L0 agent (an EBX M2M integration granted `alarm.write`); EBX-internal because it notifies the asset's contact directory. The agent always declares with `notification: null` — LLM text is sent only after a human reviewed it.

**Notification:** `null` declares the fault without notifying anyone. Otherwise `recipient_contact_ids` (at least one) must be contacts of the alarm's asset that have an email and/or Slack webhook, and `unavailability_end` must lie more than 30 min and at most 8 h (+5 min) ahead — else `422` (detail `stale_draft`: draft the message again). Both are checked before anything is written.

**Idempotency:** when the asset is already under an active FAULT unavailability, `already_declared=true` is returned with that window's real bounds and no second window is created — but the events are still emitted (idempotency keys dedup downstream) so a retry after a failed request still reaches the contacts.

**Response `notification_status`:** `requested` (every event accepted; `notified` lists the contacts with their channels), `not_requested` (no notification), or `failed` (at least one event was not accepted — the unavailability still applies; retry, the declaration is idempotent).

**Request Body:**

-   `alarm_id`: optional lifecycle id of the reviewed alarm. If it no longer matches the asset's current alarm for this rule, the request is rejected with `409` so a declaration is never applied to a different incident than the one reviewed.
-   `notes`: optional operator notes recorded on the unavailability
-   `notification`: `{language, subject, body, recipient_contact_ids, unavailability_end}` or `null`

**Path Parameters:**

-   `alarm_key`: The alarm key in format `asset_id:rule_id`

Path parameters

alarm\_key · REQUIRED

string · Alarm key in format 'asset\_id:rule\_id'

Request body · required

alarm\_id

string · Optimistic-concurrency token: the lifecycle id of the alarm whose evidence was reviewed. When set and it no longer matches the asset's current alarm for this rule, the request is rejected (409) so a declaration is never applied to — nor its message sent for — a different incident that re-fired in the meantime. Omitted by callers that act on current state (the L0 agent).

notes

string · Optional operator notes recorded on the unavailability.

notification · REQUIRED

object · The reviewed notification, or null to declare without notifying anyone (the window is then now + 8 h).

Example value

cURL:

```bash
curl ·   · -X ·  POST  · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/declare-asset-fault" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN" ·  \
   · -H ·   · "Content-Type: application/json" ·  \
   · -d ·   · '{"alarm_id":"<string>","notes":"<string>","notification":{"language":"de","subject":"<string>","body":"<string>","recipient_contact_ids":[0],"unavailability_end":"2026-09-10T13:30:00Z"}}'
```

Python:

```python
import ·  httpx

r = httpx.post(
     · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/declare-asset-fault" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
    json= · { · 
         · "alarm_id" · : ·   · "<string>" · , · 
         · "notes" · : ·   · "<string>" · , · 
         · "notification" · : ·   · { · 
             · "language" · : ·   · "de" · , · 
             · "subject" · : ·   · "<string>" · , · 
             · "body" · : ·   · "<string>" · , · 
             · "recipient_contact_ids" · : ·   · [ · 
                 · 0 · , · 
             · ], · 
             · "unavailability_end" · : ·   · "2026-09-10T13:30:00Z" · , · 
         · }, · 
     · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/declare-asset-fault" · , ·   · { · 
   · method · : ·   · "POST" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
     · "Content-Type" · : ·   · "application/json" · , · 
   · }, · 
   · body · : ·  JSON.stringify( · { · "alarm_id" · : · "<string>" · , · "notes" · : · "<string>" · , · "notification" · :{ · "language" · : · "de" · , · "subject" · : · "<string>" · , · "body" · : · "<string>" · , · "recipient_contact_ids" · :[ · 0 · ], · "unavailability_end" · : · "2026-09-10T13:30:00Z" · }} · ) · , · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "alarm_key" · : ·   · "<string>" · , · 
   · "asset_id" · : ·   · "<string>" · , · 
   · "declared_by" · : ·   · "<string>" · , · 
   · "unavailability_start" · : ·   · "2026-01-01T00:00:00Z" · , · 
   · "unavailability_end" · : ·   · "2026-01-01T00:00:00Z" · , · 
   · "already_declared" · : ·   · false · , · 
   · "notification_status" · : ·   · "pending" · , · 
   · "notified" · : ·   · [ · 
     · { · 
       · "contact_id" · : ·   · 0 · , · 
       · "name" · : ·   · "<string>" · , · 
       · "channels" · : ·   · [ · 
         · "email" · 
       · ] · 
     · } · 
   · ] · 
 · }
```

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/alarms/{alarm\_key}/fault-evidence

### Preview the evidence for an asset-fault declaration

alarm.write

Assemble the evidence for an open alarm without taking any action (never calls an LLM).

Returns the deterministic, evidence-backed facts (asset, rule and its catalog name, sustained duration, setpoint/return values, concurrent alarms), a Control Center deep link, the fixed unavailability length, the FAULT unavailability the asset is already under right now (`active_fault_hold`, null when none — a declaration then notifies against that hold instead of creating a new window), and the asset's contacts as selectable `recipients` (`notifiable` = has an email and/or Slack webhook; `is_emergency` contacts are pre-selected in the Control Center).

Used by the Control Center "Declare asset fault" modal and by the L0 agent to gather context; the message itself is drafted by `POST .../fault-message-draft`.

**Path Parameters:**

-   `alarm_key`: The alarm key in format `asset_id:rule_id`

Path parameters

alarm\_key · REQUIRED

string · Alarm key in format 'asset\_id:rule\_id'

Example value

cURL:

```bash
curl ·   · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/fault-evidence" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

r = httpx.get(
     · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/fault-evidence" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/fault-evidence" · , ·   · { · 
   · method · : ·   · "GET" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
   · }, · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "alarm_key" · : ·   · "<string>" · , · 
   · "asset_id" · : ·   · "<string>" · , · 
   · "asset_name" · : ·   · "<string>" · , · 
   · "tso" · : ·   · "<string>" · , · 
   · "rule_id" · : ·   · "TELEMETRY-001" · , · 
   · "rule_name" · : ·   · "<string>" · , · 
   · "severity" · : ·   · "INFO" · , · 
   · "facts" · : ·   · [ · 
     · "<string>" · 
   · ], · 
   · "deep_link" · : ·   · "<string>" · , · 
   · "sustained_seconds" · : ·   · 0 · , · 
   · "concurrent_alarm_rule_ids" · : ·   · [ · 
     · "<string>" · 
   · ], · 
   · "unavailability_hours" · : ·   · 0 · , · 
   · "active_fault_hold" · : ·   · { · 
     · "start_time" · : ·   · "2026-09-10T13:30:00Z" · , · 
     · "end_time" · : ·   · "2026-09-10T13:30:00Z" · 
   · }, · 
   · "recipients" · : ·   · [ · 
     · { · 
       · "contact_id" · : ·   · 0 · , · 
       · "name" · : ·   · "<string>" · , · 
       · "role" · : ·   · "asset_owner" · , · 
       · "company" · : ·   · "<string>" · , · 
       · "email" · : ·   · "<string>" · , · 
       · "phone" · : ·   · "<string>" · , · 
       · "has_slack" · : ·   · false · , · 
       · "is_emergency" · : ·   · false · , · 
       · "notifiable" · : ·   · false · 
     · } · 
   · ] · 
 · }
```

Can raise

-   401 · no valid token
-   403 · scope missing
-   404 · unknown or not visible
-   429 · rate limited

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

· POST · /v1/alarms/{alarm\_key}/fault-message-draft

### Draft the partner message for an asset-fault declaration

alarm.write

Draft the natural-language message (subject + plain-text body) a partner receives.

The facts are computed in code into a fact sheet; the ops-inbox narrator (an LLM under strict no-invention rules) writes the message from it in the requested language; the signature and reference footer are appended. The draft is a proposal: the operator reviews and edits it in the Control Center, and the declare endpoint sends exactly the reviewed text. LLM text never reaches a partner unreviewed — the L0 agent neither drafts nor notifies.

The draft quotes the deadline of the hold that applies: the asset's active FAULT unavailability when it is already under one (the L0 agent or an earlier declaration), else now + 8 h. It is returned as `unavailability_end` and must be sent back as `notification.unavailability_end` so the declaration is checked against exactly the instant the text states. An open-ended active hold has no deadline to quote: `422 open_ended_hold` (adjust it in the Availability tab first). `unverified_numbers` lists the numbers in the draft that do not appear in the evidence — advisory, for the operator to check before sending; nothing is rejected on that basis.

Takes tens of seconds. `503` when the narrator is not configured, `502` when it fails or returns an unusable draft — there is no fallback text; the operator writes the message.

**Request Body:**

-   `language`: `de` (default in the Control Center, formal "Sie") or `en`
-   `assessment`: an existing hedged hypothesis to build on (the L0 judge's); null from the modal

**Path Parameters:**

-   `alarm_key`: The alarm key in format `asset_id:rule_id`

Path parameters

alarm\_key · REQUIRED

string · Alarm key in format 'asset\_id:rule\_id'

Request body · required

language · REQUIRED

enum · `de` · `en` · Language of a partner fault notification (German is the default in the Control Center).

assessment

string · An existing hedged hypothesis (the L0 judge's) the draft builds on; null from the Control Center.

Example value

cURL:

```bash
curl ·   · -X ·  POST  · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/fault-message-draft" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN" ·  \
   · -H ·   · "Content-Type: application/json" ·  \
   · -d ·   · '{"language":"de","assessment":"<string>"}'
```

Python:

```python
import ·  httpx

r = httpx.post(
     · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/fault-message-draft" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
    json= · { · 
         · "language" · : ·   · "de" · , · 
         · "assessment" · : ·   · "<string>" · , · 
     · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/fault-message-draft" · , ·   · { · 
   · method · : ·   · "POST" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
     · "Content-Type" · : ·   · "application/json" · , · 
   · }, · 
   · body · : ·  JSON.stringify( · { · "language" · : · "de" · , · "assessment" · : · "<string>" · } · ) · , · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "language" · : ·   · "de" · , · 
   · "subject" · : ·   · "<string>" · , · 
   · "body" · : ·   · "<string>" · , · 
   · "unavailability_end" · : ·   · "2026-09-10T13:30:00Z" · , · 
   · "unverified_numbers" · : ·   · [ · 
     · "<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)

· GET · /v1/alarms/{alarm\_key}/incident

### Get the BetterStack incident status for an alarm

alarm.read

Return the BetterStack incident status for an alarm's current lifecycle.

Lets the Control Center show whether the on-call page is acknowledged — and whether a human or the L0 agent acknowledged it — reflecting acknowledgements made outside the portal too. Best-effort: returns `found=False` when the alarm has no live state, no incident was opened (not production-critical), or ops-inbox is unavailable, so the alarm view degrades instead of erroring.

Path parameters

alarm\_key · REQUIRED

string · Alarm key in format 'asset\_id:rule\_id'

Example value

cURL:

```bash
curl ·   · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/incident" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

r = httpx.get(
     · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/incident" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/incident" · , ·   · { · 
   · method · : ·   · "GET" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
   · }, · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "found" · : ·   · false · , · 
   · "incident_id" · : ·   · "<string>" · , · 
   · "status" · : ·   · "<string>" · , · 
   · "acknowledged" · : ·   · false · , · 
   · "acknowledged_by" · : ·   · "<string>" · , · 
   · "acknowledged_by_agent" · : ·   · false · , · 
   · "acknowledged_at" · : ·   · "<string>" · , · 
   · "started_at" · : ·   · "<string>" · , · 
   · "url" · : ·   · "<string>" · 
 · }
```

Can raise

-   401 · no valid token
-   403 · scope missing
-   404 · unknown or not visible
-   429 · rate limited

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

· PUT · /v1/alarms/{alarm\_key}/mute

### Mute an alarm

alarm.write

Mute an alarm.

Muted alarms are still recorded in the event log but are filtered from notification channels (SNS, PagerDuty). WebSocket connections still receive muted alarm events.

**Path Parameters:**

-   `alarm_key`: The alarm key in format `asset_id:rule_id`

**Request Body:**

-   `duration_minutes`: Duration to mute in minutes (1–10080, defaults to 60)
-   `reason`: Optional reason for muting

**Note:** The mute action is asynchronous.

Path parameters

alarm\_key · REQUIRED

string · Alarm key in format 'asset\_id:rule\_id'

Request body · required

duration\_minutes

integer · default 60 · Duration in minutes (1–10080). Defaults to one hour; every mute expires.

reason

string · Optional reason for muting the alarm.

Example value

cURL:

```bash
curl ·   · -X ·  PUT  · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/mute" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN" ·  \
   · -H ·   · "Content-Type: application/json" ·  \
   · -d ·   · '{"duration_minutes":60,"reason":"<string>"}'
```

Python:

```python
import ·  httpx

r = httpx.put(
     · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/mute" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
    json= · { · 
         · "duration_minutes" · : ·   · 60 · , · 
         · "reason" · : ·   · "<string>" · , · 
     · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/mute" · , ·   · { · 
   · method · : ·   · "PUT" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
     · "Content-Type" · : ·   · "application/json" · , · 
   · }, · 
   · body · : ·  JSON.stringify( · { · "duration_minutes" · : · 60 · , · "reason" · : · "<string>" · } · ) · , · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "event_id" · : ·   · "<string>" · , · 
   · "alarm_key" · : ·   · "<string>" · , · 
   · "muted" · : ·   · true · , · 
   · "muted_by" · : ·   · "<string>" · , · 
   · "muted_at" · : ·   · "2026-01-01T00:00:00Z" · , · 
   · "mute_expires_at" · : ·   · "2026-01-01T00:00:00Z" · 
 · }
```

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/alarms/{alarm\_key}/mute

### Unmute an alarm

alarm.write

Unmute an alarm.

Removes the operator mute. Asset-unavailability suppression remains effective.

**Path Parameters:**

-   `alarm_key`: The alarm key in format `asset_id:rule_id`

**Note:** The unmute action is asynchronous.

Path parameters

alarm\_key · REQUIRED

string · Alarm key in format 'asset\_id:rule\_id'

Example value

cURL:

```bash
curl ·   · -X ·  DELETE  · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/mute" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

r = httpx.delete(
     · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/mute" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
)
print(r.json())
```

TypeScript:

```typescript
const ·  res =  · await ·  fetch( · "https://api.ebx.energy/v1/alarms/DE_BESS_01:CONTROL-003/mute" · , ·   · { · 
   · method · : ·   · "DELETE" · , · 
   · headers · : ·   · { · 
    Authorization · : ·   · `Bearer ${token}` · , · 
   · }, · 
 · } · );
 · const ·  data =  · await ·  res.json();
```

Example response · 200

```json
{ · 
   · "event_id" · : ·   · "<string>" · , · 
   · "alarm_key" · : ·   · "<string>" · , · 
   · "muted" · : ·   · false · , · 
   · "unmuted_by" · : ·   · "<string>" · , · 
   · "unmuted_at" · : ·   · "2026-01-01T00:00:00Z" · 
 · }
```

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/alarms/active

### List active alarms for an organization

alarm.read

Get currently active alarms for all assets in an organization.

Returns all non-resolved alarms from the alarm state table (DynamoDB). This is a fast, real-time view of current alarm state across the organization.

**Query Parameters:**

-   `organization_id`: Target organization. Optional for users that map to exactly one organization — required for EBX admins and multi-org users.
-   `severity`: Filter by severity levels (optional, can specify multiple)
-   `include_muted`: Include muted alarms in the response (default: true)

**Performance Notes:**

-   This endpoint reads from DynamoDB and is fast
-   Uses GSI on status for efficient querying
-   For alarm history, use `GET /alarms` with a time range

Query parameters

organization\_id

string · Target organization. Optional for single-org users; required for EBX admins and multi-org users.

severity

array\[enum\] · Filter by severity levels (can specify multiple)

include\_muted

boolean · default true · Include muted alarms in the response

Example value

cURL:

```bash
curl ·   · "https://api.ebx.energy/v1/alarms/active" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

r = httpx.get(
     · "https://api.ebx.energy/v1/alarms/active" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
)
print(r.json())
```

TypeScript:

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

Example response · 200

```json
{ · 
   · "alarms" · : ·   · [ · 
     · { · 
       · "alarm_key" · : ·   · "<string>" · , · 
       · "alarm_id" · : ·   · "<string>" · , · 
       · "asset_id" · : ·   · "<string>" · , · 
       · "rule_id" · : ·   · "TELEMETRY-001" · , · 
       · "alarm_type" · : ·   · "<string>" · , · 
       · "severity" · : ·   · "INFO" · , · 
       · "message" · : ·   · "<string>" · , · 
       · "status" · : ·   · "open" · , · 
       · "opened_at" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "last_updated" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "condition_active" · : ·   · true · , · 
       · "condition_ended_at" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "muted" · : ·   · false · , · 
       · "source_muted" · : ·   · false · , · 
       · "mute_expires_at" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "mute_reason" · : ·   · "<string>" · , · 
       · "acknowledged" · : ·   · false · , · 
       · "acknowledged_by" · : ·   · "<string>" · , · 
       · "acknowledged_at" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "evidence" · : ·   · "<string>" · 
     · } · 
   · ], · 
   · "total" · : ·   · 0 · 
 · }
```

Can raise

-   401 · no valid token
-   403 · scope missing
-   422 · validation failed
-   429 · rate limited

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

· GET · /v1/alarms/active/fleet

### List active fleet-level (pool) alarms

alarm.read

Get currently active fleet-level (pool) alarms.

Pool alarms (e.g. POOL-004, POOL-006, POOL-003) are published by the asset-state monitoring service under synthetic `tso-{tso_id}` partition keys — one partition per TSO zone — rather than under real asset ids. They describe the aggregated fleet per TSO zone and span all customer organizations, so this endpoint is restricted to EBX admins.

**Query Parameters:**

-   `include_muted`: Include muted alarms in the response (default: true)

Query parameters

include\_muted

boolean · default true · Include muted alarms in the response

Example value

cURL:

```bash
curl ·   · "https://api.ebx.energy/v1/alarms/active/fleet" ·  \
   · -H ·   · "Authorization: Bearer $EBX_TOKEN"
```

Python:

```python
import ·  httpx

r = httpx.get(
     · "https://api.ebx.energy/v1/alarms/active/fleet" · , · 
    headers= · { · "Authorization" · : ·  f · "Bearer {token}" · }, · 
)
print(r.json())
```

TypeScript:

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

Example response · 200

```json
{ · 
   · "alarms" · : ·   · [ · 
     · { · 
       · "alarm_key" · : ·   · "<string>" · , · 
       · "alarm_id" · : ·   · "<string>" · , · 
       · "asset_id" · : ·   · "<string>" · , · 
       · "rule_id" · : ·   · "TELEMETRY-001" · , · 
       · "alarm_type" · : ·   · "<string>" · , · 
       · "severity" · : ·   · "INFO" · , · 
       · "message" · : ·   · "<string>" · , · 
       · "status" · : ·   · "open" · , · 
       · "opened_at" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "last_updated" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "condition_active" · : ·   · true · , · 
       · "condition_ended_at" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "muted" · : ·   · false · , · 
       · "source_muted" · : ·   · false · , · 
       · "mute_expires_at" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "mute_reason" · : ·   · "<string>" · , · 
       · "acknowledged" · : ·   · false · , · 
       · "acknowledged_by" · : ·   · "<string>" · , · 
       · "acknowledged_at" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "evidence" · : ·   · "<string>" · 
     · } · 
   · ], · 
   · "total" · : ·   · 0 · 
 · }
```

Can raise

-   401 · no valid token
-   403 · scope missing
-   422 · validation failed
-   429 · rate limited

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

· GET · /v1/assets/{asset\_id}/alarms

### List alarm history for an asset

alarm.read

Get alarms for a specific asset within a time range.

Returns a paginated list of alarms that have been triggered for the specified asset. Results are ordered by timestamp (most recent first).

**Query Parameters:**

-   `start_time`: Start of the time range (required, ISO 8601 format)
-   `end_time`: End of the time range (required, ISO 8601 format)
-   `severity`: Filter by severity levels (optional, can specify multiple)
-   `limit`: Maximum number of alarms to return (default: 100, max: 1000)
-   `offset`: Offset for pagination (default: 0)

**Alarm Severity Levels:**

-   `INFO`: Informational alerts
-   `WARNING`: Potential issues that may require attention
-   `ERROR`: Errors that need immediate attention
-   `CRITICAL`: Critical issues requiring immediate action

**Performance Notes:**

-   Historical queries via Athena typically take 2-5 seconds
-   Use date ranges efficiently for better performance
-   For real-time updates, use the WebSocket connection

Path parameters

asset\_id · REQUIRED

string · The ID of the asset

Query parameters

start\_time · REQUIRED

string<date-time> · Start time for filtering results (ISO 8601 format)

end\_time · REQUIRED

string<date-time> · End time for filtering results (ISO 8601 format)

severity

array\[enum\] · Filter by severity levels (can specify multiple)

limit

integer · default 100 · Maximum number of alarms to return

offset

integer · default 0 · Offset for pagination

Example value

cURL:

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

Example response · 200

```json
{ · 
   · "alarms" · : ·   · [ · 
     · { · 
       · "event_id" · : ·   · "<string>" · , · 
       · "event_type" · : ·   · "alarm.opened" · , · 
       · "alarm_id" · : ·   · "<string>" · , · 
       · "alarm_key" · : ·   · "<string>" · , · 
       · "asset_id" · : ·   · "<string>" · , · 
       · "rule_id" · : ·   · "TELEMETRY-001" · , · 
       · "alarm_type" · : ·   · "<string>" · , · 
       · "severity" · : ·   · "INFO" · , · 
       · "message" · : ·   · "<string>" · , · 
       · "evidence" · : ·   · "<string>" · , · 
       · "timestamp" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "opened_at" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "resolved_at" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "date_partition" · : ·   · "<string>" · , · 
       · "muted" · : ·   · false · , · 
       · "acknowledged" · : ·   · false · , · 
       · "acknowledged_by" · : ·   · "<string>" · , · 
       · "acknowledged_at" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "user_id" · : ·   · "<string>" · , · 
       · "user_email" · : ·   · "<string>" · , · 
       · "notes" · : ·   · "<string>" · , · 
       · "mute_reason" · : ·   · "<string>" · , · 
       · "mute_expires_at" · : ·   · "2026-01-01T00:00:00Z" · 
     · } · 
   · ], · 
   · "total" · : ·   · 0 · , · 
   · "limit" · : ·   · 0 · , · 
   · "offset" · : ·   · 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)

· GET · /v1/assets/{asset\_id}/alarms/active

### List active alarms for an asset

alarm.read

Get currently active alarms for a specific asset.

Returns all non-resolved alarms from the alarm state table (DynamoDB). This is a fast, real-time view of current alarm state.

**Query Parameters:**

-   `include_muted`: Include muted alarms in the response (default: true)

**Performance Notes:**

-   This endpoint reads from DynamoDB and is very fast (<100ms)
-   For alarm history, use `GET /assets/{asset_id}/alarms` with a time range

Path parameters

asset\_id · REQUIRED

string · The ID of the asset

Query parameters

include\_muted

boolean · default true · Include muted alarms in the response

Example value

cURL:

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

Python:

```python
import ·  httpx

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

TypeScript:

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

Example response · 200

```json
{ · 
   · "alarms" · : ·   · [ · 
     · { · 
       · "alarm_key" · : ·   · "<string>" · , · 
       · "alarm_id" · : ·   · "<string>" · , · 
       · "asset_id" · : ·   · "<string>" · , · 
       · "rule_id" · : ·   · "TELEMETRY-001" · , · 
       · "alarm_type" · : ·   · "<string>" · , · 
       · "severity" · : ·   · "INFO" · , · 
       · "message" · : ·   · "<string>" · , · 
       · "status" · : ·   · "open" · , · 
       · "opened_at" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "last_updated" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "condition_active" · : ·   · true · , · 
       · "condition_ended_at" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "muted" · : ·   · false · , · 
       · "source_muted" · : ·   · false · , · 
       · "mute_expires_at" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "mute_reason" · : ·   · "<string>" · , · 
       · "acknowledged" · : ·   · false · , · 
       · "acknowledged_by" · : ·   · "<string>" · , · 
       · "acknowledged_at" · : ·   · "2026-01-01T00:00:00Z" · , · 
       · "evidence" · : ·   · "<string>" · 
     · } · 
   · ], · 
   · "total" · : ·   · 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)
