fc5624c7d57a

latestOpenAPI 3.1.0raw.githubusercontent.com2026-08-13260150938.9 KB
Sequences

Move sequence enrollments

Releases a bounded batch of contacts off one sequence step and onto another, keeping their existing enrollment, entry event properties, and stop-condition snapshots. Moved contacts become active on the target step immediately. Defaults to a dry run; each call is capped at 500 and is never drained automatically, so repeat the request while remainingCount is above zero. Works while new enrollment is paused, because the contacts are already enrolled.

post/sequences/{sequenceId}/enrollments/move

Path parameters

sequenceIdstring required

Sequence ID

Request body

fromNodeIdstring required

Node ID the contacts are currently sitting on, such as the delay step they are waiting at.

targetNodeIdstring

Node ID to move them onto. Defaults to the source step's only next step, and is required when that step branches or is terminal. Cannot be the trigger node.

limitnumber

Maximum enrollments to move in this call. Defaults to 100, maximum 500.

sort'wait_until_asc' | 'wait_until_desc' | 'enrolled_at_asc' | 'enrolled_at_desc'

Which enrollments to take first. Defaults to wait_until_asc, the contacts that have been waiting longest for their next step.

subscriberIdsstring[]

Optional narrowing filter. Only move these subscribers, up to 500.

dailyLimitnumber

Refuses to move more than this many enrollments onto targetNodeId in a rolling 24 hours, counting the moves recorded by earlier calls.

tagsstring[]

Existing tag names applied to the moved contacts. Requires the subscribers:tag scope. Applying them never enrolls contacts in tag_added sequences.

reasonstring

Note stored on every moved enrollment and returned as moveReason when listing enrollments.

dryRunboolean

When true (the default), reports which enrollments would move without moving them.

Example request

{
  "fromNodeId": "node_delay_2",
  "targetNodeId": "node_email_3",
  "limit": 180,
  "sort": "wait_until_asc",
  "subscriberIds": [
    "sub_abc123",
    "sub_def456"
  ],
  "dailyLimit": 500,
  "tags": [
    "wave-3-released"
  ],
  "reason": "Wave 3"
}

Response

Enrollments moved, or dry-run matches returned

successboolean
sequenceIdstring
dryRunboolean
fromNodeIdstring
targetNodeIdstring
sortstring
requestedLimitnumber
effectiveLimitnumber

How many this call was allowed to move after the daily guardrail was applied.

matchedCountnumber

Movable enrollments parked on fromNodeId when the request started.

movedCountnumber
remainingCountnumber

Movable enrollments still on fromNodeId. Repeat the same request while this is above zero.

skippedCountnumber

Enrollments excluded because they are active, a worker is mid-step on them, or they are parked awaiting double opt-in. Only safely parked waiting tokens can be moved.

dailyLimitnumber nullable
movedInWindownumber

Moves onto targetNodeId already recorded in the rolling 24-hour window.

dailyRemainingnumber nullable
enqueuedCountnumber

Moved enrollments handed to the worker queue. Zero while the sequence is not running.

tagResultobject nullable
hasMoreboolean
messagestring

Example response

{
  "success": true,
  "sequenceId": "seq_abc123",
  "fromNodeId": "node_delay_2",
  "targetNodeId": "node_email_3",
  "sort": "wait_until_asc",
  "requestedLimit": 180,
  "effectiveLimit": 180,
  "matchedCount": 4320,
  "movedCount": 180,
  "remainingCount": 4140,
  "dailyLimit": 500,
  "dailyRemaining": 320,
  "enqueuedCount": 180,
  "enqueueErrors": [
    {
      "tokenId": "tok_abc123",
      "error": "Redis connection lost"
    }
  ],
  "enrollments": [
    {
      "tokenId": "tok_abc123",
      "subscriberId": "sub_abc123",
      "subscriberEmail": "customer@example.com",
      "status": "waiting",
      "enrollmentKey": "__default__"
    }
  ],
  "hasMore": true,
  "message": "Moved 180 enrollments. 4140 still wait on the source step; repeat this request to release more."
}