curl --request POST \
--url https://your-instance.example.com/api/contacts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"page": {
"New Lead": 1,
"Qualified": 1
},
"size": 25,
"search": "jane",
"ownerFilter": "my",
"pipelineType": "Contact",
"pipelineId": "64f0a1b2c3d4e5f6a7b8c9d1"
}
'import requests
url = "https://your-instance.example.com/api/contacts"
payload = {
"page": {
"New Lead": 1,
"Qualified": 1
},
"size": 25,
"search": "jane",
"ownerFilter": "my",
"pipelineType": "Contact",
"pipelineId": "64f0a1b2c3d4e5f6a7b8c9d1"
}
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({
page: {'New Lead': 1, Qualified: 1},
size: 25,
search: 'jane',
ownerFilter: 'my',
pipelineType: 'Contact',
pipelineId: '64f0a1b2c3d4e5f6a7b8c9d1'
})
};
fetch('https://your-instance.example.com/api/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://your-instance.example.com/api/contacts",
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([
'page' => [
'New Lead' => 1,
'Qualified' => 1
],
'size' => 25,
'search' => 'jane',
'ownerFilter' => 'my',
'pipelineType' => 'Contact',
'pipelineId' => '64f0a1b2c3d4e5f6a7b8c9d1'
]),
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://your-instance.example.com/api/contacts"
payload := strings.NewReader("{\n \"page\": {\n \"New Lead\": 1,\n \"Qualified\": 1\n },\n \"size\": 25,\n \"search\": \"jane\",\n \"ownerFilter\": \"my\",\n \"pipelineType\": \"Contact\",\n \"pipelineId\": \"64f0a1b2c3d4e5f6a7b8c9d1\"\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://your-instance.example.com/api/contacts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"page\": {\n \"New Lead\": 1,\n \"Qualified\": 1\n },\n \"size\": 25,\n \"search\": \"jane\",\n \"ownerFilter\": \"my\",\n \"pipelineType\": \"Contact\",\n \"pipelineId\": \"64f0a1b2c3d4e5f6a7b8c9d1\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://your-instance.example.com/api/contacts")
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 \"page\": {\n \"New Lead\": 1,\n \"Qualified\": 1\n },\n \"size\": 25,\n \"search\": \"jane\",\n \"ownerFilter\": \"my\",\n \"pipelineType\": \"Contact\",\n \"pipelineId\": \"64f0a1b2c3d4e5f6a7b8c9d1\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"New Lead": {
"contacts": [],
"total": 12
},
"Qualified": {
"contacts": [],
"total": 4
}
},
"stageIdByName": {
"New Lead": "64f0a1b2c3d4e5f6a7b8c9d2"
}
}{
"error": "Attachment not found",
"message": "Attachment not found"
}{
"error": "Attachment not found",
"message": "Attachment not found"
}List contacts by pipeline status buckets
Returns contacts grouped by pipeline status / stage, supporting per-bucket pagination via the page map. Used by the Kanban board to fetch each column. Honors the same ownership, search, and advanced filters as the flat list endpoint.
curl --request POST \
--url https://your-instance.example.com/api/contacts \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"page": {
"New Lead": 1,
"Qualified": 1
},
"size": 25,
"search": "jane",
"ownerFilter": "my",
"pipelineType": "Contact",
"pipelineId": "64f0a1b2c3d4e5f6a7b8c9d1"
}
'import requests
url = "https://your-instance.example.com/api/contacts"
payload = {
"page": {
"New Lead": 1,
"Qualified": 1
},
"size": 25,
"search": "jane",
"ownerFilter": "my",
"pipelineType": "Contact",
"pipelineId": "64f0a1b2c3d4e5f6a7b8c9d1"
}
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({
page: {'New Lead': 1, Qualified: 1},
size: 25,
search: 'jane',
ownerFilter: 'my',
pipelineType: 'Contact',
pipelineId: '64f0a1b2c3d4e5f6a7b8c9d1'
})
};
fetch('https://your-instance.example.com/api/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://your-instance.example.com/api/contacts",
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([
'page' => [
'New Lead' => 1,
'Qualified' => 1
],
'size' => 25,
'search' => 'jane',
'ownerFilter' => 'my',
'pipelineType' => 'Contact',
'pipelineId' => '64f0a1b2c3d4e5f6a7b8c9d1'
]),
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://your-instance.example.com/api/contacts"
payload := strings.NewReader("{\n \"page\": {\n \"New Lead\": 1,\n \"Qualified\": 1\n },\n \"size\": 25,\n \"search\": \"jane\",\n \"ownerFilter\": \"my\",\n \"pipelineType\": \"Contact\",\n \"pipelineId\": \"64f0a1b2c3d4e5f6a7b8c9d1\"\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://your-instance.example.com/api/contacts")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"page\": {\n \"New Lead\": 1,\n \"Qualified\": 1\n },\n \"size\": 25,\n \"search\": \"jane\",\n \"ownerFilter\": \"my\",\n \"pipelineType\": \"Contact\",\n \"pipelineId\": \"64f0a1b2c3d4e5f6a7b8c9d1\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://your-instance.example.com/api/contacts")
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 \"page\": {\n \"New Lead\": 1,\n \"Qualified\": 1\n },\n \"size\": 25,\n \"search\": \"jane\",\n \"ownerFilter\": \"my\",\n \"pipelineType\": \"Contact\",\n \"pipelineId\": \"64f0a1b2c3d4e5f6a7b8c9d1\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"New Lead": {
"contacts": [],
"total": 12
},
"Qualified": {
"contacts": [],
"total": 4
}
},
"stageIdByName": {
"New Lead": "64f0a1b2c3d4e5f6a7b8c9d2"
}
}{
"error": "Attachment not found",
"message": "Attachment not found"
}{
"error": "Attachment not found",
"message": "Attachment not found"
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
Per-stage page numbers keyed by stage id or stage name (e.g. { "New Lead": 2 }).
Show child attributes
Show child attributes
Page size applied to every stage query.
Case-insensitive substring match across first/last name, full name, and phone-number value.
Filter to contacts whose source equals this value (Contacts pipeline only).
Quick-tab owner scope: my, all, team, unassigned, or a specific user _id.
Specific-tab owner ids — matches contacts where any listed user is creator, owner, or assignee. Overrides ownerFilter.
Restrict to contacts whose conversations have any of these users as assignees.
Which model to query; defaults to Contact.
Contact, Application Specific pipeline _id to query; falls back to the org's active pipeline of pipelineType.
When set, restrict the result to this single stage (by name or id) instead of returning all stages.
Legacy { start, end } createdAt window; kept for backward compatibility — prefer createdDateRange.
{ start, end } ISO range filtering on createdAt.
Map of custom-field key to value; string values use case-insensitive regex match.
Client-provided stage names to avoid a pipeline lookup; ordering controls which stages get queried.
Optional stage-name to stage-id map enabling indexed pipelineStage queries instead of legacy status-name filters.
Show child attributes
Show child attributes
Restrict to contacts created via bulk import (isBulkSms: true).
Message engagement filter: all, answered (has any message), or unanswered.
{ value, unit } (hours/days) — returns contacts with NO messages within that recent window.
{ start, end } window — returns contacts whose messages fall within this absolute date range.