curl --request GET \
--url https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/ \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/', 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.getoneprofile.ai/sequences/{sequence_id}/contacts/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"enrolments": [
{
"bounced": true,
"company_key": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"current_step_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"due_at": "2023-11-07T05:31:56Z",
"email": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"record_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"replied_at": "2023-11-07T05:31:56Z",
"status": "pending",
"stop_reason": "reply",
"updated_at": "2023-11-07T05:31:56Z",
"contact_company": "<string>",
"contact_name": "<string>",
"contact_number": 0,
"contact_title": "<string>",
"decides_at": "2023-11-07T05:31:56Z",
"failure_code": "connected_before_withdraw",
"failure_reason": "<string>",
"held_by_sequence": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>"
},
"hold_reason": "window",
"invited_at": "2023-11-07T05:31:56Z",
"last_contacted_at": "2023-11-07T05:31:56Z",
"last_step_at": "2023-11-07T05:31:56Z",
"last_step_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"linkedin_queue": "running",
"linkedin_resets_at": "2023-11-07T05:31:56Z",
"linkedin_starts_at": "2023-11-07T05:31:56Z",
"linkedin_steps_ahead": 123,
"linkedin_url": "<string>",
"mailbox_address": "<string>",
"mailbox_issue": "deleted",
"reachable": true,
"unreachable_reason": "no_email",
"waiting_on": "approval"
}
],
"total": 123
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>",
"issues": [
{
"input": "<string>",
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}List a sequence's contacts
Newest-first unless sorted; each row names why it is where it is. ‘group’ lists one tab of the Audience tab (In progress, Needs approval, Paused, Done, Blocked), which get_audience_eligibility counts over the whole roster and count_sequence_contacts_per_group under the same filters. ‘status’ orders contacts the way the Status column reads them, first in line on top (on LinkedIn now, then everyone with a next move by when it happens, then Needs approval, then everyone done); ‘status_desc’ reverses it. Status, stop reason, search and the added-date range all filter server-side, so ‘total’ counts what the filter matched rather than the whole sequence.
curl --request GET \
--url https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/ \
--header 'X-API-Key: <api-key>'import requests
url = "https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/"
headers = {"X-API-Key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-Key': '<api-key>'}};
fetch('https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/', 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.getoneprofile.ai/sequences/{sequence_id}/contacts/",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-Key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/")
.header("X-API-Key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-Key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"enrolments": [
{
"bounced": true,
"company_key": "<string>",
"created_at": "2023-11-07T05:31:56Z",
"current_step_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"due_at": "2023-11-07T05:31:56Z",
"email": "<string>",
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"record_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"replied_at": "2023-11-07T05:31:56Z",
"status": "pending",
"stop_reason": "reply",
"updated_at": "2023-11-07T05:31:56Z",
"contact_company": "<string>",
"contact_name": "<string>",
"contact_number": 0,
"contact_title": "<string>",
"decides_at": "2023-11-07T05:31:56Z",
"failure_code": "connected_before_withdraw",
"failure_reason": "<string>",
"held_by_sequence": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>"
},
"hold_reason": "window",
"invited_at": "2023-11-07T05:31:56Z",
"last_contacted_at": "2023-11-07T05:31:56Z",
"last_step_at": "2023-11-07T05:31:56Z",
"last_step_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"linkedin_queue": "running",
"linkedin_resets_at": "2023-11-07T05:31:56Z",
"linkedin_starts_at": "2023-11-07T05:31:56Z",
"linkedin_steps_ahead": 123,
"linkedin_url": "<string>",
"mailbox_address": "<string>",
"mailbox_issue": "deleted",
"reachable": true,
"unreachable_reason": "no_email",
"waiting_on": "approval"
}
],
"total": 123
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>",
"issues": [
{
"input": "<string>",
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}Authorizations
Path Parameters
Query Parameters
Where one contact stands in one sequence.
ACTIVE rows carry a due_at and are what the tick claims; CLAIMED is the
in-flight guard between claim and outcome. PAUSED is a deliberate
per-contact hold: unclaimable because the tick claims strictly on ACTIVE,
yet still LIVE. It keeps its step and its one-live-sequence slot, and a
compliance stop (reply, unsubscribe) reaches it. Everything else is
settled: COMPLETED walked off the end; STOPPED was halted (reply,
unsubscribe, bounce, manual, company pause); FAILED is terminal;
SUPPRESSED was on the do-not-contact list;
SKIPPED_DUPLICATE lost the one-live-sequence-per-contact rule, with the
reason visible in the grid.
A contact the workspace's recontact rule refuses is STOPPED with
StopReason.COOLDOWN. There is deliberately no held state: a cooldown
settles a contact rather than parking them, so nothing here waits on a date
and nothing lets itself out later.
AWAITING_ACTION is a contact parked behind a task that needs a person or a channel, modelled on PAUSED: live, keeps its step and its one-live-sequence slot, unclaimable because the tick claims strictly on ACTIVE, and a compliance stop reaches it. Unlike PAUSED nobody wakes it by hand: only the outreach-task sweep does, once the task it waits on is decided or delivered. Deliberately not "awaiting approval": an AUTO-mode LinkedIn park is waiting for a browser rather than for anyone's approval, and this value is the word the Contacts tab shows for both.
PENDING is a draft's roster: in, standing on a step, and NOT live. Binding
an audience enrols on the spot so the Contacts tab can show who is in, but
a sequence nobody has launched must not hold anybody's one-live-sequence
slot, or a second sequence written for the same people skips them all.
uq_sequence_enrolment_one_live leaves PENDING out, the tick never
claims it, and launch turns each row ACTIVE, settling the ones another
sequence took meanwhile as SKIPPED_DUPLICATE.
pending, active, claimed, paused, awaiting_action, completed, stopped, failed, suppressed, skipped_duplicate Where one contact stands in one sequence.
ACTIVE rows carry a due_at and are what the tick claims; CLAIMED is the
in-flight guard between claim and outcome. PAUSED is a deliberate
per-contact hold: unclaimable because the tick claims strictly on ACTIVE,
yet still LIVE. It keeps its step and its one-live-sequence slot, and a
compliance stop (reply, unsubscribe) reaches it. Everything else is
settled: COMPLETED walked off the end; STOPPED was halted (reply,
unsubscribe, bounce, manual, company pause); FAILED is terminal;
SUPPRESSED was on the do-not-contact list;
SKIPPED_DUPLICATE lost the one-live-sequence-per-contact rule, with the
reason visible in the grid.
A contact the workspace's recontact rule refuses is STOPPED with
StopReason.COOLDOWN. There is deliberately no held state: a cooldown
settles a contact rather than parking them, so nothing here waits on a date
and nothing lets itself out later.
AWAITING_ACTION is a contact parked behind a task that needs a person or a channel, modelled on PAUSED: live, keeps its step and its one-live-sequence slot, unclaimable because the tick claims strictly on ACTIVE, and a compliance stop reaches it. Unlike PAUSED nobody wakes it by hand: only the outreach-task sweep does, once the task it waits on is decided or delivered. Deliberately not "awaiting approval": an AUTO-mode LinkedIn park is waiting for a browser rather than for anyone's approval, and this value is the word the Contacts tab shows for both.
PENDING is a draft's roster: in, standing on a step, and NOT live. Binding
an audience enrols on the spot so the Contacts tab can show who is in, but
a sequence nobody has launched must not hold anybody's one-live-sequence
slot, or a second sequence written for the same people skips them all.
uq_sequence_enrolment_one_live leaves PENDING out, the tick never
claims it, and launch turns each row ACTIVE, settling the ones another
sequence took meanwhile as SKIPPED_DUPLICATE.
pending, active, claimed, paused, awaiting_action, completed, stopped, failed, suppressed, skipped_duplicate reply, unsubscribe, bounce, manual, company_reply, row_left_audience, row_left_paused, step_removed, removed, cooldown, rejected, mailbox_removed 255Only the contacts under this tab of the Audience tab, as get_audience_eligibility's 'groups' counts them, or count_sequence_contacts_per_group's under the same filters. The Audience tab's tab a contact sits under; every contact is under one.
The tabs used to be counts that overlapped (a bounced contact was both "reachable" and "blocked", so the counts added up past the roster) and opened a list of names over the roster they repeated (Natsuki, 2026-10-02). They partition the roster now and filter it in place, so a tab's count is exactly the rows it shows, and each row's own status chip names the state that put it there.
Derived at read time from the status, the stop reason, the contact's current-step task and whether an address reaches them, never stored.
in_progress, needs_approval, paused, done, blocked The orders the Audience tab can list a sequence's contacts in.
created_desc, created_asc, status, status_desc, next_due 1 <= x <= 500x >= 0Was this page helpful?