Building Workflows
Create automated email and SMS sequences using the Wraps workflow DSL.
Define automated email and SMS sequences as code using a declarative DSL. Build drip campaigns, onboarding sequences, and re-engagement flows that run on the Wraps Platform.
A workflow is a sequence of steps triggered by an event. Each workflow is defined in a TypeScript file using the defineWorkflow helper and exported as the default export.
// wraps/workflows/welcome-sequence.tsimport { defineWorkflow, sendEmail, delay, condition, exit, waitForEvent,} from '@wraps.dev/client';export default defineWorkflow({ name: 'Welcome Sequence', trigger: { type: 'contact.created', }, settings: { maxEnrollments: 1, // Each contact enters once }, steps: [ sendEmail('welcome', { template: 'welcome-email' }), delay('wait-1-day', { days: 1 }), condition('check-activated', { field: 'contact.hasActivated', operator: 'equals', value: true, branches: { yes: [exit('already-active')], no: [ sendEmail('activation-reminder', { template: 'activate' }), delay('wait-2-days', { days: 2 }), sendEmail('final-reminder', { template: 'last-chance' }), ], }, }), ],});Type-safe workflow definitions
All step helpers are fully typed. Your editor provides autocompletion for configuration options, trigger types, and operator values.
Triggers determine when a contact enters a workflow. Each workflow has exactly one trigger.
| Type | Description |
|---|---|
contact.created | When a new contact is added |
contact.updated | When contact fields change |
event.received | When a custom event is received |
segment.entered | When a contact enters a segment |
segment.exited | When a contact exits a segment |
manual | Manually triggered via API |
Wraps provides 11 step helpers to build your workflow logic. Each helper takes a unique step ID and a configuration object.
sendEmail(id, config)Send an email using a template.
Config: template, from?, fromName?
sendSms(id, config)Send an SMS message.
Config: template?, message?
delay(id, duration)Wait before continuing.
Config: { days?, hours?, minutes? }
condition(id, config)Branch based on a condition.
Config: field, operator, value, branches: { yes: [...], no: [...] }
waitForEvent(id, config)Pause until an event occurs.
Config: eventName, timeout?
waitForEmailEngagement(id, config)Wait for email open or click.
Config: emailStepId, engagementType ('opened' | 'clicked'), timeout?
exit(id, config?)End the workflow.
Config: reason?, markAs? ('completed' | 'cancelled')
updateContact(id, config)Modify contact fields.
Config: updates: [{ field, operation: 'set' | 'increment' | 'append', value }]
subscribeTopic(id, config)Subscribe contact to a topic.
Config: topicId, channel ('email' | 'sms')
unsubscribeTopic(id, config)Unsubscribe contact from a topic.
Config: topicId, channel ('email' | 'sms')
webhook(id, config)Call an external webhook.
Config: url, method? ('POST' default), headers?, body?
Before deploying, validate your workflow definitions to catch errors like missing templates, invalid step references, or circular dependencies. Then push to the Wraps Platform.
# Validate workflow definitionswraps email workflows validate# Push to Wraps Platformwraps email workflows pushValidation checks:
waitForEmailEngagement references a valid sendEmail stepThis workflow targets contacts who have been inactive for 30 days. It sends a win-back email, waits for engagement, and branches based on whether the contact opened it.
import { defineWorkflow, sendEmail, delay, condition, exit, waitForEmailEngagement,} from '@wraps.dev/client';export default defineWorkflow({ name: 'Re-engagement Campaign', trigger: { type: 'segment.entered', segmentId: 'inactive-30-days', }, steps: [ sendEmail('win-back', { template: 'we-miss-you' }), waitForEmailEngagement('check-opened', { emailStepId: 'win-back', engagementType: 'opened', timeout: { days: 3 }, }), condition('was-opened', { field: 'steps.check-opened.engaged', operator: 'equals', value: true, branches: { yes: [ sendEmail('special-offer', { template: 'comeback-offer' }), exit('re-engaged'), ], no: [ delay('wait-week', { days: 7 }), sendEmail('final-attempt', { template: 'last-chance' }), exit('campaign-complete'), ], }, }), ],});inactive-30-days segment, triggering the workflowWrite email templates as React components for use in workflows.
Template GuideFull reference for the Wraps client SDK and workflow API.
SDK Reference