Skip to main content
POST
Add contacts to a sequence
Enrolls up to 500 people in one synchronous call. For more, start an enrollment run, which works through up to 5,000 in the background.

Identifying people

Give each prospect one of:
  • contact: the id of a contact already on your team.
  • email: matched against your team’s contacts; a new contact is created when there is no match.
  • linkedin_username: the handle, not a full URL. Matched and created the same way.
When the person already exists, the other fields you send (first_name, title, timezone and so on) only fill fields that are empty on the contact; they never overwrite. custom_fields are the exception: a value you send replaces the contact’s value for the same label, so {{custom.<label>}} merge fields render what you sent. phone_number is added only when the contact has no phone number at all.

Example

owner_id is who ends up holding the enrollments, so whose queue their tasks land in. It defaults to user_id.

Reading the response

A 200 does not mean everyone went in. Every response reports the whole outcome:
skipped[].reason currently carries the refusal message, as above, not a reason code, and rule on a skip is an object with id, name, action and reason. The schema below still shows a code and a string. For the code, read List enrollment refusals, where every skip is recorded.

Why someone is skipped

The whole request is refused with 422, and nobody is enrolled, when the sequence is archived, has no steps, or has throttle_paused set, or when owner_id is not on the team.

Timing

On an enabled sequence, each person’s first step is scheduled straight away: it comes due after the first step’s interval_seconds, inside the sending window. On a disabled sequence people wait as pending and start when it is enabled.

Retrying

Re-sending someone who is already in the sequence skips them as already enrolled rather than adding a duplicate, so a retry never enrolls anyone twice. Send an Idempotency-Key anyway: a retry with the same key returns the original response, including the original skipped list.

Authorizations

x-api-key
string
header
required

Team-scoped API key generated in the Salesfinity dashboard under Settings → Connections → API & Webhooks. A missing or invalid key returns HTTP 403.

Headers

Idempotency-Key
string

Makes this write safe to retry. Send a unique value, such as a UUID, and send the same value again when you retry the same request. A retry with the same key and the same request (method, path including the query string, and JSON body) returns the original successful response without acting twice. The same key with a different body or path returns 409, and so does a retry while the first request is still running; that one is safe to repeat after a moment. A request that fails frees its key, so a retry runs the write again: after a 5xx on a create, confirm with a GET before retrying. Keys are kept for 24 hours and are scoped to your team.

Path Parameters

id
string
required

24-character sequence id.

Body

application/json
user_id
string
required

The team member this call acts as. Must be an active member of the key's team with an active plan or seat. A 24-character hexadecimal ID.

Example:

"507f1f77bcf86cd799439011"

prospects
object[]
required

1 to 500 people. For more, start an enrollment run (POST /v2/sequencer/enrollment-runs).

Maximum array length: 500
owner_id
string

Who owns the resulting enrollments, and so whose queue their tasks land in. Defaults to user_id. Must be a member of the team; otherwise the whole request is refused with 422. A 24-character hexadecimal ID.

Response

The outcome for every person sent.

The outcome of adding people. A 200 does not mean everyone went in: read skipped.

enrolled
integer

How many people went in, including anyone listed in held.

skipped
object[]

Everyone refused, in the order sent. Each refusal is also recorded, with a reason code, on GET /v2/sequencer/sequences/{id}/enrollment-attempts.

held
object[]

People enrolled but held in pending until a manager approves them, because a rule requires approval. They are counted in enrolled.

warnings
object[]

People who went in although a rule matched them with a warning.

sequence_states
object[]

The enrollments created, in the same shape as GET /v2/sequencer/enrollments/{id}, except that contact is expanded to _id, first_name, last_name, email, linkedin_username, account, title and channel_stats. On an enabled sequence their state is active; on a disabled one, or when held, it is pending.