Skip to main content
Before you enroll contacts, create a preflight. A preflight checks whether the selected contacts are already in another sequence or have replied. It returns the available choices without changing any enrollments. You then confirm one of two actions: skip contacts that need a decision, or move them into this sequence. If you plan to move contacts, you can preview the result before confirming.
The direct enrollment endpoint is deprecated. Use preflight and confirmation for new integrations.

Prerequisites

Prepare these values before you start:
  • WORKSPACE_ID
  • SEQUENCE_ID for the sequence you want to enroll contacts into
  • SALESFORGE_API_KEY
  • the contact filters or contact IDs you want to use
Send the raw API key in the Authorization header:
For the shared authentication pattern, see Authentication.

Select contacts

You must provide at least one contact filter or set limit to a number greater than zero.
  • Contact IDs: leadIds, notInLeadIds
  • Tag IDs: tagIds, notInTagIds
  • Email service providers: esps, notInESPs
  • Custom variable values: customVars, notInCustomVars
  • Custom variable IDs: customVarIds, notInCustomVarIds
  • Contact search: searchQuery
  • Email validation: validationStatuses, validationRunId
  • Contact state: excludeContacted, hasValidLinkedIn, hasEmail
Use limit to set the maximum number of contacts the preflight checks.

Enrollment flow

1

Check the contacts

Create a preflight for the contacts you want to enroll.POST /multichannel/workspaces/{workspaceID}/sequences/{sequenceID}/enrollments/preflight
selectionScope controls which matching contacts are included:
  • all includes all matching contacts.
  • in_sequence includes contacts with at least one enrollment that could produce a preflight decision: any enrollment in a draft sequence, or an enrollment with status active, paused, out_of_office, failed, company_limit_reached, or replied.
  • not_in_sequence includes contacts without one of those decision-producing enrollments. A contact whose only enrollments are completed, dnc, unsubscribed, or bounced is included in this scope unless one of those enrollments belongs to a draft sequence.
If you omit selectionScope, it defaults to all.
A validationRunId must belong to the workspace, be completed, and contain at least one contact. If you also provide leadIds, the API keeps only contacts present in both selections.
2

Read the result

The response shows how many contacts can be enrolled and which contacts need a decision:
A contact may appear in more than one move group. For that reason, move-group contact counts may overlap.Save preflightId for the next request. The preflight expires at expiresAt, 15 minutes after creation.
3

Choose skip or move

Choose the action that matches what you want to do:
  • Skip enrolls contacts that do not need a decision. It leaves the other contacts in their current sequences.
  • Move enrolls eligible contacts in this sequence and updates their enrollment in the sequences you select.
To move contacts, select the relevant sequenceId values from moveGroups. If a contact appears in several required groups, select all of them. Otherwise, the API skips that contact.When a move is confirmed, a draft source enrollment is deleted. Any other selected source enrollment is set to completed, and its pending steps are canceled.
4

Preview a move

This step is optional. It shows the expected result without changing any enrollments.POST /multichannel/workspaces/{workspaceID}/sequences/{sequenceID}/enrollments/preflight/{preflightID}/move-preview
You must set skipReplied:
  • true does not enroll contacts that have replied.
  • false allows them to be enrolled if you selected all required sequences.
The response shows the expected outcome:
sourceCleanupCount is the number of contacts whose enrollment in another sequence will be updated. skipBreakdown shows whether contacts are skipped because they replied or because you did not select every required sequence.
5

Apply the decision

Confirm the preflight with skip or move.POST /multichannel/workspaces/{workspaceID}/sequences/{sequenceID}/enrollments/preflight/{preflightID}/confirm
skipReplied is required for move. It is not required for skip.A successful response contains the enrolled contact IDs and the final counts:
Preview returns expected counts. Confirmation returns the counts that were actually applied.
A contact suppressed elsewhere by do-not-contact, unsubscribe, or bounce shield is enrolled with that status and is never contacted. The response still includes the contact in enrolledLeadIds and enrolledCount, without a field that distinguishes it from a contactable enrollment. Do not treat enrolledCount as the number of contactable contacts.

If the preflight changes or expires

Contact enrollments can change after you create a preflight. If this happens, preview or confirmation returns 409 with message set to preflight_stale. The data field contains a new preflight:
Review the new result and use data.preflightId for the next preview or confirmation request. An expired preflight returns 404. Create another preflight with the same contact selection. A 422 response with insufficient remaining active credits balance means confirmation would exceed the account contact limit. A 423 response with enrollment_confirmation_busy means another enrollment is being confirmed; try again after it finishes.

If a validation run is not ready

When you use validationRunId, the run must be completed and contain at least one contact.