Skip to main content

Enroll sequence leads

Enroll lead IDs into a sequence. Work is queued asynchronously via bulk job.

POST/api/sequences/{sequence_id}/enroll
HTTP referenceScope sequences:runUpdated October 16, 2026

This page documents the canonical HTTP contract for this endpoint.

Async contract

This endpoint queues enrollment work and returns immediately when eligible leads exist. Poll GET /api/operation-runs/{operation_run_id} with the returned operationRunId or operation_run_id for canonical progress; developer keys need the additional jobs:read scope. The returned task_id identifies the native bulk job, whose status read is available for executor diagnostics. Admission does not prove completed enrollment or message delivery.

If preflight finds no eligible leads, the response is a successful status=noop. Without an idempotency key, task_id=null and no operation ID is returned. With idempotencyKey, the server persists a terminal no-op outcome and returns its task and canonical operation IDs for replay. Inspect skip reasons; poll only identities actually returned.

idempotencyKey makes a retry safe only when the enrollment input is unchanged. tableAudience is optional proof; when supplied, the backend validates its table, lead column, and fingerprint before admitting enrollment.

Native Command Center enrollment remains sensitive under Approve for me, including manual-only or reviewOnly enrollment. Activating a sequence automatically in that mode does not approve adding Leads. Combined launch-and-enroll actions also require approval. HTTP and CLI enrollment keep their existing explicit authenticated invocation and scope requirements.

Activation contract

  • Real enrollment requires the target sequence to already be ACTIVE.
  • reviewOnly=true stages paused enrollment records and skips sending side effects. It is a mutation, not a read-only preview, and also permits DRAFT or PAUSED sequences. Use the audience preview for read-only eligibility checks.
  • Table-driven add_to_sequence columns use the same activation and eligibility checks as direct enroll. The sequence's sourceTableId must match the table the column belongs to.

Assignee and sender routing

Find teammate IDs with GET /api/org/users (users:read). Find mailbox and LinkedIn account IDs with GET /api/sender-accounts (integrations:read). Copy exact returned IDs; never use current_user, a display name or email as an ID.

If assignedToUserId and assignmentPlan are omitted, ownership defaults to the resolved requesting actor. A developer-key request uses its owner as the default actor. With one assignee and no team plan, routing is single; round-robin requires an explicit team assignment plan. Existing sender selections can be pinned; inspect account defaults and access before overriding them.

  • Most enrollments only need assignedToUserId. When senderAccountIds and assignmentPlan are omitted, Autotouch uses that assignee's default connected email and LinkedIn sender accounts.
  • Use senderAccountIds only when one enrollment must be pinned to a specific email or LinkedIn sender account.
  • Use assignmentPlan plus routingMode=round_robin or weighted_round_robin when distributing leads across multiple owners or sender accounts.
  • Owners/admins manage defaults and delegation through /api/sender-accounts; ordinary "assign these leads to me" enrollments do not need sender-account management.

Lead-ID prerequisite

leadIds must contain existing CRM Lead IDs, not teammate IDs or a table's boolean In Leads flag. For Research Table rows without CRM identities, use Sync to Leads (the add_to_crm provider; research_table.sync_to_leads where that operation is exposed), then consume its Lead-ID result column. Preserve the requested audience; do not silently restrict it to rows already in CRM.

Conflict guard

Set skipActiveSequenceConflicts: true when the handoff should skip people already active in another sequence. This is recommended for table-driven or automated handoffs unless the user explicitly wants parallel enrollment.

Context behavior

  • When researchContext.fieldIds is present, those IDs are used as the selected context set.
  • When fieldIds is omitted, audience/draft context falls back to starred research columns.

Why favorites matter

  • Calling workflows use favorites to surface high-signal context quickly in sidecar views.
  • AI draft generation uses the selected/fallback context set, so importing both intent and full context improves output quality.

Mark a research column as a favorite by setting isImportant: true on POST /api/tables/{table_id}/columns or PATCH /api/tables/{table_id}/columns/{column_id}.

Path parameters

  • sequence_idrequired

    string

    Sequence ID.

Query parameters

  • actorUserId · optional

    string

    Optional actor override used as default assignee; an invalid explicit actor is rejected rather than replaced with the key owner.

Body parameters

  • leadIdsrequired

    array<string>

    Lead IDs to enroll.

  • assignedToUserId · optional

    string

    Assignee for generated sequence tasks. Easy path: set this and omit senderAccountIds/assignmentPlan so the assignee's default connected senders are used.

  • senderAccountIds · optional

    object

    Advanced sender pinning keyed by channel. Supported keys: email, linkedin. Omit for normal assignee-default routing.

  • senderAccountIds.email · optional

    string

    Advanced: explicit email sender account ID for this enrollment.

  • senderAccountIds.linkedin · optional

    string

    Advanced: explicit LinkedIn sender account ID for this enrollment.

  • assignmentPlan · optional

    array<object>

    Advanced/team routing plan. Use when distributing leads across multiple assignees or sender accounts.

  • assignmentPlan[].assigneeUserId · optional

    string

    User who should own tasks for this route.

  • assignmentPlan[].senderAccountIds · optional

    object

    Optional route-specific email/linkedin sender account IDs.

  • assignmentPlan[].weight · optional

    number

    Optional route weight when routingMode=weighted_round_robin.

  • routingMode · optional

    string

    Advanced routing mode for assignmentPlan: single, round_robin, or weighted_round_robin.

  • updateLeadOwner · optional

    boolean

    If true, update the Lead owner to the resolved assignee.

  • skipActiveSequenceConflicts · optional

    boolean

    Skip leads already active in another sequence. If omitted, the sequence enrollment rule is used.

  • reviewOnly · optional

    boolean

    Stage paused enrollment records with sending side effects skipped. This is a mutation; it permits DRAFT or PAUSED sequences as well as ACTIVE.

  • researchContext · optional

    object

    Optional research linkage metadata.

  • researchContext.sourceTableId · optional

    string

    Research table ID for live row linkage.

  • researchContext.fieldIds · optional

    array<string>

    Optional selected research field IDs (column IDs).

  • researchContext.sourceTableName · optional

    string

    Optional display name for the research table.

  • idempotencyKey · optional

    string

    Optional client key (8-200 characters) for retrying identical enrollment input. Reusing it with different input is rejected.

  • tableAudience · optional

    object

    Optional reviewed table audience proof. Contains sourceTableId, sourceLeadColumn, and a 64-character lowercase hexadecimal fingerprint; the backend rechecks it at admission.

  • tableAudience.sourceTableId · optional

    string

    Research table whose reviewed audience is being enrolled.

  • tableAudience.sourceLeadColumn · optional

    string

    Lead-ID result column used to resolve this audience.

  • tableAudience.fingerprint · optional

    string

    64-character lowercase hexadecimal fingerprint from the table audience readiness flow.

  • startDate · optional

    string (ISO datetime)

    Optional enrollment start time.

  • variableMap · optional

    object

    Optional sequence variable-to-table field mapping.

  • variableOverrides · optional

    object

    Optional per-lead variable overrides keyed by lead ID.

  • senderBindings · optional

    object

    Optional channel-keyed sender binding objects.

Errors

StatusMeaning
400Invalid payload or actor.
401Invalid API key or missing auth.
403Missing sequences:run scope.
409Idempotency conflict or sequence must be ACTIVE to enroll leads.
404Sequence not found.
503Enrollment could not be queued or provider/runtime admission is unavailable.

Docs