Alerts
An alert says which processing events of which flows should notify whom. Alert definitions
are stored with the flows (durable with store.dialect: postgres) and managed over the API and
the command-line client. Every request needs the alerts:edit permission.
!!! note "Stored, not sent yet" Alerts do not fire yet: no email or webhook is sent. Today these endpoints store, validate, and return the definitions, so you can set them up and move them between servers. Testing an alert is a dry run that shows what would be sent.
An alert
{
"id": "adt-errors",
"name": "ADT errors",
"enabled": true,
"trigger": {"events": ["message.errored", "message.dead-lettered"], "flows": ["adt"]},
"actions": [
{"type": "email", "to": ["ops@example.com"]},
{"type": "webhook", "url": "https://hooks.example.com/weavster"}
]
}
| Field | Rules |
|---|---|
id |
Required. 1–128 characters from A-Z a-z 0-9 . _ -; not import, options, or statuses. An alert saved as statuses by an earlier release is still listed, exported and deleted, but GET /api/v1/alerts/statuses now returns the statuses: export it with exportalert statuses "file", change its id in the file, import it, and delete the old one. |
name |
Required, 1–200 characters. |
enabled |
true or false (default false). |
trigger.events |
At least one of message.errored (the transform failed), message.queued (a delivery failed and will be retried), message.dead-lettered (retries ran out). |
trigger.flows |
Flow ids. Leave it out for every flow. |
actions |
At least one. {"type":"email","to":[addresses]} with plain addresses (ops@example.com, not Ops <ops@example.com>), or {"type":"webhook","url":"http(s)://…"}. A webhook URL may not contain a user name or password, because everyone who can read alerts sees it; put a token in the path or query only if that is acceptable. |
Unknown fields and invalid values are rejected with 400 and a message naming the problem.
GET /api/v1/alerts/options lists the allowed trigger events and action types.
API
| Request | What it does |
|---|---|
GET /api/v1/alerts |
Every alert, sorted by id. |
POST /api/v1/alerts |
Creates one alert (201; 409 if the id is taken). |
GET /api/v1/alerts/{id} |
One alert (404 if unknown). |
PUT /api/v1/alerts/{id} |
Creates or replaces one alert. id in the body is optional and must match the path. |
DELETE /api/v1/alerts/{id} |
Deletes one alert (204). |
POST /api/v1/alerts/{id}/enable, POST /api/v1/alerts/{id}/disable |
Turns an alert on or off and returns it. |
POST /api/v1/alerts/import |
Saves a JSON array of alerts, all or nothing. An id that already exists is 409 and nothing is saved; add ?force=true to replace existing alerts. |
GET /api/v1/alerts/options |
{"events": [...], "actionTypes": [...]}. |
GET /api/v1/alerts/statuses |
Every alert's id, name, and enabled, sorted by id. |
GET /api/v1/alerts/{id}/info |
{"alert": {...}, "events": [...], "actionTypes": [...]}: the alert with the values it may use (404 if unknown). |
POST /api/v1/alerts/{id}/test |
A dry run: whether an event of a flow would trigger the alert, and which actions would run. See below. |
curl -s -u 'admin:PASSWORD' -H 'X-Weavster-CSRF: 1' -X POST http://127.0.0.1:8080/api/v1/alerts \
-d '{"id":"adt-errors","name":"ADT errors","enabled":true,"trigger":{"events":["message.errored"],"flows":["adt"]},"actions":[{"type":"email","to":["ops@example.com"]}]}'
curl -s -u 'admin:PASSWORD' -H 'X-Weavster-CSRF: 1' -X POST http://127.0.0.1:8080/api/v1/alerts/adt-errors/disable
Test an alert
POST /api/v1/alerts/{id}/test checks an alert against an event without waiting for one. The body
is optional: event defaults to the alert's first trigger event and flowId to the first of its
trigger.flows. An alert without trigger.flows matches every flow, so flowId may be left out.
A disabled alert can be tested too: matches and actions then show what it would do once
enabled, and enabled: false says that today it does nothing.
curl -s -u 'admin:PASSWORD' -H 'X-Weavster-CSRF: 1' -X POST \
http://127.0.0.1:8080/api/v1/alerts/adt-errors/test -d '{"event":"message.errored","flowId":"adt"}'
{"matches":true,"enabled":true,"event":"message.errored","flowId":"adt","actions":[{"type":"email","to":["ops@example.com"]}],"delivered":false}
matchesis false, with noactions, when the event is not intrigger.eventsor the flow is not intrigger.flows.deliveredis alwaysfalse: nothing is sent, not even a test message.- An event that is not one of the trigger events in
GET /api/v1/alerts/options, or an invalid flow id, returns400.
Command-line client
| Command | What it does |
|---|---|
exportalert id "path" |
Writes one alert, chosen by id or name (quote a name with spaces), to a JSON file. An id match wins; a name that several alerts share is refused, so export those by id. |
exportalert * "path" |
Writes every alert. |
importalert "path" [force] |
Saves the alerts in the file. Without force, an alert whose id already exists stops the import and nothing is saved. |
weavster> exportalert * "alerts.json"
exported 2 alerts to alerts.json
weavster> importalert "alerts.json" force
imported 2 alerts from alerts.json
The file is a JSON array of alerts, the same shape the API uses, so you can edit it before importing it on another server.