Alerts
The platform watches itself with 48 rules, and announces what they find in the Studio, by e-mail or to a webhook.
Nothing is polled by you and nothing is reported to us. Each rule reads the platform on its own cadence and compares what it measures with a warning threshold and an alert threshold. The 8 state rules have no threshold: they only say whether something is broken. A change of severity is announced, a return to normal included, and the announcement is repeated at an interval set by the rule while it keeps firing.
The four families
| Family | Rules | What it watches |
|---|---|---|
| platform | 14 | Restart loops, database, Redis and object storage errors, slow queries, queue backlog, outbox age and relay failures, refused side services, mail missing or failing, trace export failures, rate limiting |
| runs | 13 | Failure rate, lost runs, failed resumes, refusals, runs dormant on a quota, duration, queue wait, halted loops, context overflow, approvals left waiting, unanswered visitor questions, silent deployments, lost run leases |
| providers | 9 | Failed attempts, exhausted credit, failed or outdated connection tests, cost deviation, tokens per run, latency, unknown models, unusable fallback models |
| security | 12 | Login failures, denied API keys, rejected CSRF, RBAC refusals, blocked webhook egress, untrusted content, blocked outputs, operator console access, a refused sealing key, audit write failures, rejected SSO returns, an unreachable identity provider |
A family is how the screen groups rules. Every rule carries a stable key written family.subject.outcome, and that key never changes. Platform and security rules are on by default. Runs and providers rules are off until someone switches them on, with Create alert on the Alerts screen, under Monitor.
Severities
After each evaluation, a rule is ok, warning or alert. A rate whose window held too few samples to judge is no_data, and a rule not evaluated yet is unknown: both are recorded and never announced. The Alerts screen shows a rule that has never been evaluated as Awaiting data, not as healthy.
Where an alert goes
Three channels, chosen per rule. Only one of them has an address you state. This is deliberate: the other two already know where to go.
| Channel | Where it goes | You configure |
|---|---|---|
| studio | The Alerts screen, and a counter on its menu entry | Nothing |
| The active owners and admins of the organization, or the platform operators for the deployment's own rules | A working mail server | |
| webhook | One URL, stated once per scope | The URL |
The webhook channel
A scope states one URL, and Rikoo sends it a JSON POST for each announcement. There is no subscription to manage, no event catalog to pick from, and no signature. What travels is the announcement itself: the rule, the severity it announces and since when, the last measure and when it was taken, the thresholds and the window, plus a text field that says the same thing in one sentence.
Its first field is text, on purpose. A Slack incoming webhook is a URL like any other: pointing a scope at one makes alerts arrive in a Slack channel with no integration, no bot token and no workspace to connect. Rikoo keeps Slack as a destination and stopped maintaining it as an alert integration.
{
"text": "ALERT: runs.failure_rate is sounding on this organisation. Too large a share of runs is failing. Last measure: 0.23.",
"ruleId": "0b7e5c52-8d1f-4a52-9d0e-3c6f1a2b4d77",
"detector": "runs.failure_rate",
"scope": "org",
"orgId": "5a0d9f3e-2c41-4b8e-a7f6-91e2d3c4b5a6",
"channel": "webhook",
"transitionKey": "alert@1789805642511",
"severity": "alert",
"renotification": null,
"since": "2026-09-19T08:14:02.511Z",
"measure": 0.23,
"measuredAt": "2026-09-19T08:14:02.511Z",
"warningThreshold": 0.05,
"alertThreshold": 0.2,
"windowSeconds": 3600
}
The body is built field by field: no run content, and never a database row copied into it. A receiver that gets the same transitionKey twice is looking at one announcement delivered twice.
A webhook delivery is marked sent when your endpoint answers 2xx. Any other answer is retried, up to 5 attempts. For mail, sent means that the messages were handed to the mail queue, not that they arrived: no system can promise that a message reached its reader.
The address is guarded
A webhook URL is typed in by hand, so it is treated as untrusted input. Every delivery goes through the anti-SSRF guard, which checks the address the host actually resolves to and follows a redirect only to an address it would also accept. A webhook aimed at a link-local metadata endpoint is refused before it leaves.
A refusal by that guard is itself announced, under security.webhook_egress_blocked. An address that resolves somewhere it must not is what an attempt to reach your internal network looks like from here, so it gets a rule instead of a silent error.
Saving a URL sends nothing, because the API server never calls the outside world. Send a test queues a real delivery, with the same body as a real announcement. The proof is the message arriving in the Slack channel or in the receiving service's log, not a green tick drawn by the platform.
What a rule lets you change
Four settings, and no more: whether it is on, its two thresholds and its channels. Everything else is the behavior of the rule, frozen in the product, which is what makes two deployments comparable.
- Window and cadence. How far back an evaluation looks, and how often it runs.
- Minimum samples. A rate refuses to judge a window with too few samples. One failed run out of one is not a 100% failure rate, it is one failed run.
- Re-notification. How long before the same severity is announced again while a rule keeps firing. Acknowledge silences it until the severity changes.
- No-data policy. What an empty window is worth, which is not the same answer for a queue depth and for a heartbeat.
Its 12 rules refuse to be disabled: the API rejects the attempt. You can still adjust their thresholds, because a threshold is a judgment about your traffic, but a deployment that could silence its own failed logins would have an audit that means nothing.
Two scopes
A rule belongs either to the deployment, read by a platform operator, or to one organization: 20 rules are the deployment's, 28 belong to each organization. The two live in the same table, told apart by whether they carry an organization, and the tenant isolation policy is what gives the distinction its teeth: a row that belongs to no organization is reachable by no tenant connection. The Alerts screen of the Studio shows the organization's rules.