Skip to content

API reference Alert rules

API reference

Alert rules

The API operations about alert rules, each with its input, its output and an example.

The operations about alert rules. Each one is a POST with a JSON object as its body: Making a request has the rules they share.

Create alert rule #

POST /api/v1/alerts.create · Write

Adds an alert rule to one site: a goal or a funnel, a metric, a comparison with a threshold, a trailing window and a webhook address. Rules are checked once an hour. When the value crosses the threshold a delivery with type alert.triggered is queued, again after cooldownHours while it stays breached, and alert.recovered when it is fine again. Deliveries are sent every five minutes, signed as Standard Webhooks describes. The answer carries webhookSecret, the signing secret, this once. The webhook address must be https on the default port with a public host name: no bare IP address, no user name or password, no localhost or internal name, and not an address of this service (400 invalid webhookUrl). Redirects are not followed. The endpoint starts unverified: call alerts.test to send a test, and the first 2xx answer verifies it. An unverified rule is switched off after its first failed delivery and is not retried. The metric must fit the subject (400 invalid metric), a rate threshold is at most 1 (400 invalid threshold), the subject must be a goal or funnel of this site (400 invalid subjectId). A site holds at most 25 rules and a workspace 50 (409 limit_reached). Needs a token with the Write permission.

Input #

Field Type Required Description
siteId string required The site id, from sites.list.
name string, 1 to 80 characters required A name for the rule, 1 to 80 characters. It is sent in every delivery as ruleName.
subjectType "goal" | "funnel" required What the rule watches: goal (a conversion goal) or funnel (a saved funnel).
subjectId string, 1 to 64 characters required The id of the goal (from goals.list) or of the funnel (from funnels.list). It must belong to this site.
metric "goal_completions" | "goal_rate" | "funnel_completed" | "funnel_rate" required What is measured. For a goal: goal_completions (how often it was completed) or goal_rate (visitors who completed it divided by all visitors). For a funnel: funnel_completed (visitors who did every step) or funnel_rate (completed divided by entered). The metric must fit subjectType.
comparison "below" | "above" required below: the rule is breached while the value is below the threshold. above: while it is above.
threshold number, 0 to 1000000000 required The number to compare with. A count for goal_completions and funnel_completed; a fraction from 0 to 1 for the two rates, for example 0.02 for 2 percent.
window "24h" | "7d" required The trailing period the value is measured over: 24h or 7d, ending at the start of the hour of each check.
minSample integer, 1 to 1000000 optional For the two rates: the fewest visitors (goal_rate) or entered visitors (funnel_rate) the rate is judged on. With fewer the rule has no data and does not fire. 1 to 1,000,000; 50 when left out on create. Counts ignore it. Default: 50.
cooldownHours integer, 1 to 720 optional While the rule stays breached, alert.triggered is sent again after this many hours. 1 to 720; 24 when left out on create. Default: 24.
webhookUrl string, at most 2048 characters required Where deliveries are sent, as an HTTP POST with a JSON body. The webhook address must be https on the default port with a public host name: no bare IP address, no user name or password, no localhost or internal name, and not an address of this service (400 invalid webhookUrl). Redirects are not followed. Treat the address as a secret.
enabled boolean optional Whether the rule is checked. True when left out on create. Sending true for a rule the system switched off switches it on again. Default: true.

Output #

Field Type Present Description
id string always The rule id. Pass it to alerts.update, alerts.test and alerts.deliveries as id.
name string always The name the rule was saved under.
subject object always What the rule watches: type (goal or funnel), its id, and its name. The name is empty when the goal or funnel no longer exists.
metric "goal_completions" | "goal_rate" | "funnel_completed" | "funnel_rate" always What is measured: goal_completions (a count), goal_rate (converters divided by visitors), funnel_completed (visitors who did every step) or funnel_rate (completed divided by entered).
comparison "below" | "above" always Whether the rule is breached while the value is below the threshold or above it.
threshold number always The number the value is compared with: a count, or for a rate a fraction from 0 to 1.
window "24h" | "7d" always The trailing period the value is measured over, ending at the start of the hour of each check.
minSample number always The fewest visitors (for a goal rate) or entered visitors (for a funnel rate) a rate is judged on. With fewer the rule has no data and is never breached. Counts ignore it.
cooldownHours number always While the rule stays breached, alert.triggered is sent again after this many hours.
webhookUrl string | null always The address deliveries are sent to. Null for a token without the Write permission: the address is a secret, and such a caller gets webhookHost only.
webhookHost string always The host name of the webhook address.
enabled boolean always Whether the rule is checked. A rule that was switched off by the system says why in disabledReason.
state "fine" | "breached" | "no_data" always What the last check found: fine, breached, or no_data (too small a sample for a rate, or a goal that is switched off).
lastValue number | null always The value at the last check, or null before the first check and when there was nothing to divide by.
lastSample number | null always The sample at the last check: visitors for a goal, entered visitors for a funnel. Null before the first check.
lastEvaluatedAt number | null always When the rule was last checked, milliseconds since 1970 UTC. Null before the first check. Rules are checked once an hour.
lastFiredAt number | null always When alert.triggered was last queued, milliseconds since 1970 UTC. Null when it never was.
verified boolean always Whether the endpoint has ever answered a delivery with a 2xx status. An unverified rule is switched off after its first failed delivery.
disabledReason "subject_deleted" | "endpoint_failing" | "endpoint_gone" | "endpoint_unverified" | null always Why the system switched the rule off, else null: subject_deleted (the goal or funnel is gone), endpoint_failing (20 failed deliveries in a row), endpoint_gone (the endpoint answered 410), endpoint_unverified (the endpoint failed before it ever answered).
createdAt number always When the rule was created, milliseconds since 1970 UTC.
updatedAt number always When the rule was last changed, milliseconds since 1970 UTC.
webhookSecret string always The signing secret of the rule: whsec_ followed by base64. Deliveries are signed with it as Standard Webhooks describes (HMAC-SHA256 over id.timestamp.body, keyed with the bytes after whsec_). It is shown this once and cannot be read again; store it now.

Example #

curl -s -X POST https://clearsaga.com/api/v1/alerts.create \
  -H "Authorization: Bearer $CLEARSAGA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"siteId":"site_abc123def456","name":"Signup rate dropped","subjectType":"goal","subjectId":"GOAL_ID","metric":"goal_rate","comparison":"below","threshold":0.02,"window":"7d","webhookUrl":"https://example.com/hooks/alerts"}'

Run clearsaga help alerts create for one flag per field.

Delete alert rule #

POST /api/v1/alerts.delete · Write

Removes an alert rule from one site for good, together with its delivery log (what alerts.deliveries lists) and its signing secret. This cannot be undone. To pause a rule and keep its log, call alerts.update with enabled false instead. The id comes from alerts.list. The rule is checked no more. Deliveries that were still waiting are removed with it and none is queued after that; only one that is being sent at that very moment can still arrive. The goal or funnel the rule watched is not touched, and neither is any report. An id the site does not have is not an error: the answer says deleted false and nothing was changed, so sending the same call twice is safe. Needs a token with the Write permission.

Input #

Field Type Required Description
siteId string required The site id, from sites.list.
id string, at least 1 characters required The id of the rule to remove, from alerts.list.

Output #

Field Type Present Description
id string always The id that was sent.
deleted boolean always true when the alert rule was there and this call removed it. false when the site has no alert rule with that id, because it was removed before or the id is wrong: nothing was changed, and that is not an error.
name string | null always The name the rule had, so it is clear what was removed. Null when deleted is false.

Example #

curl -s -X POST https://clearsaga.com/api/v1/alerts.delete \
  -H "Authorization: Bearer $CLEARSAGA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"siteId":"site_abc123def456","id":"ALERT_ID"}'

Run clearsaga help alerts delete for one flag per field.

List alert deliveries #

POST /api/v1/alerts.deliveries · Read

The webhook deliveries of one alert rule, newest first: what was sent (triggered, recovered or a test), the value at that moment, and how the sending went (status, attempts, the last HTTP status, when it is tried next). A failed delivery to a verified endpoint is retried with growing gaps for about a day and a half; an endpoint that never answered is not retried. The newest 200 deliveries of a rule are kept. The rows never carry the webhook address or the body that was sent. An unknown id answers 404. Keeps working while the workspace is locked.

Needs a token with the Read permission. Keeps answering while the dashboards of the workspace are locked.

Input #

Field Type Required Description
siteId string required The site id, from sites.list.
id string, at least 1 characters required The id of the rule, from alerts.list.
limit integer, 1 to 100 optional How many deliveries to answer, 1 to 100. 100 when left out.

Output #

Field Type Present Description
rows array of object always The deliveries of the rule, newest first. Each row is a delivery as alerts.test answers it.

Example #

curl -s -X POST https://clearsaga.com/api/v1/alerts.deliveries \
  -H "Authorization: Bearer $CLEARSAGA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"siteId":"site_abc123def456","id":"ALERT_ID"}'

Run clearsaga help alerts deliveries for one flag per field.

List alert rules #

POST /api/v1/alerts.list · Read

Lists the alert rules of one site, oldest first. A rule watches one conversion goal or one funnel over the last 24 hours or 7 days and calls a webhook when its number crosses a threshold. Each row says what the last hourly check found (state, lastValue, lastSample), when the rule last fired, whether its endpoint is verified and, when the system switched it off, why. The full webhook address is only in the answer for a token with the Write permission; a read token gets webhookUrl null and the host name in webhookHost. The signing secret is never listed. Keeps working while the workspace is locked.

Needs a token with the Read permission. Keeps answering while the dashboards of the workspace are locked.

Input #

Field Type Required Description
siteId string required The site id, from sites.list.

Output #

Field Type Present Description
rows array of object always One row per alert rule of the site, oldest first. Each row is a rule as alerts.create answers it, without the signing secret.

Example #

curl -s -X POST https://clearsaga.com/api/v1/alerts.list \
  -H "Authorization: Bearer $CLEARSAGA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"siteId":"site_abc123def456"}'

Run clearsaga help alerts list for one flag per field.

Send test delivery #

POST /api/v1/alerts.test · Write

Queues one test delivery (type alert.test) for an alert rule, with the numbers of its last check, and answers the delivery row with status pending. Nothing is sent during this call: deliveries are sent every five minutes, so read alerts.deliveries afterwards to see whether it arrived. A 2xx answer to a test verifies the endpoint, and switches a rule back on that was off only because its endpoint had never answered. A failed test to an unverified endpoint switches the rule off. A test is never retried. One test per rule can wait at a time (409 limit_reached test), and a rule takes at most 10 tests an hour (429 rate_limited). An unknown id answers 404. Needs a token with the Write permission.

Input #

Field Type Required Description
siteId string required The site id, from sites.list.
id string, at least 1 characters required The id of the rule, from alerts.list.

Output #

Field Type Present Description
id string always The delivery id. It is sent as the webhook-id header and stays the same across retries.
event "alert.triggered" | "alert.recovered" | "alert.test" always What the delivery says: the rule became breached (or is still breached after the cooldown), it went back to fine, or it is a test.
firedAt number always When the event happened, milliseconds since 1970 UTC.
value number | null always The value of the rule at that moment, or null when it had none.
sample number | null always The sample at that moment, or null when it had none.
threshold number always The threshold of the rule at that moment.
status "pending" | "sending" | "delivered" | "failed" always pending: waiting to be sent or retried. sending: being sent right now. delivered: the endpoint answered 2xx. failed: given up.
attempts number always How many times the endpoint was called for this delivery.
lastStatusCode number | null always The HTTP status of the last call, or null when no answer arrived (a timeout, a network error) or nothing was sent yet.
nextAttemptAt number | null always When a pending delivery is sent next, milliseconds since 1970 UTC. Deliveries are sent every five minutes. Null otherwise.
deliveredAt number | null always When the endpoint answered 2xx, milliseconds since 1970 UTC, else null.

Example #

curl -s -X POST https://clearsaga.com/api/v1/alerts.test \
  -H "Authorization: Bearer $CLEARSAGA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"siteId":"site_abc123def456","id":"ALERT_ID"}'

Run clearsaga help alerts test for one flag per field.

Update alert rule #

POST /api/v1/alerts.update · Write

Changes one alert rule. Send id and only the fields to change; a field left out keeps its value. Changing what is measured (subjectType, subjectId, metric, comparison, threshold, window, minSample) starts the rule over: its state goes back to fine and the next hourly check judges the new condition. A new webhookUrl makes the endpoint unverified again until a delivery to it gets a 2xx answer. regenerateSecret true issues a new signing secret, which is in the answer as webhookSecret this once; the old one stops working at once. The webhook address must be https on the default port with a public host name: no bare IP address, no user name or password, no localhost or internal name, and not an address of this service (400 invalid webhookUrl). Redirects are not followed. The same value rules as alerts.create apply. An unknown id answers 404. Needs a token with the Write permission.

Input #

Field Type Required Description
siteId string required The site id, from sites.list.
id string, at least 1 characters required The id of the rule, from alerts.list.
name string, 1 to 80 characters optional A name for the rule, 1 to 80 characters. It is sent in every delivery as ruleName.
subjectType "goal" | "funnel" optional What the rule watches: goal (a conversion goal) or funnel (a saved funnel).
subjectId string, 1 to 64 characters optional The id of the goal (from goals.list) or of the funnel (from funnels.list). It must belong to this site.
metric "goal_completions" | "goal_rate" | "funnel_completed" | "funnel_rate" optional What is measured. For a goal: goal_completions (how often it was completed) or goal_rate (visitors who completed it divided by all visitors). For a funnel: funnel_completed (visitors who did every step) or funnel_rate (completed divided by entered). The metric must fit subjectType.
comparison "below" | "above" optional below: the rule is breached while the value is below the threshold. above: while it is above.
threshold number, 0 to 1000000000 optional The number to compare with. A count for goal_completions and funnel_completed; a fraction from 0 to 1 for the two rates, for example 0.02 for 2 percent.
window "24h" | "7d" optional The trailing period the value is measured over: 24h or 7d, ending at the start of the hour of each check.
minSample integer, 1 to 1000000 optional For the two rates: the fewest visitors (goal_rate) or entered visitors (funnel_rate) the rate is judged on. With fewer the rule has no data and does not fire. 1 to 1,000,000; 50 when left out on create. Counts ignore it.
cooldownHours integer, 1 to 720 optional While the rule stays breached, alert.triggered is sent again after this many hours. 1 to 720; 24 when left out on create.
webhookUrl string, at most 2048 characters optional Where deliveries are sent, as an HTTP POST with a JSON body. The webhook address must be https on the default port with a public host name: no bare IP address, no user name or password, no localhost or internal name, and not an address of this service (400 invalid webhookUrl). Redirects are not followed. Treat the address as a secret.
enabled boolean optional Whether the rule is checked. True when left out on create. Sending true for a rule the system switched off switches it on again.
regenerateSecret boolean optional True to issue a new signing secret. The answer carries it once and the old one stops working.

Output #

Field Type Present Description
id string always The rule id. Pass it to alerts.update, alerts.test and alerts.deliveries as id.
name string always The name the rule was saved under.
subject object always What the rule watches: type (goal or funnel), its id, and its name. The name is empty when the goal or funnel no longer exists.
metric "goal_completions" | "goal_rate" | "funnel_completed" | "funnel_rate" always What is measured: goal_completions (a count), goal_rate (converters divided by visitors), funnel_completed (visitors who did every step) or funnel_rate (completed divided by entered).
comparison "below" | "above" always Whether the rule is breached while the value is below the threshold or above it.
threshold number always The number the value is compared with: a count, or for a rate a fraction from 0 to 1.
window "24h" | "7d" always The trailing period the value is measured over, ending at the start of the hour of each check.
minSample number always The fewest visitors (for a goal rate) or entered visitors (for a funnel rate) a rate is judged on. With fewer the rule has no data and is never breached. Counts ignore it.
cooldownHours number always While the rule stays breached, alert.triggered is sent again after this many hours.
webhookUrl string | null always The address deliveries are sent to. Null for a token without the Write permission: the address is a secret, and such a caller gets webhookHost only.
webhookHost string always The host name of the webhook address.
enabled boolean always Whether the rule is checked. A rule that was switched off by the system says why in disabledReason.
state "fine" | "breached" | "no_data" always What the last check found: fine, breached, or no_data (too small a sample for a rate, or a goal that is switched off).
lastValue number | null always The value at the last check, or null before the first check and when there was nothing to divide by.
lastSample number | null always The sample at the last check: visitors for a goal, entered visitors for a funnel. Null before the first check.
lastEvaluatedAt number | null always When the rule was last checked, milliseconds since 1970 UTC. Null before the first check. Rules are checked once an hour.
lastFiredAt number | null always When alert.triggered was last queued, milliseconds since 1970 UTC. Null when it never was.
verified boolean always Whether the endpoint has ever answered a delivery with a 2xx status. An unverified rule is switched off after its first failed delivery.
disabledReason "subject_deleted" | "endpoint_failing" | "endpoint_gone" | "endpoint_unverified" | null always Why the system switched the rule off, else null: subject_deleted (the goal or funnel is gone), endpoint_failing (20 failed deliveries in a row), endpoint_gone (the endpoint answered 410), endpoint_unverified (the endpoint failed before it ever answered).
createdAt number always When the rule was created, milliseconds since 1970 UTC.
updatedAt number always When the rule was last changed, milliseconds since 1970 UTC.
webhookSecret string may be absent Only present when regenerateSecret was true. The signing secret of the rule: whsec_ followed by base64. Deliveries are signed with it as Standard Webhooks describes (HMAC-SHA256 over id.timestamp.body, keyed with the bytes after whsec_). It is shown this once and cannot be read again; store it now. The old secret stops working at once.

Example #

curl -s -X POST https://clearsaga.com/api/v1/alerts.update \
  -H "Authorization: Bearer $CLEARSAGA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"siteId":"site_abc123def456","id":"ALERT_ID"}'

Run clearsaga help alerts update for one flag per field.