Documentation menu

Alerts

Email alerts on traffic and goal conditions. Alerts are per-user: a team member only ever sees and manages their own.

5 endpoints, all relative to https://analytics.appfor.you. Shared rules live in Conventions, Rate limits and Error codes.

List alerts

GET/api/v2/sites/{siteId}/alertsscope: read

Sorted by creation date descending.

Path parameters

siteIdstringThe Mongo _id returned as `siteId` by GET /api/v2/sites, or the public `trackingId` embedded in the tracking snippet. Both are accepted everywhere.

Query parameters

NameTypeDescription
enabledbooleanFilter to only enabled (`true`) or only disabled (`false`) records. Omit for all.
limitintegerRows to return. Default 50, minimum 1, maximum 500.
offsetintegerRows to skip, for paging. Default 0.

Example request

curl -H "Authorization: Bearer $ANALYTICS_API_KEY" \
  "https://analytics.appfor.you/api/v2/sites/6507f1f77bcf86cd799439011/alerts?enabled=true"

Example response

{
  "alerts": [
    {
      "alertId": "6512dd04bcf86cd7994390d4",
      "siteId": "6507f1f77bcf86cd799439011",
      "type": "traffic_drop",
      "threshold": 30,
      "comparison": "previous_week",
      "enabled": true,
      "email": "ops@example.com",
      "lastTriggeredAt": null,
      "createdAt": "2025-02-20T08:00:00.000Z",
      "updatedAt": "2025-02-20T08:00:00.000Z"
    }
  ],
  "total": 1,
  "limit": 50,
  "offset": 0
}

Create an alert

POST/api/v2/sites/{siteId}/alertsscope: write

For `previous_day` and `previous_week` comparisons the threshold is a percentage change; for `absolute` it is a raw count. `email` defaults to the key owner’s account email.

  • Viewers receive 403.

Path parameters

siteIdstringThe Mongo _id returned as `siteId` by GET /api/v2/sites, or the public `trackingId` embedded in the tracking snippet. Both are accepted everywhere.

Request body

FieldTypeRequiredDescription
type'traffic_spike' | 'traffic_drop' | 'goal_completed' | 'error_rate'YesWhat the alert watches. Immutable after creation.
thresholdnumberYesMinimum 1. Percentage or raw count depending on `comparison`.
comparison'previous_day' | 'previous_week' | 'absolute'YesBaseline the threshold is measured against.
emailstringNoRecipient. Defaults to the key owner's account email.
enabledbooleanNoStart enabled or muted.

Example request

curl -X POST "https://analytics.appfor.you/api/v2/sites/6507f1f77bcf86cd799439011/alerts" \
  -H "Authorization: Bearer $ANALYTICS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "type": "traffic_drop", "threshold": 30, "comparison": "previous_week", "email": "ops@example.com" }'

Example response (201)

{
  "alertId": "6512dd04bcf86cd7994390d4",
  "siteId": "6507f1f77bcf86cd799439011",
  "type": "traffic_drop",
  "threshold": 30,
  "comparison": "previous_week",
  "enabled": true,
  "email": "ops@example.com",
  "lastTriggeredAt": null,
  "createdAt": "2025-03-21T09:00:00.000Z",
  "updatedAt": "2025-03-21T09:00:00.000Z"
}

Get an alert

GET/api/v2/sites/{siteId}/alerts/{alertId}scope: read

Returns 404 "Alert not found" if it belongs to another user or another site.

Path parameters

siteIdstringThe Mongo _id returned as `siteId` by GET /api/v2/sites, or the public `trackingId` embedded in the tracking snippet. Both are accepted everywhere.
alertIdstringIdentifier of the alert.

Example request

curl -H "Authorization: Bearer $ANALYTICS_API_KEY" \
  "https://analytics.appfor.you/api/v2/sites/6507f1f77bcf86cd799439011/alerts/6512dd04bcf86cd7994390d4"

Example response

{
  "alertId": "6512dd04bcf86cd7994390d4",
  "siteId": "6507f1f77bcf86cd799439011",
  "type": "traffic_drop",
  "threshold": 30,
  "comparison": "previous_week",
  "enabled": true,
  "email": "ops@example.com",
  "lastTriggeredAt": "2025-03-18T06:00:00.000Z",
  "createdAt": "2025-02-20T08:00:00.000Z",
  "updatedAt": "2025-02-20T08:00:00.000Z"
}

Update an alert

PATCH/api/v2/sites/{siteId}/alerts/{alertId}scope: write

`type` is immutable, mirroring the dashboard. At least one field is required. Setting `enabled` to false mutes the alert without deleting it — prefer this over deletion.

  • Viewers receive 403.

Path parameters

siteIdstringThe Mongo _id returned as `siteId` by GET /api/v2/sites, or the public `trackingId` embedded in the tracking snippet. Both are accepted everywhere.
alertIdstringIdentifier of the alert.

Request body

Every field is optional, but at least one must be supplied.

FieldTypeRequiredDescription
thresholdnumberNoMinimum 1.
comparison'previous_day' | 'previous_week' | 'absolute'NoNew baseline.
emailstringNoNew recipient.
enabledbooleanNofalse mutes the alert.

Example request

curl -X PATCH "https://analytics.appfor.you/api/v2/sites/6507f1f77bcf86cd799439011/alerts/6512dd04bcf86cd7994390d4" \
  -H "Authorization: Bearer $ANALYTICS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": false }'

Example response

{
  "alertId": "6512dd04bcf86cd7994390d4",
  "siteId": "6507f1f77bcf86cd799439011",
  "type": "traffic_drop",
  "threshold": 30,
  "comparison": "previous_week",
  "enabled": false,
  "email": "ops@example.com",
  "updatedAt": "2025-03-21T09:35:00.000Z"
}

Delete an alert

DELETE/api/v2/sites/{siteId}/alerts/{alertId}scope: adminDestructive

Pass `confirm=<alertId>` as a query parameter or as a `confirm` field in the JSON body. A missing or mismatched value returns 400 with an explicit message. Consider `enabled: false` via PATCH instead — it is reversible.

Irreversible. Requires the admin scope and confirm={alertId} — see Destructive operations.

  • Viewers receive 403.

Path parameters

siteIdstringThe Mongo _id returned as `siteId` by GET /api/v2/sites, or the public `trackingId` embedded in the tracking snippet. Both are accepted everywhere.
alertIdstringIdentifier of the alert.

Query parameters

NameTypeDescription
confirmstringDestructive-operation confirmation. Must exactly equal the `alertId` in the URL. May be sent as a `confirm` field in the JSON body instead.

Request body

Optional — send `{ "confirm": "<alertId>" }` instead of the query parameter if you prefer.

FieldTypeRequiredDescription
confirmstringNoMust equal the alertId in the URL.

Example request

curl -X DELETE "https://analytics.appfor.you/api/v2/sites/6507f1f77bcf86cd799439011/alerts/6512dd04bcf86cd7994390d4?confirm=6512dd04bcf86cd7994390d4" \
  -H "Authorization: Bearer $ANALYTICS_API_KEY"

Example response

{
  "deleted": true,
  "alertId": "6512dd04bcf86cd7994390d4"
}