Create Metric Alert Rule
Creates a threshold rule the evaluator worker will check on each cycle. A rule combines a metric, an operator, a numeric threshold, and a sliding window. When the observed value crosses the threshold the rule transitions to firing and the worker sends one notification per configured channel — subject to cooldown_seconds to suppress repeats.
Endpoint scope is optional: omit endpoint_uuid to evaluate across every endpoint owned by the caller; supply one to scope the metric to a single endpoint.
Plan-gated: requires the metric_alerts entitlement (403 without it).
Request body
request_rate (req/s), error_rate_pct (% of 4xx+5xx), p95_latency_ms, p99_latency_ms, bandwidth_in_bps, bandwidth_out_bps.>, >=, <, <=.true. Disabled rules are persisted but skipped by the evaluator.400 (see Errors), even when enabled is false. Each channel has type + target (and optional secret). Supported types: email (target must contain @); webhook (target must be an https:// URL; may include a secret the worker uses to HMAC-SHA256-sign the POST body as X-Ngris-Signature: sha256=<hex>); slack (target is a Slack Incoming Webhook https://hooks.slack.com/... URL); discord (target is a Discord webhook https://discord.com/api/webhooks/... URL). Slack/Discord carry no secret — the URL itself is the credential. A secret of **** is refused with 400 on notify_channels: it is the placeholder responses show for a saved secret, never a secret itself.Response (201 Created)
The newly-created rule (same fields as Get Alert) with its assigned uuid and endpoint_uuid. status starts at unknown until the first evaluator cycle.
The secret is write-only: a channel that has one answers "secret": "****", never the value you sent. A channel without a secret has no secret key.
Deprecated: until the sunset this response also carries the legacy integer id and *_id fields. Don't use them; read uuid and the *_uuid fields.
Errors
error and, for a field-level problem, also under fields keyed by the field name.notify_channels missing or empty: {"error": "at least one notification channel is required", "fields": {"notify_channels": "at least one notification channel is required"}}.secret is ****. A new rule has no saved secret to keep, so the placeholder is refused, keyed to notify_channels: channel #N: "****" is the masked placeholder of a saved secret, not a secret: send the webhook's secret, or none (N is the channel's 1-based position).endpoint_uuid doesn't match an endpoint in the caller's tenant. Returned as a 400 field-error keyed to endpoint_uuid, not a 404.metric_alerts.