Rule syntax, channels, cooldowns, group_by. Two ways to configure: YAML in the project repo, or the dashboard form. The YAML is the canonical source if both are present.
version: 1
project: truecom
rules:
- name: fatal_in_production
when: "level:fatal env:production"
threshold: "count > 0 in 1m"
channels: [slack-prod, email-eric]
cooldown: 5m
- name: error_spike
when: "level:error env:production"
threshold: "rate > baseline * 5 in 5m"
group_by: [project]
channels: [slack-prod]
- name: new_fingerprint_prod
when: "fingerprint:new env:production"
channels: [slack-prod]
- name: regression
when: "fingerprint.was_resolved == true"
channels: [slack-prod, email-eric]
- name: slow_p95
when: "span.duration_p95 > 1000ms"
group_by: [operation]
channels: [slack-prod]
channels:
- id: slack-prod
type: slack
webhook: ${SLACK_WEBHOOK_URL}
- id: email-eric
type: email
to: [[email protected]]
- id: ops-webhook
type: webhook
url: ${OPS_WEBHOOK_URL}
secret: ${OPS_WEBHOOK_SECRET} # signs payload with hmac-sha256
method: POST
headers:
X-Source: coderadar
coderadar alerts apply --file=.coderadar/alerts.yaml
# diff first:
coderadar alerts diff --file=.coderadar/alerts.yaml
Same as the dashboard search. Supported operators:
field:value — exact match.field:value1,value2 — OR.field:*pattern* — glob.field.subfield:value — nested.in:5m — time window (5m, 1h, 24h, 7d).env:production, level:error, project:foo — common shorthands.count > N in WINDOW — absolute count.rate > N/min in WINDOW — events per minute.rate > baseline * N in WINDOW — spike against rolling baseline.span.duration_p95 > 1000ms — span percentile.project.quota_remaining_pct < N — quota burn-rate.Splits the threshold per group. group_by: [project] means the rule fires once per project that meets the threshold. Common groupings: project, environment, fingerprint, operation, customer (tag).
Default: 5 minutes. After a rule fires, it won't fire again for the same group within the cooldown window. Override per rule.
Slack — incoming webhook URL. The body is block-kit formatted with the issue title, fingerprint, sample stack frame, and a link to the dashboard.
Email — list of to: addresses. Sent via Resend. Subject line is configurable.
Webhook — generic POST. Body is the alert event JSON; signed with HMAC-SHA256 if a secret is set. Custom headers allowed.
PagerDuty / Microsoft Teams / SMS — roadmap
POST $WEBHOOK_URL
Content-Type: application/json
X-CodeRadar-Signature: sha256=...
X-CodeRadar-Event: alert.fired
{
"alert_id": "al_01HZS...",
"rule": "fatal_in_production",
"project": "truecom",
"fired_at": "2026-04-26T14:22:08Z",
"fingerprint": "fp_e3a9c1",
"level": "fatal",
"count": 1,
"sample_event": { "...": "..." },
"dashboard_url": "https://app.coderadar.app/projects/truecom/issues/fp_e3a9c1"
}
cooldown aggressively for noisy fingerprints. 30 minutes for first-time-noisy issues is fine.[project] for spike rules so a single rule covers the whole portfolio.fingerprint:new env:production is the most useful default rule — fires when a new error class shows up in prod.