Automations
An automation is a sequence of steps that fires when a trigger matches. Triggers, steps, and per-account scoping are all declarative — the dispatcher handles matching, deduping, and retries.
Anatomy
Trigger declares the event to listen for. When the dispatcher fires, matching active automations are found per account. Each starts an AutomationRun that walks AutomationStep rows in order and writes an AutomationLog per attempt.
Triggers
MESSAGE_RECEIVEDFirst inbound message — useful for human handoff.KEYWORD_DETECTEDA keyword list matched inside the inbound text (case-insensitive).CONTACT_TAG_ADDEDA tag was applied to a contact — fires only on genuine adds.CONTACT_CREATEDNew contact via import, form, API, or inbound message.CAMPAIGN_COMPLETEDA specific campaign finished sending.SCHEDULETime-of-day / cron schedule, evaluated per contact timezone.CONTACT_BIRTHDAYRuns on the contact’s dob at send-hour.DEAL_STAGE_CHANGEDA deal moved to a target stage in a pipeline.BUTTON_REPLY_RECEIVEDReply to a SEND_INTERACTIVE_BUTTONS message.LIST_REPLY_RECEIVEDReply to a SEND_INTERACTIVE_LIST message.
Actions
SEND_MESSAGEFree-form text with {{firstName}}/{{lastName}}/{{fullName}}/{{phoneNumber}}/{{email}} substitution.SEND_TEMPLATEResolve template by (workspaceId, name); honors campaign-style variable mapping.SEND_INTERACTIVE_BUTTONSUp to 3 reply buttons — button replies re-trigger via BUTTON_REPLY_RECEIVED.SEND_INTERACTIVE_LISTMulti-row list picker; replies re-trigger via LIST_REPLY_RECEIVED.ADD_TAG / REMOVE_TAGUpserts the tag by name and connects/disconnects the relation.UPDATE_CONTACTWhitelisted fields (firstName, lastName, email, optOut) replace; other fields merge into customFields.SEND_CAMPAIGNEnqueues the campaign through the scheduler for the matched contact.DELAYDefers the next step by N minutes.WEBHOOKPOSTs a versioned {event, deliveredAt, data} envelope to your URL.
Account scoping
An automation can be tenant-wide (no accountId) or pinned to one WhatsApp account. Pinned automations are silently dropped when the account isn’t ACTIVE — no retries, no error noise.
Execution policy
RESTART(default) — cancel any in-flight run for the same contact and start fresh.IGNORE— drop the new event while a run is active.PARALLEL— allow concurrent runs for the same contact.
SCHEDULE, CAMPAIGN_COMPLETED, and DEAL_STAGE_CHANGED always start fresh regardless of the policy.
Recipes
Welcome message
CONTACT_CREATED → SEND_TEMPLATE
Fires the moment a contact is created. Pairs well with a delayed follow-up via DELAY + SEND_MESSAGE.
Keyword auto-reply
KEYWORD_DETECTED → SEND_TEMPLATE → or → SEND_INTERACTIVE_BUTTONS
Match a phrase, send a template or button menu, then capture the button reply back into a separate flow.
Tag-based re-engagement
CONTACT_TAG_ADDED → SEND_MESSAGE
Tags carry context — fire different copy depending on which tag was added by inspecting triggerConfig.tag.