Skip to Content
ConceptsAlerts & Contacts

Alerts & contacts

Available

  • Contacts and contact lists
  • Address verification (email link, SMS code)
  • Trigger and reset alerts with cooldowns
  • Aggregated alerts (one message per contact)
  • Delivery log
  • alert.sent webhook events

Planned

  • Per-contact test sends

When a Flow triggers (its tile chain evaluates true for a target) or resets (returns to normal), the Engine can notify people by email, SMS, or voice call.

Contacts

A contact is a recipient a user manages (/v1/contacts; owned per user, see tenancy): display name, email and/or phone, and per-channel opt-ins (emailOptIn, smsOptIn, callOptIn). Contacts are grouped into contact lists (/v1/contact-lists); flows reference lists, never individual contacts. A contact’s blacklist holds Source ids they should never be alerted for: per-person muting of specific fields/sensors.

The Engine never sends to an unverified address. Verify each address once via POST /v1/contacts/{id}/verifications ({"channel": "email" | "sms"}). Email gets a one-time link (24 h), SMS a 6-digit code (10 min, 5 attempts) confirmed with POST …/verifications/confirm. The same flow exists for users. Changing an address resets its verification; skipped sends are recorded as skipped_unverified in the delivery log.

In the Growth Lab GUI, manage people in Settings → Contacts (Add contact / Assign). The Alerts step only lets you pick which lists this flow uses. Unverified channels show a badge; Edit contact sends the email link or SMS code for your own contacts. Run on the flow is silent unless you check Also send alerts.

Alert configuration (per flow)

Alert config lives in the flow’s settings.alerts block (validated by the Engine):

{ "settings": { "alerts": { "contactListIds": ["…"], "triggerTypes": ["trigger", "reset"], // "trigger" = only on a NEW crossing; "reset" enables return-to-normal alerts "triggerAlertCooldownMinutes": 10, "resetAlertCooldownMinutes": 10, "triggerMessage": "Scout the field today.", // appended to the alert text "resetMessage": "", "aggregateAlerts": false } } }

Semantics (unchanged from Growth Lab):

  • Every-run vs crossing-only. Without "trigger" in triggerTypes, an alert goes out on every run while the target stays triggered (subject to the cooldown). With it, alerts fire only when a target newly crosses into the triggered state.
  • Cooldowns are per target and anti-flap: a target that flaps trigger→reset→trigger inside the window stays quiet.
  • Quiet sensors can’t cause false resets. If a run fetches no newer sensor/scout data than the previous evaluation saw, the target’s previous trigger state holds, so a beacon going dark for a couple of hours won’t fire a spurious “back to normal” alert. A genuine new trigger is always honored, and normal evaluation resumes as soon as fresh data arrives.
  • Aggregation (aggregateAlerts): one combined message per contact per run listing every alerting target (“Frost Flow trigger for 3 areas: A, B, C”) instead of one message per target. SMS/voice truncate at 3 names; email lists all.
  • Message wording: "{flowName} Flow {trigger|reset} for {targetType} {targetName}", with your triggerMessage/resetMessage appended on a new line.

When alerts run

After every scheduled run, and after manual runs started with POST /v1/flows/{id}/run {"suppressAlerts": false}. Plain manual runs default to suppressed so you can iterate on a flow without paging anyone. Evaluation happens in a background job after the run finishes; a transport outage never affects the run itself. Every send attempt and every meaningful skip is recorded per contact/channel in the delivery log.