BuildBaseBuildBase

Triggers and actions

The full catalog of workflow triggers, actions, and conditions with their inputs and outputs.

Every node in a workflow graph is one of three kinds, identified by a dotted ID whose prefix names the kind:

KindPrefixCount
Triggertriggers.62
Actionactions.19
Conditionconditions.3

A workflow needs at least one trigger. Actions and conditions are optional, but a graph with no action does nothing observable.

You pick these from the console's node palette rather than writing them, but the IDs are what a workflow's exported JSON contains — so this is the table you read when inspecting an export or a stored flow:

{
  "nodes": [
    { "id": "n1", "kind": "trigger", "type": "triggers.form.submitted" },
    { "id": "n2", "kind": "condition", "type": "conditions.if_else" },
    { "id": "n3", "kind": "action", "type": "actions.send_email" }
  ],
  "edges": [
    { "source": "n1", "target": "n2" },
    { "source": "n2", "target": "n3", "sourceHandle": "true" }
  ]
}

sourceHandle is how a branch is chosen: condition nodes emit true and false, and actions.wait_for_event emits event_received and timeout. An edge with no handle is the default path.

Fetch a workflow's flow with GET /api/workflows/:id/export.

Triggers

Audience

Thirteen triggers covering membership, tags, lists, and compliance state.

IDFires when
triggers.audience.member_createdA new audience member is created
triggers.audience.member_updatedAny member field changes
triggers.audience.attribute_changedA specific custom attribute changes
triggers.audience.added_to_listAdded to an audience list
triggers.audience.removed_from_listRemoved from an audience list
triggers.audience.tag_addedA tag is applied
triggers.audience.tag_removedA tag is removed
triggers.audience.unsubscribedOpted out
triggers.audience.resubscribedOpted back in
triggers.audience.blockedBlocked
triggers.audience.unblockedUnblocked
triggers.audience.email_invalidatedAddress marked invalid, usually after a hard bounce
triggers.audience.import_completedA bulk import finished

Email engagement

IDFires when
triggers.email.sentA message is dispatched
triggers.email.openedThe tracking pixel loads
triggers.email.clickedA tracked link is followed
triggers.email.bouncedDelivery hard-fails
triggers.email.unsubscribedRecipient opts out from this message
triggers.email.campaign_sentA whole campaign finishes sending

opened and clicked depend on tracking being enabled for the template. Neither is reliable enough to gate access on — image blocking suppresses opens.

Subscription

IDFires when
triggers.subscription.createdFirst subscription on a workspace
triggers.subscription.updatedAny subscription field changes
triggers.subscription.upgradedMoved to a higher plan
triggers.subscription.canceledCanceled immediately
triggers.subscription.cancel_scheduledCancellation set for period end
triggers.subscription.resumedReactivated after cancellation
triggers.subscription.suspendedSuspended, typically for non-payment
triggers.subscription.trial_startedTrial begins
triggers.subscription.trial_will_endTrial is approaching its end
triggers.subscription.trial_expiredTrial ended without conversion

cancel_scheduled and canceled are distinct. A win-back sequence should listen for cancel_scheduled, which still has time to act.

Payment, credits, quota

IDFires when
triggers.payment.succeededPayment captured
triggers.payment.failedPayment declined
triggers.payment.action_requiredPayment needs 3DS or similar
triggers.credit.purchasedCredits bought
triggers.credit.grantedCredits issued without payment
triggers.credit.consumedCredits spent
triggers.credit.expiredCredits lapsed
triggers.credit.low_balanceBalance crossed the low threshold
triggers.quota.limit_exceededA metered quota was exceeded

User and organization

IDFires when
triggers.user.registeredAccount created
triggers.user.email_verifiedAddress confirmed
triggers.user.logged_inSuccessful sign-in
triggers.user.password_changedPassword updated
triggers.user.password_reset_requestedReset requested
triggers.user.profile_updatedProfile fields changed
triggers.organization.member_invitedOrg invite sent
triggers.organization.member_acceptedOrg invite accepted
triggers.organization.member_removedOrg member removed

Workspace

IDFires when
triggers.workspace.createdWorkspace created
triggers.workspace.updatedWorkspace fields changed
triggers.workspace.deletedWorkspace deleted
triggers.workspace.member_addedMember joins
triggers.workspace.member_removedMember leaves
triggers.workspace.member_role_changedA member's role changes
triggers.workspace.settings_updatedSettings changed
triggers.workspace.features_updatedFeature flags toggled

Forms, push, workflows

IDFires when
triggers.form.submittedA form is submitted
triggers.push.campaign_sentA push campaign finishes sending
triggers.workflow.publishedA workflow version is published
triggers.workflow.pausedA workflow is paused
triggers.workflow.resumedA workflow is resumed
triggers.workflow.instance_completedAn instance finishes successfully
triggers.workflow.instance_failedAn instance fails

The triggers.workflow.* family lets one workflow react to another — useful for alerting on repeated failures without polling.

Actions

Email and push

IDNotes
actions.send_emailTwo modes: Use Template or Custom Content. Outputs delivery status plus engagement fields (Email Opened, Link Clicked, Email Bounced, Open Count) that populate as they happen
actions.send_pushTargets an audience member, a workspace, or a user. Outputs Delivered, Status, Skipped, Skip Reason

Both report Skipped with a Skip Reason rather than failing when a recipient is unsubscribed or has no push subscription. A skipped send is not an error and does not consume a retry.

Timing

IDNotes
actions.delayThree modes: fixed duration (minutes, hours, days), until a time of day, or until the next weekday — including a "next business day" option
actions.wait_for_eventPauses the instance until a matching event arrives or a timeout fires

wait_for_event is the branching primitive for engagement flows. It exposes two outgoing handles, event_received and timeout, so "opened the email" and "did not open within three days" are separate paths.

Match conditions use three operators: eq, exists, and contains. Timeout can be a fixed duration, a time of day, or no timeout at all — an instance waiting forever stays running and counts against re-entry rules.

Audience and CRM

IDPurpose
actions.add_tag / actions.remove_tagTag management. Outputs include Was Already Tagged-style flags
actions.audience_list_add / actions.audience_list_removeList membership
actions.audience_subscribe / actions.audience_unsubscribeOpt-in state, with a reason on unsubscribe
actions.audience_block / actions.audience_unblockBlocking, with a reason
actions.audience_mark_invalidFlag an address as undeliverable
actions.update_audienceUpdate name, email, language, country, timezone, currency, or custom attributes
actions.grant_creditsGrant credits to a workspace. Outputs Amount Granted and Balance After

Every compliance action outputs a "was already in that state" boolean, so a workflow can branch on whether it actually changed anything rather than re-notifying someone who was already unsubscribed.

Lookup and data

IDPurpose
actions.get_audienceLook up a member by ID or email. Outputs the full profile — tags, lists, country, timezone, custom attributes — plus Found
actions.get_workspaceLook up a workspace. Outputs member count, owner email, subscription status, plan name, billing currency
actions.data_transformExtract a field, parse JSON, format a date, evaluate a math expression, replace or split a string, change case, render a template, or set a static value

Found is a boolean output, not a failure. A lookup that matches nothing continues the flow — branch on Found with a condition rather than assuming the instance stops.

Integrations

IDPurpose
actions.http_webhookCall your own API. See webhook actions

Conditions

IDBehavior
conditions.if_elseBranches on a field check. Handles: true, false
conditions.filterContinues only when the check passes, otherwise ends this path
conditions.split_randomPercentage split, for A/B testing a sequence

conditions.split_random is the only non-deterministic node in a workflow. The same subject re-entering a workflow can take a different branch, so do not use it where a stable assignment matters.

Merge tags

Any input marked allowMergeTags accepts {{path}} referring to the trigger payload or an earlier node's outputs. The console offers only tags that are actually reachable from that node.

Publishing validates every reference, and an invalid one is a blocking error — not a warning. Two cases are rejected:

  • the tag points at a node that has been deleted
  • the tag names an output the referenced node does not produce

So a broken merge tag stops the publish rather than resolving to an empty string at run time. Note this is stricter than the email template engine, where an unknown tag silently becomes an empty string.

Next Steps