Sequences
Enroll Audience
Enroll everyone, lists, or a segment in a sequence as a background run
POST
/
api
/
v1
/
sequences
/
{sequenceId}
/
enroll-audience
Enroll Audience
curl --request POST \
--url https://api.sequenzy.com/api/v1/sequences/{sequenceId}/enroll-audience \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"audience": {
"type": "<string>",
"listIds": [
"<string>"
],
"segmentId": "<string>",
"filters": [
{}
],
"include": [
{}
],
"exclude": [
{}
]
},
"targetNodeId": {},
"scheduledFor": {}
}
'import requests
url = "https://api.sequenzy.com/api/v1/sequences/{sequenceId}/enroll-audience"
payload = {
"audience": {
"type": "<string>",
"listIds": ["<string>"],
"segmentId": "<string>",
"filters": [{}],
"include": [{}],
"exclude": [{}]
},
"targetNodeId": {},
"scheduledFor": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
audience: {
type: '<string>',
listIds: ['<string>'],
segmentId: '<string>',
filters: [{}],
include: [{}],
exclude: [{}]
},
targetNodeId: {},
scheduledFor: {}
})
};
fetch('https://api.sequenzy.com/api/v1/sequences/{sequenceId}/enroll-audience', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sequenzy.com/api/v1/sequences/{sequenceId}/enroll-audience",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'audience' => [
'type' => '<string>',
'listIds' => [
'<string>'
],
'segmentId' => '<string>',
'filters' => [
[
]
],
'include' => [
[
]
],
'exclude' => [
[
]
]
],
'targetNodeId' => [
],
'scheduledFor' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.sequenzy.com/api/v1/sequences/{sequenceId}/enroll-audience"
payload := strings.NewReader("{\n \"audience\": {\n \"type\": \"<string>\",\n \"listIds\": [\n \"<string>\"\n ],\n \"segmentId\": \"<string>\",\n \"filters\": [\n {}\n ],\n \"include\": [\n {}\n ],\n \"exclude\": [\n {}\n ]\n },\n \"targetNodeId\": {},\n \"scheduledFor\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.sequenzy.com/api/v1/sequences/{sequenceId}/enroll-audience")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"audience\": {\n \"type\": \"<string>\",\n \"listIds\": [\n \"<string>\"\n ],\n \"segmentId\": \"<string>\",\n \"filters\": [\n {}\n ],\n \"include\": [\n {}\n ],\n \"exclude\": [\n {}\n ]\n },\n \"targetNodeId\": {},\n \"scheduledFor\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sequenzy.com/api/v1/sequences/{sequenceId}/enroll-audience")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"audience\": {\n \"type\": \"<string>\",\n \"listIds\": [\n \"<string>\"\n ],\n \"segmentId\": \"<string>\",\n \"filters\": [\n {}\n ],\n \"include\": [\n {}\n ],\n \"exclude\": [\n {}\n ]\n },\n \"targetNodeId\": {},\n \"scheduledFor\": {}\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"audienceEnrollment": {
"id": "aer_abc123",
"sequenceId": "seq_abc123",
"status": "queued",
"audience": { "type": "segment", "segmentId": "seg_past_buyers" },
"targetNodeId": "node_delay_1",
"estimatedCount": 11800,
"processedCount": 0,
"enrolledCount": 0,
"skippedCount": 0,
"source": "api",
"error": null,
"createdAt": "2026-11-01T10:00:00.000Z",
"scheduledFor": null,
"startedAt": null,
"completedAt": null,
"cancelRequestedAt": null
},
"message": "Enrolling about 11,800 contacts in the background. Poll GET /sequences/seq_abc123/audience-enrollments/aer_abc123 for progress."
}
{
"success": true,
"matchingCount": 12000,
"alreadyEnrolledCount": 200,
"enrollableCount": 11800
}
{
"error": "Activate the sequence before enrolling an audience."
}
{
"error": "The target step does not belong to this sequence"
}
{
"error": "Invalid API key"
}
{
"error": "Sequence not found"
}
{
"success": false,
"code": "run_in_progress",
"error": "An audience enrollment is already in progress for this sequence. Wait for it to finish or cancel it first."
}
Enroll a whole audience in a sequence. Unlike Enroll Subscribers, there is no 500-contact cap: Sequenzy starts a background run that walks the audience in batches and reports progress. This is how a manual-trigger countdown sequence, such as a Black Friday countdown, gets its audience: enable the sequence, then enroll the audience.
To keep enrolling people who join the audience after this run (new list
members, new segment matches) until the countdown ends, set
Estimate first:
- Only active contacts with an email address are enrolled. Unsubscribed and bounced contacts are never enrolled.
- Contacts already active or waiting in the sequence are skipped. Sequences with
enrollmentMode: "one_time"also skip contacts who completed or were cancelled before. - Late enrollees in a sequence with key-date waits skip the steps whose moment already passed and continue from the next wait (the step’s
pastAction). - Only one run per sequence can be queued or running at a time.
- The sequence must be enabled and accepting entrants.
POST /api/v1/sequences/{sequenceId}/enroll-audience/estimate with the same audience body to preview the counts without starting a run.
Request
string
required
Sequence ID.
object
required
Who to enroll. Same shape as campaign
targetLists.Show Audience shapes
Show Audience shapes
string
required
all, lists, segment, filtered, or rules.string[]
For
lists: members of any of these lists.string
For
segment: members of this saved segment.object[]
For
filtered: subscriber filters, with an optional filterJoinOperator of and or or.object[]
For
rules: include rules of type all, lists, segments, or filtered.object[]
For
rules: exclude rules of type lists, segments, or filtered.string | null
Step to start contacts at. Defaults to the first step after the trigger.
Cannot be a trigger node.
string | null
ISO 8601 date-time to start the run later, up to one year ahead. The run is
created with
status: "queued" and scheduledFor set, and can be cancelled
before it starts. A past value starts now.audienceAutoEnroll on the sequence with Update Sequence.
curl -X POST "https://api.sequenzy.com/api/v1/sequences/seq_abc123/enroll-audience" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"audience": {"type": "segment", "segmentId": "seg_past_buyers"}}'
curl -X POST "https://api.sequenzy.com/api/v1/sequences/seq_abc123/enroll-audience/estimate" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"audience": {"type": "all"}}'
Responses
{
"success": true,
"audienceEnrollment": {
"id": "aer_abc123",
"sequenceId": "seq_abc123",
"status": "queued",
"audience": { "type": "segment", "segmentId": "seg_past_buyers" },
"targetNodeId": "node_delay_1",
"estimatedCount": 11800,
"processedCount": 0,
"enrolledCount": 0,
"skippedCount": 0,
"source": "api",
"error": null,
"createdAt": "2026-11-01T10:00:00.000Z",
"scheduledFor": null,
"startedAt": null,
"completedAt": null,
"cancelRequestedAt": null
},
"message": "Enrolling about 11,800 contacts in the background. Poll GET /sequences/seq_abc123/audience-enrollments/aer_abc123 for progress."
}
{
"success": true,
"matchingCount": 12000,
"alreadyEnrolledCount": 200,
"enrollableCount": 11800
}
{
"error": "Activate the sequence before enrolling an audience."
}
{
"error": "The target step does not belong to this sequence"
}
{
"error": "Invalid API key"
}
{
"error": "Sequence not found"
}
{
"success": false,
"code": "run_in_progress",
"error": "An audience enrollment is already in progress for this sequence. Wait for it to finish or cancel it first."
}
Failure and retry semantics
The run is idempotent per contact: the cursor is committed together with every batch of enrollments, so a retried worker resumes where it stopped and never enrolls the same contact twice. If the run fails after retries, itsstatus becomes failed with an error, and the contacts enrolled before the failure stay in the sequence. Cancelling stops after the current batch and keeps everyone already enrolled.⌘I
Enroll Audience
curl --request POST \
--url https://api.sequenzy.com/api/v1/sequences/{sequenceId}/enroll-audience \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"audience": {
"type": "<string>",
"listIds": [
"<string>"
],
"segmentId": "<string>",
"filters": [
{}
],
"include": [
{}
],
"exclude": [
{}
]
},
"targetNodeId": {},
"scheduledFor": {}
}
'import requests
url = "https://api.sequenzy.com/api/v1/sequences/{sequenceId}/enroll-audience"
payload = {
"audience": {
"type": "<string>",
"listIds": ["<string>"],
"segmentId": "<string>",
"filters": [{}],
"include": [{}],
"exclude": [{}]
},
"targetNodeId": {},
"scheduledFor": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
audience: {
type: '<string>',
listIds: ['<string>'],
segmentId: '<string>',
filters: [{}],
include: [{}],
exclude: [{}]
},
targetNodeId: {},
scheduledFor: {}
})
};
fetch('https://api.sequenzy.com/api/v1/sequences/{sequenceId}/enroll-audience', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sequenzy.com/api/v1/sequences/{sequenceId}/enroll-audience",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'audience' => [
'type' => '<string>',
'listIds' => [
'<string>'
],
'segmentId' => '<string>',
'filters' => [
[
]
],
'include' => [
[
]
],
'exclude' => [
[
]
]
],
'targetNodeId' => [
],
'scheduledFor' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.sequenzy.com/api/v1/sequences/{sequenceId}/enroll-audience"
payload := strings.NewReader("{\n \"audience\": {\n \"type\": \"<string>\",\n \"listIds\": [\n \"<string>\"\n ],\n \"segmentId\": \"<string>\",\n \"filters\": [\n {}\n ],\n \"include\": [\n {}\n ],\n \"exclude\": [\n {}\n ]\n },\n \"targetNodeId\": {},\n \"scheduledFor\": {}\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.sequenzy.com/api/v1/sequences/{sequenceId}/enroll-audience")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"audience\": {\n \"type\": \"<string>\",\n \"listIds\": [\n \"<string>\"\n ],\n \"segmentId\": \"<string>\",\n \"filters\": [\n {}\n ],\n \"include\": [\n {}\n ],\n \"exclude\": [\n {}\n ]\n },\n \"targetNodeId\": {},\n \"scheduledFor\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sequenzy.com/api/v1/sequences/{sequenceId}/enroll-audience")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"audience\": {\n \"type\": \"<string>\",\n \"listIds\": [\n \"<string>\"\n ],\n \"segmentId\": \"<string>\",\n \"filters\": [\n {}\n ],\n \"include\": [\n {}\n ],\n \"exclude\": [\n {}\n ]\n },\n \"targetNodeId\": {},\n \"scheduledFor\": {}\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"audienceEnrollment": {
"id": "aer_abc123",
"sequenceId": "seq_abc123",
"status": "queued",
"audience": { "type": "segment", "segmentId": "seg_past_buyers" },
"targetNodeId": "node_delay_1",
"estimatedCount": 11800,
"processedCount": 0,
"enrolledCount": 0,
"skippedCount": 0,
"source": "api",
"error": null,
"createdAt": "2026-11-01T10:00:00.000Z",
"scheduledFor": null,
"startedAt": null,
"completedAt": null,
"cancelRequestedAt": null
},
"message": "Enrolling about 11,800 contacts in the background. Poll GET /sequences/seq_abc123/audience-enrollments/aer_abc123 for progress."
}
{
"success": true,
"matchingCount": 12000,
"alreadyEnrolledCount": 200,
"enrollableCount": 11800
}
{
"error": "Activate the sequence before enrolling an audience."
}
{
"error": "The target step does not belong to this sequence"
}
{
"error": "Invalid API key"
}
{
"error": "Sequence not found"
}
{
"success": false,
"code": "run_in_progress",
"error": "An audience enrollment is already in progress for this sequence. Wait for it to finish or cancel it first."
}