Provenance
Alerting

Interaction Metrics

Define reusable metric definitions that aggregate your interaction data.

Interaction Metrics are reusable metric definitions that aggregate your interaction data. They serve as the foundation for Metric Alerts — you define what to measure, and alerts define when to act on it.

Overview

A metric definition specifies:

  • What to aggregate — count, sum, average, min, max, distinct count, or rate
  • Which interactions — scoped by resource type, action, origin, and custom filters
  • Over what period — a time window like 5m, 1h, 24h
  • Grouped by what — optional dimensions like resourceId, interaction.country

When calculated, the metric runs a SQL aggregation against your interaction data and returns one or more result rows.

Creating a metric

POST /api/interaction-metrics
{
  "name": "Failed Logins (5m)",
  "description": "Count of failed login attempts in the last 5 minutes",
  "resourceTypeId": "customer-uuid",
  "actionId": "login-fail-uuid",
  "metricTypeId": "count-metric-type-uuid",
  "timeWindow": "5m",
  "filters": [],
  "groupBy": [],
  "enabled": true
}

Fields

FieldRequiredDescription
nameYesHuman-readable metric name
descriptionNoWhat this metric measures
metricTypeIdYesAggregation type (see metric types)
resourceTypeIdNoScope to a resource type, or omit for all
actionIdNoScope to an action, or omit for all
originIdNoScope to an origin, or omit for all
fieldConditionalField to aggregate (required for sum, avg, min, max, distinct count)
filtersNoAdditional filter conditions
timeWindowNoAggregation window (omit for all time)
groupByNoDimensions to group by
enabledNoWhether the metric is active (default: true)

Metric types

Retrieve available metric types:

GET /api/interaction-metrics/types
TypeMnemonicDescriptionRequires field
CountCOUNTNumber of matching interactionsNo
SumSUMSum of a numeric fieldYes
AverageAVGAverage of a numeric fieldYes
MinimumMINMinimum value of a fieldYes
MaximumMAXMaximum value of a fieldYes
Distinct CountDISTINCT_COUNTCount of unique valuesYes
RateRATECount per time unitNo (requires timeWindow)

Time window format

FormatExampleMeaning
{n}m5m5 minutes
{n}h1h1 hour
{n}d7d7 days

Omit timeWindow to aggregate across all time.

Filters

Filters narrow the interactions included in the metric calculation. Each filter has:

FieldDescription
fieldThe field to filter on — resourceId, or interaction.{key} for nested fields
operatoreq, neq, gt, gte, lt, lte, contains
valueThe value to compare against
{
  "filters": [
    { "field": "interaction.country", "operator": "eq", "value": "ZA" },
    { "field": "interaction.attempts", "operator": "gt", "value": 3 }
  ]
}

Group by

Group by adds dimensions to the metric result. Instead of a single aggregate value, you get one row per unique combination of dimension values.

{
  "groupBy": ["interaction.country", "interaction.browser"]
}

Result:

{
  "results": [
    { "value": 42, "dimensions": { "interaction_country": "ZA", "interaction_browser": "Chrome" } },
    { "value": 18, "dimensions": { "interaction_country": "US", "interaction_browser": "Safari" } }
  ]
}

Supported group-by fields:

  • resourceId — group by resource
  • interaction.{key} — group by any field in the interaction JSON

Field discovery

If you've selected a resource type and action, you can discover which fields exist in your interaction data:

GET /api/interaction-metrics/fields/discover?resourceTypeId=uuid&actionId=uuid

Returns an array of field paths:

["interaction.email", "interaction.country", "interaction.browser", "interaction.ip_address"]

Calculating metrics

Single metric

POST /api/interaction-metrics/:metricId/calculate

Returns:

{
  "metricId": "uuid",
  "metricName": "Failed Logins (5m)",
  "metricType": "COUNT",
  "calculatedAt": "2026-03-20T14:30:00.000Z",
  "results": [
    { "value": 42, "dimensions": null }
  ]
}

For grouped metrics, results contains one entry per dimension combination:

{
  "results": [
    { "value": 25, "dimensions": { "interaction_country": "ZA" } },
    { "value": 17, "dimensions": { "interaction_country": "US" } }
  ]
}

All metrics

POST /api/interaction-metrics/calculate-all

Returns:

{
  "calculated": 5,
  "results": [
    {
      "metricId": "uuid",
      "metricName": "Failed Logins (5m)",
      "metricType": "COUNT",
      "calculatedAt": "2026-03-20T14:30:00.000Z",
      "resultCount": 1,
      "sampleValue": 42,
      "results": [{ "value": 42, "dimensions": null }]
    }
  ]
}

Examples

Count of orders in the last hour

{
  "name": "Orders (1h)",
  "metricTypeId": "count-uuid",
  "resourceTypeId": "order-uuid",
  "actionId": "created-uuid",
  "timeWindow": "1h"
}

Average order value by origin

{
  "name": "Avg Order Value by Origin",
  "metricTypeId": "avg-uuid",
  "resourceTypeId": "order-uuid",
  "actionId": "chk-done-uuid",
  "field": "interaction.total",
  "timeWindow": "24h",
  "groupBy": ["interaction.origin"]
}

Failed logins per country (5 min)

{
  "name": "Failed Logins by Country (5m)",
  "metricTypeId": "count-uuid",
  "resourceTypeId": "customer-uuid",
  "actionId": "login-fail-uuid",
  "timeWindow": "5m",
  "groupBy": ["interaction.login_location"]
}

Email bounce rate

{
  "name": "Email Bounces (1h)",
  "metricTypeId": "count-uuid",
  "resourceTypeId": "email-uuid",
  "actionId": "bounced-uuid",
  "timeWindow": "1h"
}

API reference

MethodEndpointDescription
GET/api/interaction-metricsList all metrics
GET/api/interaction-metrics/:idGet metric by ID
POST/api/interaction-metricsCreate metric
PUT/api/interaction-metrics/:idUpdate metric
DELETE/api/interaction-metrics/:idDelete metric
GET/api/interaction-metrics/typesList metric types
GET/api/interaction-metrics/fields/discoverDiscover fields for resource type + action
POST/api/interaction-metrics/:id/calculateCalculate single metric
POST/api/interaction-metrics/calculate-allCalculate all enabled metrics