Skip to main content

Alerts

Create an alert

Add a rule that emails somebody when traffic moves.

POST/sites/{siteId}/alerts
Create an alert
curl --request POST \
  --url 'https://truestat.io/api/v1/sites/{siteId}/alerts' \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
  "body": "<string>",
  "name": "<string>",
  "enabled": true,
  "subject": "<string>",
  "goal_name": "<string>",
  "threshold": 0,
  "trigger_type": "goal",
  "threshold_mode": "absolute"
}'
{
  "data": {
    "id": "ed054a7c-696a-4db4-809e-531a169da959",
    "body": null,
    "name": "Traffic dropped by half",
    "enabled": true,
    "subject": null,
    "goal_name": null,
    "threshold": 50,
    "created_at": "2026-09-16T18:05:00.000Z",
    "created_by": "734c7de3-58f1-46e6-83d1-2be85466ee70",
    "updated_at": "2026-09-16T18:05:00.000Z",
    "trigger_type": "traffic_drop",
    "last_fired_at": null,
    "threshold_mode": "percent_change"
  },
  "meta": {
    "site_id": "6fed8980-a119-4a9c-a4d4-53e448ef9f9e"
  }
}

Pick the shape first

A goal alert and a traffic alert take different fields, and sending the wrong pair is a 400 naming the one to fix.

Goal
{
  "name": "Signups stopped",
  "trigger_type": "goal",
  "goal_name": "signup"
}

threshold is refused on a goal alert and goal_name on a traffic one — not ignored. A field you cannot use is a field you thought did something.

Choose threshold_mode deliberately

percent_change compares against the same hour last week, which is what makes it usable on a site with a weekly rhythm. absolute compares against a flat count, and on most sites that means firing every Saturday night until everybody mutes the emails.

The default email is usually the right one

subject and body are optional. Leave them out and the alert sends the default copy, which already names the site, the rule and the numbers.

A custom body must be at least 10 characters. The table refuses shorter, and an almost-empty alert email helps nobody.

Your plan caps how many you can have

Past the limit this answers 402 naming the allowance — not a 500, and not a silent failure. The message says how many your plan includes so you can decide between removing one and moving up a step.

Create an alert switched off with {"enabled": false}, then turn it on once you have checked the threshold against real traffic. That is easier than discovering the number was wrong from the emails.

Authorizations

Authorizationstringheaderrequired

An API key from Settings → API keys. Scopes available: analytics:read, sites:read, sites:write, settings:read, settings:write, goals:read, goals:write, funnels:read, funnels:write, notes:read, notes:write, alerts:read, alerts:write, team:read, team:write, revenue:read, revenue:write.

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Path parameters

siteIdstring (uuid)pathrequired
The site's id, from `GET /sites`. A site that is not yours and a site that does not exist both answer 403, so this cannot be used to discover other people's ids.

Request bodyapplication/json

bodystringbody
Custom email body, at least 10 characters. Empty means the default.
namestringbodyrequired
What to call it.
enabledbooleanbody
Create it switched off by sending false.
subjectstringbody
Custom email subject. Empty means the default.
goal_namestringbody
Required when `trigger_type` is `goal`; refused otherwise.
thresholdintegerbody
Required for a traffic trigger; refused for `goal`.
trigger_typeenum<string>bodyrequired
What it watches.
options:goaltraffic_spiketraffic_drop
threshold_modeenum<string>body
`absolute` compares against a count; `percent_change` against the same hour last week.
options:absolutepercent_change

Response

application/json

The answer.

dataobject
metaobject