Alerts
An AlertRule watches one trace metric (confidenceScore, status,
or the org-level cpiScore) and fires one or more configured
actions (Slack, custom webhook, email) when the condition matches.
On match the dispatcher also fires the
alert.triggered webhook event so external
systems can fan out further. Tested against API version v1.
JWT auth on every endpoint; mutations require admin or owner
(DELETE is owner-only); plan-gated by slackAlerts (Scale and
above).
The AlertRule object
| Field | Type | Required | Description |
|---|---|---|---|
_id / id | string | yes | MongoDB ObjectId |
organizationId | string | yes | Owning org |
workspaceId | string | no | null makes the rule org-wide |
name | string | yes | Trimmed; max 100 characters; unique per (org, workspace, name) |
description | string | no | Default '' |
severity | enum | no | critical, warning (default), info |
isActive | boolean | no | Default true; inactive rules are not evaluated |
condition | object | yes | The match criterion (see below) |
actions | Action[] | yes | One to ten actions (see below) |
lastTriggeredAt | string (ISO 8601) | no | Set on each match |
createdAt / updatedAt | string (ISO 8601) | no | Standard timestamps |
condition object
| Field | Type | Required | Description |
|---|---|---|---|
field | enum | yes | confidenceScore, status, or cpiScore (the org-level Compliance Performance Index, 0–100) |
operator | enum | yes | lt, lte, eq, gte, gt |
value | number | yes | Comparison value |
Action object
| Field | Type | Required | Description |
|---|---|---|---|
type | enum | yes | slack, webhook, or email |
target | string | yes | Slack webhook URL, custom HTTPS endpoint, or email address; trimmed; max 500 characters |
Endpoints
GET /api/v1/alerts
POST /api/v1/alerts
PATCH /api/v1/alerts/:id
DELETE /api/v1/alerts/:id
POST /api/v1/alerts/:id/test
POST /api/v1/alerts/check-cpi
List alerts
GET /api/v1/alerts
Returns every alert rule in the caller's organisation. Workspace
scope comes from the x-workspace-id header.
curl https://api.adjudon.com/api/v1/alerts \
-H "Authorization: Bearer $ADJUDON_API_KEY"
Errors: 401, 403 UPGRADE_REQUIRED (plan gate), 500
INTERNAL_ERROR.
Create an alert
POST /api/v1/alerts
curl -X POST https://api.adjudon.com/api/v1/alerts \
-H "Authorization: Bearer $ADJUDON_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Low confidence — finance",
"severity": "warning",
"condition": {
"field": "confidenceScore",
"operator": "lt",
"value": 0.6
},
"actions": [
{ "type": "slack", "target": "https://hooks.slack.com/services/T0/B0/XXXX" },
{ "type": "webhook", "target": "https://hooks.example.com/adjudon-alerts" }
]
}'
import os, requests
r = requests.post(
"https://api.adjudon.com/api/v1/alerts",
headers={"Authorization": f"Bearer {os.environ['ADJUDON_API_KEY']}"},
json={
"name": "Low confidence — finance",
"severity": "warning",
"condition": {"field": "confidenceScore", "operator": "lt", "value": 0.6},
"actions": [{"type": "slack", "target": "https://hooks.slack.com/..."}],
},
)
Errors: 400 VALIDATION_ERROR (invalid name / condition /
actions), 401, 403 (role), 500.
Update an alert
PATCH /api/v1/alerts/:id
Partial update of any field. Pause an alert without losing it via
{ "isActive": false }.
curl -X PATCH https://api.adjudon.com/api/v1/alerts/65b1f2c4 \
-H "Authorization: Bearer $ADJUDON_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "isActive": false }'
Errors: 401, 404 NOT_FOUND, 500.
Delete an alert
DELETE /api/v1/alerts/:id
Hard-deletes the alert rule. Owner role required — the
admin role can create, update, and test alerts but not delete
them; this is intentional and protects against accidental loss of
a critical alert configuration.
curl -X DELETE https://api.adjudon.com/api/v1/alerts/65b1f2c4 \
-H "Authorization: Bearer $ADJUDON_API_KEY"
Errors: 401, 403 (admin attempting delete), 404, 500.
Test an alert
POST /api/v1/alerts/:id/test
Fires every configured action with a synthetic payload so you can
confirm the Slack webhook resolves, the custom-webhook handler
returns 2xx, and the email path delivers. The endpoint returns
200 on full success or 400 TEST_FAILED with a per-action
breakdown when one or more actions failed.
curl -X POST https://api.adjudon.com/api/v1/alerts/65b1f2c4/test \
-H "Authorization: Bearer $ADJUDON_API_KEY"
Errors: 400 TEST_FAILED (delivery failure surfaced in data),
401, 404, 500.
Check CPI alerts
POST /api/v1/alerts/check-cpi
Runs every cpiScore-watching alert rule against the org's current
Compliance Performance Index value. Used by the scheduled CPI
recompute job; admins can also trigger it manually after a CPI
recalculation. Errors: 401, 403 (role), 500.
Common gotchas
- Plan-gate. The whole resource requires the
slackAlertsfeature. Sandbox plans receive403 UPGRADE_REQUIRED. - Delete is owner-only. The
adminrole can create, update, and test alerts but cannot delete them. UsePATCHwithisActive: falseto pause a rule without losing it. condition.fieldis enum-bounded. OnlyconfidenceScore,status, andcpiScoreare accepted at schema level. Custom fields are not supported — if you need to alert on a trace metric we don't surface, route the trace through a webhook and run the rule on your side.alert.triggeredwebhook event. A matched alert rule fires the configured actions and the globalalert.triggeredwebhook event. Subscribe a webhook to this event to fan out further (PagerDuty, Datadog, internal SIEM) without writing per-rule HTTP integrations.- Idempotency. The
Idempotency-Keymiddleware is wired only onPOST /traces; create/update/test on this resource do not auto-receive idempotency keys. The(org, workspace, name)unique index protects against duplicate creates.
See also
- Webhook Events Catalog — the
alert.triggeredevent payload schema - Auto-Approval API — the flip-side of an alert: pre-clear traces matching a trusted pattern instead of paging on them
- Notifications API — the in-app equivalent for surfacing alerts to dashboard users
- Reviews API — flag-for-review policy actions and alert rules cover overlapping ground
- Error Codes — the full error taxonomy