Alerts
Onelo opens an incident when a feature's error rate spikes above its alert rule. Configure email recipients per app and tune thresholds per feature.
Auto-rule per feature
The first time the SDK reports an event for a new featureName, a row is created in monitor_alert_rules with a sensible default. You never have to provision rules manually.
| Field | Default | Notes |
|---|---|---|
| error_threshold | 0.10 | Fraction; 0.10 = 10% errors over the window. The auto-rule trigger sets 0.10 (the raw column default is 0.05). |
| window_mins | 15 | Sliding window in minutes. |
| enabled | true | Set to false to silence alerts for this feature without deleting the rule. |
Source: supabase/migrations/20260426000002_monitor_alert_rules_auto.sql.
Configure thresholds
Open the dashboard → Monitor → click a feature row → Configure alert. Edit error_threshold and window_mins, or flip enabled to false to disable alerts entirely for that feature. Changes apply on the next evaluation tick.
Email config (per app)
Recipients and templates live in the monitor_alert_config table — one row per app. Edit them in the dashboard; persisted via PUT /api/monitor/alert-config.
| Field | Type | Description |
|---|---|---|
| alertEmails | string[] | List of recipient email addresses. |
| alertEnabled | bool | Master switch for outbound alert emails. |
| recoveryEnabled | bool | When true, send an “all clear” email once error rate drops back below threshold. |
| alertSubject | string | Templated subject — supports {{app_name}}, {{feature_name}}, {{error_rate}}, {{errors}}, {{total}}, {{window_mins}}, {{incident_number}}, {{last_error_block}}, {{affected_str}}, {{dashboard_url}}. |
| alertHtml | string | Templated HTML body — same variables as alertSubject. |
| recoverySubject | string | Templated subject for recovery email — supports {{app_name}}, {{feature_name}}, {{error_rate}}, {{incident_number}}, {{dashboard_url}}. |
| recoveryHtml | string | Templated HTML body for recovery email — same variables as recoverySubject. |
Include {{app_name}} in your subject and body — if you manage multiple Onelo apps, recipients need to know which one the alert is about. The dashboard surfaces a warning on the app's Notifications page if a custom template is missing this variable.
{
"appId": "b3c4d5e6-…",
"alertEmails": ["[email protected]", "[email protected]"],
"alertEnabled": true,
"recoveryEnabled": true,
"alertSubject": "[Onelo] {{app_name}} · {{feature_name}} error rate {{error_rate}}",
"alertHtml": "<p>{{app_name}} / {{feature_name}}<br/>Last error: {{last_error_block}}</p>"
}Incident lifecycle
When a rule fires, Onelo opens a row in monitor_incidents. Numbering is per-workspace — unique across all apps in your tenant — and assigned by the next_incident_number(p_app_id) RPC, so your workspace's first incident is INC-0001 (a second app continues the same sequence).
| Field | Description |
|---|---|
| peak_error_rate | Highest error rate observed during the incident. |
| last_error | Most recent error string sampled while the incident is open. |
| affected_users | Count of app sessions active in the alert window — an approximation of reach, not a distinct count of users who hit the error. |
| priority | low / medium / high. Defaults to high. Editable. |
| description | Free-form incident description, editable in the dashboard. |
| notes | Separate free-form operator notes, editable in the dashboard. |
| alert_sent | Boolean, informational. Set once the email send was attempted (or skipped by the daily cap). Duplicate emails are prevented by the one-open-incident-per-feature rule, not this flag. |
| status | open / resolved. |
backend/app/scheduler.py) closes an open incident once the error rate drops back below the threshold, and sends a recovery email when recovery_enabled is on. Auto-resolve needs success traffic in the window — silence alone never closes an incident, so an error-only feature stays open until you click Resolve. You can always resolve manually (PATCH /api/monitor/incidents/{id} with status='resolved').reopen_count increments, reopened_at is set, and it shows a ↻ badge. Resolving manually never blocks a future reopen.In-app notifications
The bell icon in the dashboard reads from monitor_notifications. Each new incident inserts a row; clicking the notification or marking it read clears the badge. Notifications are per-user and don't replace email — they're a quick visual cue while you're already in the dashboard.
Webhooks
For Slack / Discord / PagerDuty fan-out, the natural integration point is the Webhooks product.
incident.opened / incident.resolved / incident.reopened, emitted from scheduler.py). The outbound Webhooks product (Slack / Discord / PagerDuty fan-out) does not yet emit these — backend/app/webhooks.py ships auth, waitlist, feedback and payment events only. Until incident webhooks land, bridge incident emails into chat.