Skip to main content

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

TypeDescription
ThresholdTriggers when a metric stays above or below a value for a sustained period. Use for boundary conditions like temperature > 80 or battery < 20.
Rate-changeTriggers 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.

await app.alert.create(params)
ParameterTypeDescription
namestringUnique alert name
descriptionstring(optional) Human-readable description
typestring"THRESHOLD" or "RATE_CHANGE"
metricstringThe telemetry metric to monitor
configobjectAlert configuration (see below)
notification_channelstring[](optional) Notification channel IDs to deliver to

Returns the alert object with a listen() method attached

Threshold Example

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],
});

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

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],
});

Config Reference

FieldTypeDescription
scope.typestring"DEVICE", "LOGICAL_GROUP" or "HEIRARCHY"
scope.valuestringThe device ID or group identifier
operatorstring>, >=, ==, <=, <
valuenumberThe threshold or rate value
durationnumberSeconds the condition must hold before the alert fires
recovery_durationnumberSeconds the condition must clear before the alert resolves
cooldownnumber(optional) Minimum seconds between re-fires

update()

Update a server-side alert's configuration.

await app.alert.update(params)
ParameterTypeDescription
idstringThe alert ID
configobject(optional) Updated config (partial update)
const updated = await app.alert.update({
id: alertId,
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).

await alert.listen(callbacks)
CallbackDescription
onFire / on_fireAlert condition met — alert has fired
onResolved / on_resolvedAlert condition cleared — alert resolved
onAck / on_ackA specific device's alert was acknowledged
onAckAll / on_ack_allAll devices' alerts were acknowledged
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),
});

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.

await app.alert.delete(alertId)
await app.alert.delete(alertId);

list()

Retrieve all alerts.

await app.alert.list()
const 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.

await app.alert.get(name)
const 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.

await app.alert.history(params)
ParameterTypeDescription
namestringThe alert name
device_identsstring[]Device identifiers to query
startstringStart time (ISO 8601)
endstring(optional) End time (ISO 8601). Defaults to now
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 retention

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.

await app.alert.ack(params)
ParameterTypeDescription
device_identstringThe device identifier
alert_idstringThe alert ID
acked_bystringWho is acknowledging (e.g., operator name)
ack_notesstring(optional) Notes about the acknowledgement
await app.alert.ack({
device_ident: "sensor_01",
alert_id: alertId,
acked_by: "operator_jane",
ack_notes: "Investigating issue",
});

ackAll()

Acknowledge an alert across all devices.

await app.alert.ackAll(params)
ParameterTypeDescription
alert_idstringThe alert ID
acked_bystringWho is acknowledging
ack_notesstring(optional) Notes about the acknowledgement
await app.alert.ackAll({
alert_id: alertId,
acked_by: "operator_jane",
ack_notes: "Maintenance window",
});

mute()

Silence an alert so it stops delivering notifications.

await app.alert.mute(params)
ParameterTypeDescription
idstringThe alert ID
mute_config.typestring"FOREVER" or "TIME_BASED"
mute_config.mute_tillstring(TIME_BASED only) ISO 8601 timestamp to unmute at
Mute TypeBehavior
"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.
// 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",
},
});

unmute()

Re-enable a muted alert.

await app.alert.unmute(alertId)
await app.alert.unmute(alertId);