Sequence steps
SEND_EMAIL and WAIT steps, delays, activation rules and DRAFT-only editing.
A sequence is built from ordered steps. There are only two step types, and you can only edit them while the sequence is in DRAFT.
Step types
stepType | What it does | Fields it uses |
|---|---|---|
SEND_EMAIL | Sends an email | templateVersionId (a PUBLISHED version), optional subject |
WAIT | Waits before the next step | delayMinutes (>= 1) |
Steps are ordered by position (integer >= 0).
Add a step
POST /sequences/{id}/steps
Authorization: Bearer <apiKey or accessToken>
X-Tenant-Id: {tenantId}
Content-Type: application/json
{
"stepType": "SEND_EMAIL",
"position": 0,
"templateVersionId": "ver_123"
}
| Field | Required | Notes |
|---|---|---|
stepType | Yes | SEND_EMAIL or WAIT |
position | No | Step order (integer >= 0) |
delayMinutes | WAIT only | Minutes to wait (>= 1) |
templateVersionId | SEND_EMAIL only | A template version in PUBLISHED state |
subject | No | Overrides the subject (up to 998 characters) |
A WAIT step of 1440 minutes waits a day before the next send:
{
"stepType": "WAIT",
"position": 1,
"delayMinutes": 1440
}
Step endpoints
| Method | Path | Scope | Description |
|---|---|---|---|
POST | /sequences/:id/steps | sequences:write | Add step (DRAFT only) |
PATCH | /sequences/:id/steps/:stepId | sequences:write | Edit step (DRAFT only) |
DELETE | /sequences/:id/steps/:stepId | sequences:write | Delete step (DRAFT only) |
Activation rules
Calling POST /sequences/:id/activate validates the step chain. It must have:
- At least one step.
- At least one
SEND_EMAILstep (a wait-only sequence sends nothing). - Never two consecutive
WAITsteps — merge the waits into a single step.
If the chain is invalid, activation fails and the sequence stays in DRAFT.
How delays run
The engine collapses the waits: when a send finishes it looks for the next SEND_EMAIL, sums the delayMinutes of the intervening WAIT steps and schedules a delayed BullMQ job (delayMs = delayMinutes * 60000). Each job is idempotent, with retries and exponential backoff, so a retry never duplicates a send. The email goes out through the normal pipeline — with suppressions and quota enforced, and per-contact locale routing.