Provenance
Alerting

Metric Alerts

Create threshold-based alerts on interaction metrics with state tracking and recovery.

Metric Alerts monitor Interaction Metrics and fire when a metric's value crosses a threshold. They track state (OK vs FIRING) per dimension and only create interactions on state transitions — preventing duplicate alerts.

Overview

Interaction Metric (e.g. "Failed Logins (5m)")

Metric Alert (e.g. "Failed Logins > 100")
        ↓  evaluate
    Calculate metric value

    Compare against threshold

    State changed?
      ├── OK → FIRING:  Create interaction with alertActionId
      ├── FIRING → OK:  Create interaction with recoveryActionId
      ├── OK → OK:      No interaction (skip)
      └── FIRING → FIRING: No interaction (skip)

Creating a metric alert

POST /api/interaction-alerts
{
  "title": "High Failed Logins",
  "description": "Alert when failed logins exceed 100 in 5 minutes",
  "metricId": "failed-logins-metric-uuid",
  "operator": "gt",
  "threshold": 100,
  "alertActionId": "fired-action-uuid",
  "recoveryActionId": "recovered-action-uuid",
  "resourceTypeId": "alert-sec-uuid",
  "enabled": true
}

Fields

FieldRequiredDescription
titleYesHuman-readable alert name
descriptionNoWhat this alert monitors
metricIdYesThe interaction metric to monitor
operatorYesComparison operator
thresholdYesNumeric threshold value
alertActionIdYesAction to trigger when alert fires
recoveryActionIdNoAction to trigger when alert recovers
resourceTypeIdNoResource type for alert interactions (defaults to system ALERT type)
enabledNoToggle the alert on/off (default: true)

Operators

OperatorLabelMeaning
gt>Greater than
gteGreater than or equal
lt<Less than
lteLess than or equal
eq=Equal to
neqNot equal to

Alert and recovery actions

Unlike subscriber alerts which use system defaults, metric alerts require you to configure explicit actions. This gives you full control over what resource type and action appear in the alert interaction — and therefore which subscriptions get triggered.

Alert Action (alertActionId) — the action used when the metric crosses the threshold (OK → FIRING). This is required.

Recovery Action (recoveryActionId) — the action used when the metric drops back below the threshold (FIRING → OK). This is optional. If not set, no interaction is created on recovery.

Example action setup

For a pizza-place tenant:

ActionMnemonicPurpose
FiredfiredUsed as alertActionId — threshold exceeded
RecoveredrecoveredUsed as recoveryActionId — back to normal
# Create alert with both actions
POST /api/interaction-alerts
{
  "title": "High Cart Abandonment",
  "metricId": "cart-abandonment-metric-uuid",
  "operator": "gt",
  "threshold": 50,
  "alertActionId": "fired-action-uuid",
  "recoveryActionId": "recovered-action-uuid",
  "resourceTypeId": "alert-biz-uuid"
}

State tracking

Metric alerts track state per dimension combination. This prevents duplicate interactions when an alert is already firing.

State transitions

Previous StateCurrent Value vs ThresholdNew StateInteraction Created?
OKExceededFIRINGYes — with alertActionId
FIRINGExceededFIRINGNo — already firing
FIRINGNot exceededOKYes — with recoveryActionId (if configured)
OKNot exceededOKNo — already OK

Multi-dimensional state

For metrics with groupBy dimensions, state is tracked independently per dimension combination.

Example: A "Failed Logins by Country" metric with threshold > 100:

Metric results:
  ZA: 150  →  State: FIRING (150 > 100)
  US:  50  →  State: OK (50 < 100)
  UK: 120  →  State: FIRING (120 > 100)

Each dimension has its own state record in interaction_alert_states. ZA firing doesn't affect US or UK.

State table

The interaction_alert_states table tracks:

ColumnDescription
alertIdWhich alert
dimensionKeyMD5 hash of dimension values (for uniqueness)
dimensionValuesActual dimension values as JSON
isFiringCurrent state: true = firing, false = OK
currentValueMost recent metric value
lastTriggeredAtWhen the alert last transitioned to FIRING
lastRecoveredAtWhen the alert last transitioned to OK
triggerCountTotal number of times this alert has fired

Alert interaction data

When a metric alert fires or recovers, it creates an interaction with this structure. See System Interactions for the complete field reference and examples of subscribing to alert events.

{
  "alertId": "uuid",
  "alertTitle": "High Failed Logins",
  "metricId": "uuid",
  "metricName": "Failed Logins (5m)",
  "metricType": "COUNT",
  "threshold": 100,
  "operator": "gt",
  "status": "exceeded",
  "value": 150,
  "dimensions": { "interaction_country": "ZA" },
  "evaluatedAt": "2026-03-20T14:30:00.000Z"
}

For recovery interactions, status is "recovered" instead of "exceeded".

The interaction is created with:

FieldValue
resourceIdThe alert's alertId
resourceTypeIdAlert's configured resource type, or system ALERT type
actionIdalertActionId (firing) or recoveryActionId (recovery)
originIdSystem METRIC_EVAL origin
externalReferencealert-{alertId}-firing-{timestamp} or alert-{alertId}-recovery-{timestamp}

System entities required

Metric alerts require these system entities:

EntityMnemonicPurpose
Resource TypeALERTDefault resource type (if not overridden per alert)
OriginMETRIC_EVALOrigin for all metric alert interactions

The alert and recovery actions are user-configured per alert — there are no system defaults.

Evaluating alerts

Manual evaluation

POST /api/interaction-alerts/evaluate

Returns:

{
  "evaluated": 3,
  "triggered": 1,
  "recovered": 1,
  "errors": 0,
  "details": [
    {
      "alertId": "uuid",
      "alertTitle": "High Failed Logins",
      "metricName": "Failed Logins (5m)",
      "metricValue": 150,
      "operator": "gt",
      "operatorLabel": ">",
      "threshold": 100,
      "triggered": true,
      "stateChanged": true,
      "previousState": "ok",
      "newState": "firing",
      "dimensions": "interaction_country: ZA"
    },
    {
      "alertId": "uuid",
      "alertTitle": "High Failed Logins",
      "metricName": "Failed Logins (5m)",
      "metricValue": 50,
      "operator": "gt",
      "operatorLabel": ">",
      "threshold": 100,
      "triggered": false,
      "stateChanged": false,
      "previousState": "ok",
      "newState": "ok",
      "dimensions": "interaction_country: US"
    }
  ]
}

Cron job

# Evaluate every minute
* * * * * curl -X POST https://your-api.com/api/interaction-alerts/evaluate \
  -H "x-api-key: your-key"

View current states

GET /api/interaction-alerts/states

Returns all alert states with their current firing status:

[
  {
    "alertId": "uuid",
    "dimensionKey": "abc123",
    "dimensionValues": { "interaction_country": "ZA" },
    "isFiring": true,
    "currentValue": 150,
    "lastTriggeredAt": "2026-03-20T14:30:00.000Z",
    "lastRecoveredAt": null,
    "alertTitle": "High Failed Logins",
    "threshold": 100,
    "operator": "gt",
    "metricName": "Failed Logins (5m)"
  }
]

Condition-based alerts

Metric alerts also support a conditions array as an alternative to metricId + threshold. This is for simpler rule-based alerts that don't need a pre-defined metric.

POST /api/interaction-alerts
{
  "title": "Large Order Alert",
  "conditions": [
    { "field": "interaction.total", "operator": "gt", "value": 10000 }
  ],
  "alertActionId": "fired-action-uuid",
  "resourceTypeId": "alert-biz-uuid"
}

Either metricId or conditions must be provided — not both.

API reference

MethodEndpointDescription
GET/api/interaction-alertsList all metric alerts
GET/api/interaction-alerts/:idGet alert by ID
POST/api/interaction-alertsCreate alert
PUT/api/interaction-alerts/:idUpdate alert
DELETE/api/interaction-alerts/:idDelete alert
GET/api/interaction-alerts/statesGet current alert states
POST/api/interaction-alerts/evaluateEvaluate all enabled alerts