OpenSequence
DocsAPI referenceSDKs and CLIReference
Enrollments

Lifecycle

The status machine, pause, resume, exit, bulk exit, and the re-enrollment rule.

Edit on GitHub
curl
curl -X POST $SEQ/v1/enrollments/enr_01J9…/pause  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" -d '{"reason":"on_hold","until":"2026-10-20T09:00:00Z"}'
curl -X POST $SEQ/v1/enrollments/enr_01J9…/resume -H "Authorization: Bearer $KEY"
curl -X POST $SEQ/v1/enrollments/enr_01J9…/exit   -H "Authorization: Bearer $ADMIN_KEY" -H "Content-Type: application/json" -d '{"label":"Deal closed by phone"}'
curl -X POST $SEQ/v1/enrollments:exit -H "Authorization: Bearer $ADMIN_KEY" -H "Content-Type: application/json" -d '{"sequence":"seq_01J9…","status":"active","label":"Retiring this sequence"}'

Statuses

                 ┌──────────── resume / paused_until ────────────┐
                 ▼                                               │
  enroll ──► active ──── pause, ooo reply, step_failed ────► paused
               │  ▲                                              
               │  └──── cap lifted ──── waiting_limit (over daily_limit)
               │
               ├──► completed   (an end node, an unwired transition, a task with no next step)
               ├──► exited      (reply or meeting per exit_on, opt-out, bounce, suppression, manual, deleted)
               └──► failed      (reserved)
StatusMeaningCounts as "in a sequence"
activerunning, or waiting on a timer or an eventyes
pausednothing happens until resumed; pause_reason says why (manual, ooo, step_failed), paused_until when it ends by itselfyes
waiting_limitthe next send is deferred by the sender's daily capyes
completedreached the endno
exitedended early; exit_reason says whyno
failedreserved; not produced today (a failed step pauses with step_failed instead)no

Pause and resume

POST /v1/enrollments/{id}/pause (scope enroll) takes an optional reason (up to 40 characters, default manual) and until. Pausing an already paused enrollment is a no-op; pausing a finished one is 409 NOT_ACTIVE. A step an executor is already running finishes; nothing more happens until resume. resume needs paused or waiting_limit (409 NOT_PAUSED) and makes the step that was due run on the next tick; a paused_until in the past resumes by itself.

The service pauses on its own in two cases: an out-of-office auto-reply (ooo, until the stated return date or 7 days) and a step that failed with no failed transition (step_failed, with run.failed and enrollment.paused delivered so you can look).

Exit

POST /v1/enrollments/{id}/exit (scope admin) ends the enrollment with exit_reason manual (or the reason you pass, up to 40 characters) and your label, closes the step it was waiting on, cancels its open task, and delivers enrollment.exited. Exiting a finished enrollment returns it unchanged.

POST /v1/enrollments:exit exits by selector: { "contact": "p_7" } exits the contact's active enrollment; { "sequence": "seq_…", "status": "active" } exits up to 200 enrollments of the sequence in that status (call again for more). PATCH /v1/sequences/{id} with status: "archived", exit_active: true does the same for a whole sequence.

Exit reasons

exit_reasonCause
replieda reply or a connected call, with reply in exit_on
meeting_bookeda calendar booking or a reported meeting, with meeting_booked in exit_on
opt_outSTOP, the opt-out link, or a reported opt-out
bounceda hard bounce or a complaint
suppresseda reported suppression (do not contact, left company, …)
manualan API exit, or a sequence archived with exit_active
deletedthe contact was erased

Re-enrollment

A contact who finished or exited a sequence can be enrolled in it again according to that version's settings.reenroll: never (default) skips them with already_enrolled_before, always allows it, after_<n>d allows it n days after the previous enrollment finished (reenroll_before_<n>d otherwise). The rule is checked at enrollment, per sequence, not per version. A contact can always be enrolled in a different sequence once the previous enrollment is no longer active.

Disabled senders

DELETE /v1/senders/{id} refuses new enrollments as that sender; enrollments already running keep going on the sender's channels as long as those channels are active. To stop them, exit by selector or remove the channels.

On this page