RelayX Alerts
Server-side alerts that run on the RelayX platform. Once created, they evaluate continuously without your application needing to be running.
Access via app.alert.
Alert Types
| Type | Description |
|---|---|
| Threshold | Triggers when a metric stays above or below a value for a sustained period. Use for boundary conditions like temperature > 80 or battery < 20. |
| Rate-change | Triggers when a metric changes too quickly over a time window. Use for detecting sudden spikes or drops like a pressure drop of 10 units in 1 minute. |
API
create()
Create a server-side threshold or rate-change alert.
- JavaScript
- Python
await app.alert.create(params)await app.alert.create(params)| Parameter | Type | Description |
|---|---|---|
name | string | Unique alert name |
description | string | (optional) Human-readable description |
type | string | "THRESHOLD" or "RATE_CHANGE" |
metric | string | The telemetry metric to monitor |
config | object | Alert configuration (see below) |
notification_channel | string[] | (optional) Notification channel IDs to deliver to |
Returns the alert object with a listen() method attached
Threshold Example
- JavaScript
- Python
const alert = await app.alert.create({
name: "high_temp",
description: "Alert when temperature exceeds 85",
type: "THRESHOLD",
metric: "temperature",
config: {
scope: {
type: "DEVICE",
value: deviceId,
},
operator: ">",
value: 85,
duration: 300,
recovery_duration: 120,
cooldown: 600,
},
notification_channel: [channelId],
});
alert = await app.alert.create({
"name": "high_temp",
"description": "Alert when temperature exceeds 85",
"type": "THRESHOLD",
"metric": "temperature",
"config": {
"scope": {
"type": "DEVICE",
"value": device_id,
},
"operator": ">",
"value": 85,
"duration": 300,
"recovery_duration": 120,
"cooldown": 600,
},
"notification_channel": [channel_id],
})
Example response:
{
"name": "high_temp",
"description": "Alert when temperature exceeds 85",
"type": "THRESHOLD",
"metric": "temperature",
"config": {
"scope": { "type": "DEVICE", "value": "69ca39e4ed4d9fe786145b48" },
"operator": ">",
"value": 85,
"duration": 300,
"recovery_duration": 120,
"cooldown": 600
},
"notification_channel": ["69cb22a4ed4d9fe786145d01"]
}
Rate-Change Example
- JavaScript
- Python
const alert = await app.alert.create({
name: "pressure_drop",
type: "RATE_CHANGE",
metric: "pressure",
config: {
scope: { type: "DEVICE", value: deviceId },
operator: "<",
value: -10,
duration: 60,
recovery_duration: 30,
},
notification_channel: [channelId],
});
alert = await app.alert.create({
"name": "pressure_drop",
"type": "RATE_CHANGE",
"metric": "pressure",
"config": {
"scope": {"type": "DEVICE", "value": device_id},
"operator": "<",
"value": -10,
"duration": 60,
"recovery_duration": 30,
},
"notification_channel": [channel_id],
})
Config Reference
| Field | Type | Description |
|---|---|---|
scope.type | string | "DEVICE", "LOGICAL_GROUP" or "HEIRARCHY" |
scope.value | string | The device ID or group identifier |
operator | string | >, >=, ==, <=, < |
value | number | The threshold or rate value |
duration | number | Seconds the condition must hold before the alert fires |
recovery_duration | number | Seconds the condition must clear before the alert resolves |
cooldown | number | (optional) Minimum seconds between re-fires |
update()
Update a server-side alert's configuration.
- JavaScript
- Python
await app.alert.update(params)await app.alert.update(params)| Parameter | Type | Description |
|---|---|---|
id | string | The alert ID |
config | object | (optional) Updated config (partial update) |
- JavaScript
- Python
const updated = await app.alert.update({
id: alertId,
config: { value: 90 },
});
updated = await app.alert.update({
"id": alert_id,
"config": {"value": 90},
})
Example response:
{
"name": "high_temp",
"type": "THRESHOLD",
"metric": "temperature",
"config": {
"scope": { "type": "DEVICE", "value": "69ca39e4ed4d9fe786145b48" },
"operator": ">",
"value": 90,
"duration": 300,
"recovery_duration": 120,
"cooldown": 600
},
"notification_channel": ["69cb22a4ed4d9fe786145d01"]
}
listen()
Subscribe to alert state changes (fire, resolved, acknowledged).
- JavaScript
- Python
await alert.listen(callbacks)await alert.listen(callbacks)| Callback | Description |
|---|---|
onFire / on_fire | Alert condition met — alert has fired |
onResolved / on_resolved | Alert condition cleared — alert resolved |
onAck / on_ack | A specific device's alert was acknowledged |
onAckAll / on_ack_all | All devices' alerts were acknowledged |
- JavaScript
- Python
await alert.listen({
onFire: (data) => console.log("FIRED:", data),
onResolved: (data) => console.log("RESOLVED:", data),
onAck: (data) => console.log("ACK:", data),
onAckAll: (data) => console.log("ACK_ALL:", data),
});
await alert.listen({
"on_fire": lambda data: print("FIRED:", data),
"on_resolved": lambda data: print("RESOLVED:", data),
"on_ack": lambda data: print("ACK:", data),
"on_ack_all": lambda data: print("ACK_ALL:", data),
})
The following operations work the same for both RelayX and ephemeral alerts. State changes (ack, mute, unmute) are globally synced — if one App SDK instance acknowledges or mutes an alert, all other instances see the change.
delete()
Permanently remove an alert.
- JavaScript
- Python
await app.alert.delete(alertId)await app.alert.delete(alertId);
await app.alert.delete(alert_id)await app.alert.delete(alert_id)
list()
Retrieve all alerts.
- JavaScript
- Python
await app.alert.list()const alerts = await app.alert.list();
await app.alert.list()alerts = await app.alert.list()
Example response:
[
{
"name": "high_temp",
"type": "THRESHOLD",
"metric": "temperature",
"config": {
"scope": { "type": "DEVICE", "value": "69ca39e4ed4d9fe786145b48" },
"operator": ">",
"value": 85,
"duration": 300,
"recovery_duration": 120
},
"notification_channel": ["69cb22a4ed4d9fe786145d01"]
}
]
get()
Retrieve a single alert by name.
- JavaScript
- Python
await app.alert.get(name)const alert = await app.alert.get("high_temp");
await app.alert.get(name)alert = await app.alert.get("high_temp")
Example response:
{
"name": "high_temp",
"type": "THRESHOLD",
"metric": "temperature",
"config": {
"scope": { "type": "DEVICE", "value": "69ca39e4ed4d9fe786145b48" },
"operator": ">",
"value": 85,
"duration": 300,
"recovery_duration": 120,
"cooldown": 600
},
"notification_channel": ["69cb22a4ed4d9fe786145d01"]
}
history()
Query the history of alert state changes.
- JavaScript
- Python
await app.alert.history(params)await app.alert.history(params)| Parameter | Type | Description |
|---|---|---|
name | string | The alert name |
device_idents | string[] | Device identifiers to query |
start | string | Start time (ISO 8601) |
end | string | (optional) End time (ISO 8601). Defaults to now |
- JavaScript
- Python
const history = await app.alert.history({
name: "high_temp",
device_idents: ["sensor_01"],
start: "2026-03-01T00:00:00.000Z",
end: "2026-03-02T00:00:00.000Z",
});
history = await app.alert.history({
"name": "high_temp",
"device_idents": ["sensor_01"],
"start": "2026-03-01T00:00:00.000Z",
"end": "2026-03-02T00:00:00.000Z",
})
Alert history retention depends on your plan. For example, the free plan retains 3 days of history. Queries outside your retention window will return empty results.
ack()
Acknowledge a specific device's alert.
- JavaScript
- Python
await app.alert.ack(params)await app.alert.ack(params)| Parameter | Type | Description |
|---|---|---|
device_ident | string | The device identifier |
alert_id | string | The alert ID |
acked_by | string | Who is acknowledging (e.g., operator name) |
ack_notes | string | (optional) Notes about the acknowledgement |
- JavaScript
- Python
await app.alert.ack({
device_ident: "sensor_01",
alert_id: alertId,
acked_by: "operator_jane",
ack_notes: "Investigating issue",
});
await app.alert.ack({
"device_ident": "sensor_01",
"alert_id": alert_id,
"acked_by": "operator_jane",
"ack_notes": "Investigating issue",
})
ackAll()
Acknowledge an alert across all devices.
- JavaScript
- Python
await app.alert.ackAll(params)await app.alert.ack_all(params)| Parameter | Type | Description |
|---|---|---|
alert_id | string | The alert ID |
acked_by | string | Who is acknowledging |
ack_notes | string | (optional) Notes about the acknowledgement |
- JavaScript
- Python
await app.alert.ackAll({
alert_id: alertId,
acked_by: "operator_jane",
ack_notes: "Maintenance window",
});
await app.alert.ack_all({
"alert_id": alert_id,
"acked_by": "operator_jane",
"ack_notes": "Maintenance window",
})
mute()
Silence an alert so it stops delivering notifications.
- JavaScript
- Python
await app.alert.mute(params)await app.alert.mute(params)| Parameter | Type | Description |
|---|---|---|
id | string | The alert ID |
mute_config.type | string | "FOREVER" or "TIME_BASED" |
mute_config.mute_till | string | (TIME_BASED only) ISO 8601 timestamp to unmute at |
| Mute Type | Behavior |
|---|---|
"FOREVER" | The alert stays muted until explicitly unmuted via unmute(). The alert still evaluates but notifications are suppressed. |
"TIME_BASED" | The alert is muted until the specified mute_till timestamp, then automatically unmutes. |
- JavaScript
- Python
// mute forever
await app.alert.mute({
id: alertId,
mute_config: { type: "FOREVER" },
});
// mute until a specific time
await app.alert.mute({
id: alertId,
mute_config: {
type: "TIME_BASED",
mute_till: "2026-04-01T00:00:00.000Z",
},
});
# mute forever
await app.alert.mute({
"id": alert_id,
"mute_config": {"type": "FOREVER"},
})
# mute until a specific time
await app.alert.mute({
"id": alert_id,
"mute_config": {
"type": "TIME_BASED",
"mute_till": "2026-04-01T00:00:00.000Z",
},
})
unmute()
Re-enable a muted alert.
- JavaScript
- Python
await app.alert.unmute(alertId)await app.alert.unmute(alertId);
await app.alert.unmute(alert_id)await app.alert.unmute(alert_id)