Test notification filter
Evaluates a notification filter against an alert event and returns whether the filter passes.
Use this endpoint to test filter behavior before saving a subscription filter.
This endpoint only evaluates filters. It does not create or update notification subscriptions.
Request modes
- Use
eventIdwhen you want to test against an existing stored alert event - Use
eventwhen you want to submit a modified event body for a custom test case
Request body
| Field | Type | Required | Description |
|---|---|---|---|
filter | object | Yes | Filter expression to evaluate |
event | object | Conditionally | Event payload to evaluate against |
eventId | string | Conditionally | Existing event identifier to load and evaluate |
prevEvent | object | No | Previous event payload used when the filter depends on prior state |
overrides | object | No | Override values for selected computed max fields during evaluation |
referenceTime | string | No | ISO date-time used for interval-based checks such as alerts.current and anomalyExists. Defaults to the event occurred time, or the current time if the event has no occurred value. |
currentAlertId | string | No | Alert identifier used when the filter references alerts.current. Use this when the current alert cannot be resolved from eventId or event.alertId. |
Provide either event or eventId.
You can obtain eventId values from the Alerts API event endpoints, such as List alert events and Get alert event.
If you want to provide a custom event body instead of eventId, start from an alert event returned by the Alerts API and modify it for your test case.
Request behavior
- If
eventIdis provided, the API resolves the stored event visible to the caller - If
prevEventis omitted andeventIdresolves to an event with a prior sequence, the API attempts to load the previous event automatically overridescan be used to inject test values for computed max fields without changing stored datareferenceTimecontrols the time used foralerts.currentandanomalyExistslookups- If the filter references
alerts.current, the endpoint usescurrentAlertId,eventId, orevent.alertIdto identify the current alert - The endpoint only loads and populates
alerts.currentwhen the filter referencesalerts.current - Invalid request bodies return
400 - If
eventIdis not found, the endpoint returns404 - Filter evaluation errors return
200with anerrorfield in the response body
computed values based on historical notification stats are not populated unless you provide them through overrides.
Event-derived computed values, such as current values, previous values, and presence arrays, are still included in the evaluation context.
Response
200 OK
| Field | Type | Description |
|---|---|---|
pass | boolean | Whether the filter matched the evaluated event |
error | string | Present when filter evaluation fails |
planTrace | object | Details for interval-based filter context such as alerts.current and anomalyExists. Durations are omitted from this endpoint. |
trace | object | Values resolved for variable paths referenced by the filter; use this to understand why the filter passed or failed |
context | object | Full evaluation context used for the filter test |
Plan trace fields
| Field | Type | Description |
|---|---|---|
referenceTime | string | ISO date-time used for interval-based checks. |
alertsCurrent.loaded | boolean | Present when the endpoint loaded current alert state because the filter referenced alerts.current. This does not guarantee that context.alerts.current is non-null. |
anomalyLookups | array | Lookup details for anomalyExists expressions evaluated by the filter. |
Anomaly lookup trace fields
| Field | Type | Description |
|---|---|---|
selector | object | Static selector used by the anomalyExists expression. |
predicate | object | Optional predicate used by the anomalyExists expression. |
result | boolean | Whether at least one active anomaly matched. |
sampleMatch | object | Example matching anomaly when result is true. |
If the filter does not reference alerts.current, the endpoint does not load current alert state. In that case, context.alerts.current can be null in the response.
Errors
400: invalid request body, invalidfilter, invalideventId, invalidreferenceTime, invalidanomalyExists, disallowed filter variables, or neithereventnoreventIdwas provided400: filter referencesalerts.currentbut no current alert ID can be resolved404:eventIdnot found
Example request
{
"filter": {
">=": [
{
"var": "computed.impact.max_24h"
},
3
]
},
"eventId": "alert-123|7",
"overrides": {
"impact": {
"max_24h": 4
}
}
}
Example response
{
"pass": true,
"trace": {
"computed.impact.max_24h": 4
},
"context": {
"event": {},
"computed": {
"impact": {
"max_24h": 4
}
}
}
}
Example with current alert state
This example passes when node 123 is active on the current alert and another node in the same system is anomalous at the referenced time.
{
"filter": {
"and": [
{
"some": [
{ "var": "alerts.current.metrics" },
{ "==": [{ "var": "nodeId" }, 123] }
]
},
{
"anomalyExists": [
{
"system": { "name": "Production line A" }
},
{ "!=": [{ "var": "anomaly.nodeId" }, 123] }
]
}
]
},
"eventId": "alert-123|7",
"currentAlertId": "alert-123",
"referenceTime": "2026-05-08T12:00:00.000Z"
}
Example plan trace
{
"pass": true,
"planTrace": {
"referenceTime": "2026-05-08T12:00:00.000Z",
"alertsCurrent": {
"loaded": true
},
"anomalyLookups": [
{
"selector": {
"system": { "name": "Production line A" }
},
"predicate": {
"!=": [{ "var": "anomaly.nodeId" }, 123]
},
"result": true,
"sampleMatch": {
"alertId": "alert-456",
"nodeId": 456,
"statTypeId": "temperature",
"severity": {
"name": "yellow",
"rank": 2
},
"type": "deviation",
"score": {
"adjusted": 0.91,
"contribution": 0.42
},
"learningStatus": 1,
"closestBaselineDeviation": 1.7,
"closestBaselineDeviationAbsPeak": 1.9,
"closestBaselineDeviationAbsLevel": 1.7
}
}
]
},
"trace": {
"alerts.current.metrics": [
{
"alertId": "alert-123",
"nodeId": 123,
"nodeName": "Boiler 1",
"nodeTypeId": "boiler",
"nodeLabels": ["critical"],
"statTypeId": "temperature",
"statTypeName": "Temperature",
"statTypeLabels": ["thermal"],
"systemId": 42,
"systemName": "Production line A",
"severity": {
"name": "orange",
"rank": 3
},
"type": "deviation",
"score": {
"adjusted": 0.97,
"contribution": 0.58
},
"learningStatus": 1,
"closestBaselineDeviation": 2.4,
"closestBaselineDeviationAbsPeak": 2.8,
"closestBaselineDeviationAbsLevel": 2.4
}
]
},
"context": {
"event": {},
"alerts": {
"current": {
"id": "alert-123",
"active": true,
"activeNodes": 1,
"activeMetrics": 1,
"maxSeverity": {
"name": "orange",
"rank": 3
},
"metrics": [
{
"alertId": "alert-123",
"nodeId": 123,
"nodeName": "Boiler 1",
"nodeTypeId": "boiler",
"nodeLabels": ["critical"],
"statTypeId": "temperature",
"statTypeName": "Temperature",
"statTypeLabels": ["thermal"],
"systemId": 42,
"systemName": "Production line A",
"severity": {
"name": "orange",
"rank": 3
},
"type": "deviation",
"score": {
"adjusted": 0.97,
"contribution": 0.58
},
"learningStatus": 1,
"closestBaselineDeviation": 2.4,
"closestBaselineDeviationAbsPeak": 2.8,
"closestBaselineDeviationAbsLevel": 2.4
}
]
}
}
}
}