curl --request POST \
--url https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/{enrolment_id}/move/ \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"target_sequence_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
'import requests
url = "https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/{enrolment_id}/move/"
payload = { "target_sequence_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a" }
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({target_sequence_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a'})
};
fetch('https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/{enrolment_id}/move/', 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/{enrolment_id}/move/",
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([
'target_sequence_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/{enrolment_id}/move/"
payload := strings.NewReader("{\n \"target_sequence_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
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.getoneprofile.ai/sequences/{sequence_id}/contacts/{enrolment_id}/move/")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"target_sequence_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/{enrolment_id}/move/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"target_sequence_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}"
response = http.request(request)
puts response.read_body{
"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_reason": "<string>",
"held_by_sequence": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>"
},
"hold_reason": "window",
"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"
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>",
"issues": [
{
"input": "<string>",
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}Move one contact to another sequence
Move to another sequence, all or nothing: the contact leaves this sequence only when the target takes them. When the target cannot (no address it can use, the do-not-contact list, the recontact rule, already in it, a different audience table) the answer is a 422 whose message says why, and the contact stays here untouched. Returns the contact’s place in THIS sequence, now stopped.
curl --request POST \
--url https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/{enrolment_id}/move/ \
--header 'Content-Type: application/json' \
--header 'X-API-Key: <api-key>' \
--data '
{
"target_sequence_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
}
'import requests
url = "https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/{enrolment_id}/move/"
payload = { "target_sequence_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a" }
headers = {
"X-API-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-API-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({target_sequence_id: '3c90c3cc-0d44-4b50-8888-8dd25736052a'})
};
fetch('https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/{enrolment_id}/move/', 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/{enrolment_id}/move/",
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([
'target_sequence_id' => '3c90c3cc-0d44-4b50-8888-8dd25736052a'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"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"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/{enrolment_id}/move/"
payload := strings.NewReader("{\n \"target_sequence_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-API-Key", "<api-key>")
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.getoneprofile.ai/sequences/{sequence_id}/contacts/{enrolment_id}/move/")
.header("X-API-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"target_sequence_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/{enrolment_id}/move/")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-API-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"target_sequence_id\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\"\n}"
response = http.request(request)
puts response.read_body{
"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_reason": "<string>",
"held_by_sequence": {
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"name": "<string>"
},
"hold_reason": "window",
"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"
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>",
"issues": [
{
"input": "<string>",
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}{
"detail": "<string>"
}{
"detail": "<string>"
}{
"detail": "<string>"
}Authorizations
Body
Where Move to another sequence should put the contact.
The sequence to move the contact to. It must send to the same table.
Response
Successful Response
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 (SEQ-30) 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 per the
phase-1 ruling; 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 (F-25) 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, step_removed, removed, cooldown, rejected, mailbox_removed Their company, from whichever column of the audience row holds one.
The person's name from their audience row: a full-name column where filled, else the given and family names joined. Null when the table names nobody.
This contact's ordinal within the sequence, from 1. A label of last resort, for a contact with neither an address nor a LinkedIn profile.
Their job title, from whichever column of the audience row holds one.
For a contact on a condition that waits (Replied?, Bounced?, Accepted?): when the branch is decided. In the past on an acceptance, the window is over and the verdict waits for the sender's browser to look at the sent invitations again.
Why a failed contact stopped, in the words of its status cell: for a LinkedIn step, the browser's own reason. Retry runs the same step again. Null on every other status.
On a contact skipped because they are in another live sequence (status skipped_duplicate): that sequence of this workspace, by id and name. Null for every other status, and once nothing holds the contact, which is when the next sync takes them in.
Show child attributes
Show child attributes
Why the send path pushed this contact's next attempt out to due_at. Set only on an active contact whose due_at is still ahead. 'window' also covers a contact due on one of the sending window's openings, whoever scheduled them.
window, daily_cap, no_mailbox, pacing, agent_unavailable, no_message, agent_writing, mailbox_waiting, no_linkedin_account The touch a cooldown stop is measured from. Whoever made it is deliberately never named — it may be a colleague's sequence entirely.
When that step ran.
The step this contact last actually ran. Not the step before current_step_id: on a branching graph those are different steps.
Set beside waiting_on 'linkedin': where the contact's step stands in the sending account's line. 'running' is in a browser now; 'queued' is in line (see linkedin_steps_ahead and linkedin_starts_at); the rest say why the line is not moving for it: a daily or weekly limit for its kind, no browser checked in for fifteen minutes, LinkedIn asking to verify the account, or the account disconnected.
running, queued, daily_limit, weekly_limit, kind_disabled, browser_offline, verify_account, disconnected For a step held by a daily or weekly limit, when the limit it waits on resets (a UTC midnight). Null otherwise.
When the step is expected to start, simulated the way the account's governor hands steps out: the next gap is exact, later gaps are the account's time between steps widened by the average jitter, and a step held by a daily or weekly limit starts after that limit resets. Null where no time can be named.
For a queued step, how many of the account's steps run before it.
The address this contact is emailed from. A contact is only ever emailed from the mailbox that first emailed them, in any sequence. Null until something has emailed them.
Why that mailbox cannot send for this sequence, set while it is what stops the contact (stop_reason mailbox_removed: deleted, not_on_sequence) or holds them (hold_reason mailbox_waiting: disconnected, no_sender).
deleted, not_on_sequence, disconnected, no_sender Whether any channel this sequence's steps use can reach the contact: an email address for an email step, a LinkedIn profile URL for a LinkedIn one. A sequence with no sending step yet counts both.
Which address the contact lacks, set only while being unreachable is what holds them: the Contacts tab reads it as Unreachable, and the audience eligibility counts them under missing_contact_details. Null for a reachable contact and for one who is settled or held by something named first (do not contact, another sequence, a cooldown).
no_email, no_linkedin_url, no_email_or_linkedin_url What the approval queue holds this contact behind, read from the task for their current step: a person's approval, a LinkedIn browser, or an approved email the engine has not sent yet. Null when nothing does.
approval, linkedin, send Was this page helpful?