Skip to main content

Rules API

Rules define detection. These endpoints create, preview, list, and update them. The behavior behind the fields is in Rule Evaluation and Dynamic Thresholds & Baselines.

Permissions: reads and preview require CanViewAlerts; create/update require CanManageRules.

Target metric constraint: a rule can only target a metric that is registered in the catalog with isActive = true and dataStatus = ACTIVE (i.e. isEvaluable = true).

Method & pathPurpose
GET /api/rules?search=&status=&page=1&pageSize=25List rules with server-side search and pagination.
GET /api/rules/summaryReturn aggregate rule counts.
GET /api/rules/{id}Get one rule by integer id.
POST /api/rules/previewReplay a candidate rule over history without saving.
POST /api/rulesCreate a rule.
PUT /api/rules/{id}Update a rule.

GET /api/rules?search=&status=&page=1&pageSize=25

Lists saved rules. search matches rule name, metric key, status, type, or threshold mode. status can narrow the list to values such as Active.

{
"items": [
{
"id": 42,
"name": "High impact metric event",
"metricId": "demo.api.response.duration.ms",
"type": "Dynamic",
"thresholdMode": "Percentage",
"status": "Active",
"createdAt": "2026-06-02T08:00:00Z"
}
],
"page": 1,
"pageSize": 25,
"totalCount": 1,
"totalPages": 1,
"hasPreviousPage": false,
"hasNextPage": false
}

GET /api/rules/summary

Returns aggregate rule counts without loading rule rows.

{
"totalCount": 128,
"activeCount": 122
}

Shared fields

These fields appear on preview, create, and the returned RuleDto.

FieldTypeMeaning
metricIdstringThe metric key the rule watches.
typeenumStatic or Dynamic.
thresholdModeenumDynamic only: Percentage, Stddev, or Envelope.
windowMinutesintEvaluation/baseline window size.
tolerancePercentnumberUsed by Percentage and Envelope modes.
stddevMultipliernumberUsed by Stddev mode (ignored otherwise).
directionenumAbove, Below, or Both.
staticUpper / staticLowernumber?Fixed limits for Static rules.
scopeobject?For a Static rule on a multidimensional metric, an optional label-equality filter that narrows the rule to a subset of fleet members (for example {"host.id":"srv-123"} for one server or {"host.group":"prod-db"} for one group). Omitted or {} watches every member; ignored for single-metric rules. On preview the series is read for just the scoped member/group; on create it is stored on the rule.
splitBystring?Rule-level grouping for multidimensional metrics. Omit or send null to use the metric's default grouping, send "" to merge matching values into one fleet series, or send comma-separated declared dimension keys such as host.id,device.
requiredViolationsintViolations needed to consider the rule breached.
violationWindowMinutesintWindow over which violations are counted.
recoveryWindowMinutesintQuiet window required to recover.
recoveryNormalCountintConsecutive normal points required to recover.
warningLevel / criticalLevelobject?Optional alert levels — fleet/multidimensional rules only (see below).
conditionsarray?Single-value rules only. One or more conditions combined into one alarm. Each condition has its own metricId, thresholdType (Static/Dynamic), operator, thresholdMode, static limits, and dynamic parameters. Omit to have the API build one condition from the flat target/threshold fields.
conditionLogicenum?All (every condition must breach) or Any (at least one). Defaults to All.
severityenum?Warning or Critical — the single severity a condition-based rule's alarm opens at. Defaults to Warning.

Compound rules

A single-value rule can carry several conditions, each watching its own metric with its own static or dynamic threshold, combined by conditionLogic into one alarm at one severity. A rule with a single condition behaves like a classic single-metric rule. A condition-based preview returns one series per condition; for compound previews it also returns ruleSeries, the folded rule-level outcome after conditionLogic, trigger, and recovery are applied. Conditions are not supported on multidimensional metrics, which continue to use warningLevel/criticalLevel, scope, and splitBy.

Mode parameter exclusivity

The dynamic modes are mutually exclusive in evaluation:

  • Percentage uses tolerancePercent around the expected value.
  • Stddev uses stddevMultiplier around the baseline standard deviation and ignores tolerancePercent.
  • Envelope uses tolerancePercent around the historical min/max.

Alert levels (warningLevel / criticalLevel)

{
"severity": "Critical",
"operator": "Above",
"thresholdValue": 90,
"durationMinutes": 10,
"triggerViolationCount": 5,
"isEnabled": true
}
FieldMeaning
severityWarning or Critical.
operatorComparison direction for this level.
thresholdValueStatic rules: literal threshold. Dynamic rules: tolerance percent (Percentage/Envelope) or stddev multiplier (Stddev).
durationMinutesHow long the breach must persist.
triggerViolationCountViolations that trigger this level.
isEnabledWhether the level is active.

Constraints (current model): Critical must use the same operator as Warning, have durationMinutes Warning, and be stricter than Warning. Critical is evaluated before Warning.


POST /api/rules/preview

Replay a candidate rule over a historical range and return per-point results — without creating anything. Use it to tune tolerances and trigger settings against real data. For static previews, the returned band comes from staticLower / staticUpper and expected is null. Multidimensional previews return separate member series, limited by seriesLimit (default 20, maximum 50). Scope filtering happens before grouping. Each series returns its stable member key plus the latest representative labels; clients can show host.name while retaining host.id as the durable identity.

Request (extends the shared fields with a time range)

{
"metricId": "demo.api.response.duration.ms",
"from": "2026-06-01T00:00:00Z",
"to": "2026-06-02T00:00:00Z",
"type": "Dynamic",
"thresholdMode": "Percentage",
"windowMinutes": 5,
"tolerancePercent": 30,
"stddevMultiplier": 0,
"requiredViolations": 3,
"violationWindowMinutes": 5,
"recoveryWindowMinutes": 10,
"recoveryNormalCount": 3,
"direction": "Above",
"staticUpper": null,
"staticLower": null,
"splitBy": "host.id",
"seriesLimit": 20,
"warningLevel": { "severity": "Warning", "operator": "Above", "thresholdValue": 80, "durationMinutes": 5, "triggerViolationCount": 3, "isEnabled": true },
"criticalLevel": { "severity": "Critical", "operator": "Above", "thresholdValue": 90, "durationMinutes": 10, "triggerViolationCount": 5, "isEnabled": true }
}

Response 200

{
"series": [
{
"member": "host.id=srv-123",
"labels": { "host.id": "srv-123", "host.name": "payments-web-01" },
"points": [
{ "timestamp": "2026-06-01T09:00:00Z", "value": 214, "expected": 220, "lower": 154, "upper": 286, "isViolation": false, "isAlarmActive": false }
]
}
],
"ruleSeries": null,
"totalMemberCount": 12,
"from": "2026-06-01T00:00:00Z",
"to": "2026-06-02T00:00:00Z"
}
Per-point fieldMeaning
valueActual value at that timestamp.
expectedBaseline expected value (dynamic rules).
lower / upperThe threshold band in force at that time.
isViolationWhether the point breached the band.
isAlarmActiveWhether, given the trigger logic, an alarm would be active at that point.

Preview reads from the metric store by metric key; a catalog-only metric with no local data cannot be previewed. Invalid parameters return 400 with a message.


POST /api/rules

Create a rule. Extends the shared fields with naming, scheduling, and baseline settings.

Additional request fields

FieldTypeMeaning
namestringRule name.
alertingProfileIdint?Optional routing profile; null uses the default profile or configured fallback target.
consecutiveViolationCountintConsecutive breaches required.
triggerWindowMinutes / triggerViolationCountintTrigger condition for opening an alert.
lookbackWeeksintHistory span the baseline learns from.
minimumBaselinePointsintMinimum clean samples for a usable baseline.
evaluationFrequencyMinutesintHow often the rule is evaluated.
suppressLowConfidenceboolSuppress alerts when baseline confidence is low.

Response 201 (Location: /api/rules/{id}) — the full RuleDto, which also carries baselineProfileId, status, lastEvaluatedAt, and createdAt.

{
"id": 17,
"name": "API latency – dynamic",
"metricId": "demo.api.response.duration.ms",
"type": "Dynamic",
"thresholdMode": "Percentage",
"tolerancePercent": 30,
"direction": "Above",
"status": "Active",
"createdAt": "2026-06-02T09:00:00Z",
"warningLevel": { "severity": "Warning", "...": "..." },
"criticalLevel": { "severity": "Critical", "...": "..." }
}

PUT /api/rules/{id}

Update a rule by integer id. Body is the same shape as create. Returns the updated RuleDto, or 404 if the rule does not exist. Updating a rule invalidates the active-rule cache so evaluation picks up the change promptly.