curl --request GET \
--url https://api.cloudtalk.io/v1/contacts \
--header 'Authorization: Basic <encoded-value>'import requests
url = "https://api.cloudtalk.io/v1/contacts"
headers = {"Authorization": "Basic <encoded-value>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Basic <encoded-value>'}};
fetch('https://api.cloudtalk.io/v1/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.cloudtalk.io/v1/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 => [
"Authorization: Basic <encoded-value>"
],
]);
$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.cloudtalk.io/v1/contacts"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Basic <encoded-value>")
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.cloudtalk.io/v1/contacts")
.header("Authorization", "Basic <encoded-value>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloudtalk.io/v1/contacts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Basic <encoded-value>'
response = http.request(request)
puts response.read_body{
"data": [
{
"id": "44210",
"type": "contact",
"name": "Jane Doe",
"title": "Head of Procurement",
"company": "Acme Inc.",
"industry": "Manufacturing",
"website": "https://acme.example.com",
"address": "1 Market Street",
"city": "San Francisco",
"state": "CA",
"zip": "94105",
"country": {
"code": "US",
"name": "United States"
},
"phones": [
"+12025550143",
"+13105550166"
],
"emails": [
"[email protected]"
],
"tags": [
{
"id": "123",
"name": "vip",
"readOnly": false
}
],
"customFields": {
"Segment": "enterprise"
},
"favoriteUserId": "7",
"source": "api",
"createdAt": "2026-08-17T09:34:21Z",
"updatedAt": "2026-10-02T14:05:11Z",
"dashboardUrl": "https://dashboard.cloudtalk.io/menu/contacts/details/44210"
}
],
"pagination": {
"limit": 20,
"next": "djE6NDQyMDk"
},
"requestId": "c9856b94-db55-402b-a6ba-adb130351158"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}{
"code": "UNAUTHORIZED",
"message": "You are not authorized to access this resource."
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}<string>{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}List and search contacts
Returns your contacts and leads one page at a time, with every number, email, tag and custom field on each row. Narrow the list with search, tagIds, type and updatedSince. For an exact phone or email match, use Look up contacts. To follow changes as they happen, subscribe to the contact.created, contact.updated and contact.deleted webhooks.
How search matches. Text fields (name, company, title, industry, website, address, city, state and zip) match by word prefix, and every word must match. Emails match by substring. Phone numbers are searched only when the query has no letters, and then match any number that contains its digits. Custom fields and notes are not searched. With search, tagIds matches plain tag links only.
Ordering. Without search, the newest contacts come first; with updatedSince (and no search), the most recently updated come first. With search, the best matches come first. The order stays stable while you page through one query. A filtered page can hold fewer than limit contacts while more pages follow.
Syncing with updatedSince. Send the time your previous run started. updatedAt moves on changes made through this API, the Dashboard contact form and CSV import. Dashboard bulk edits, CRM list sync, and renaming or deleting a contact tag do not move it, so contacts changed only that way are not returned.
curl --request GET \
--url https://api.cloudtalk.io/v1/contacts \
--header 'Authorization: Basic <encoded-value>'import requests
url = "https://api.cloudtalk.io/v1/contacts"
headers = {"Authorization": "Basic <encoded-value>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Basic <encoded-value>'}};
fetch('https://api.cloudtalk.io/v1/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.cloudtalk.io/v1/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 => [
"Authorization: Basic <encoded-value>"
],
]);
$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.cloudtalk.io/v1/contacts"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Basic <encoded-value>")
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.cloudtalk.io/v1/contacts")
.header("Authorization", "Basic <encoded-value>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.cloudtalk.io/v1/contacts")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Basic <encoded-value>'
response = http.request(request)
puts response.read_body{
"data": [
{
"id": "44210",
"type": "contact",
"name": "Jane Doe",
"title": "Head of Procurement",
"company": "Acme Inc.",
"industry": "Manufacturing",
"website": "https://acme.example.com",
"address": "1 Market Street",
"city": "San Francisco",
"state": "CA",
"zip": "94105",
"country": {
"code": "US",
"name": "United States"
},
"phones": [
"+12025550143",
"+13105550166"
],
"emails": [
"[email protected]"
],
"tags": [
{
"id": "123",
"name": "vip",
"readOnly": false
}
],
"customFields": {
"Segment": "enterprise"
},
"favoriteUserId": "7",
"source": "api",
"createdAt": "2026-08-17T09:34:21Z",
"updatedAt": "2026-10-02T14:05:11Z",
"dashboardUrl": "https://dashboard.cloudtalk.io/menu/contacts/details/44210"
}
],
"pagination": {
"limit": 20,
"next": "djE6NDQyMDk"
},
"requestId": "c9856b94-db55-402b-a6ba-adb130351158"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}{
"code": "UNAUTHORIZED",
"message": "You are not authorized to access this resource."
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}<string>{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}{
"error": {
"code": "<string>",
"message": "<string>",
"details": [
{
"code": "<string>",
"message": "<string>",
"target": "<string>"
}
],
"target": "<string>"
},
"requestId": "<string>"
}Authorizations
HTTP Basic Authentication. Use your API Access Key ID as the username and your API Access Key Secret as the password. Generate keys in the CloudTalk Dashboard under Account -> Settings -> API Keys (https://dashboard.cloudtalk.io/menu/account/settings/API-keys).
Query Parameters
Page size, 1 to 100. Out-of-range values are clamped and the value used is echoed in pagination.limit. A value that is not a whole number, such as abc or 1.5, is rejected with 400 VALIDATION.INVALID_PARAMETER.
20
Opaque cursor from a previous page's pagination.next. Pass it back unchanged. Send it with the same filters: a cursor from a list with updatedSince (ordered by update time) is rejected on a list without it, and the other way round. A cursor this API did not issue, or one sent with different filters, is rejected with 400 PAGINATION.INVALID_CURSOR.
Full-text search, 2 to 200 characters. See How search matches above.
2 - 200"acme"
1 to 20 comma-separated contact tag ids from List contact tags. A contact matches when it has any of them. Integration tag ids match nothing.
"123,131"
contact or lead. Default: both.
contact, lead RFC 3339 time. Only contacts whose updatedAt is at or after it. Without search, the list is then ordered by updatedAt, most recently updated first. A contact updated while you page moves to the top of that order, so the next run with a later updatedSince picks it up.
"2026-11-01T00:00:00Z"