Contacts
List, create, read, update, and delete contacts via the API.
Contacts API
Manage contacts programmatically. All endpoints require an API token with the appropriate contacts.* ability.
List Contacts
GET /api/v1/contacts — Permission: contacts.view
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
search | string | No | Search by first name, last name, or email |
sort | string | No | Sort field (default: created_at) |
sort_dir | string | No | asc or desc (default: desc) |
filters | string | No | JSON-encoded advanced filter object |
per_page | integer | No | Results per page, 1–100 (default: 25) |
Example Request
curl -X GET "https://your-domain.com/api/v1/contacts?search=jane&per_page=10" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"const response = await fetch("https://your-domain.com/api/v1/contacts?search=jane&per_page=10", {
headers: {
"Authorization": "Bearer YOUR_API_TOKEN",
"Accept": "application/json"
}
});
const data = await response.json();$ch = curl_init('https://your-domain.com/api/v1/contacts?search=jane&per_page=10');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_TOKEN',
'Accept: application/json',
],
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);import requests
response = requests.get(
"https://your-domain.com/api/v1/contacts?search=jane&per_page=10",
headers={
"Authorization": "Bearer YOUR_API_TOKEN",
"Accept": "application/json"
}
)
data = response.json()Example Response
{
"data": [
{
"id": 1,
"first_name": "Jane",
"last_name": "Doe",
"email": "jane@example.com",
"phone": "+1 555-0100",
"custom_fields": {
"company": "Acme Corp",
"title": "CEO"
},
"tags": [
{ "id": 3, "name": "VIP", "slug": "vip", "color": "blue" }
],
"created_at": "2025-03-15T10:30:00.000000Z",
"updated_at": "2025-03-20T14:00:00.000000Z"
}
],
"meta": { "current_page": 1, "last_page": 1, "per_page": 10, "total": 1 },
"links": { "first": "...", "last": "...", "prev": null, "next": null }
}
Create Contact
POST /api/v1/contacts — Permission: contacts.create
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
first_name | string | Yes | Contact’s first name (max 255) |
last_name | string | No | Contact’s last name (max 255) |
email | string | No | Valid email address (max 255) |
phone | string | No | Phone number (max 50) |
custom_fields | object | No | Key-value pairs matching your custom field keys |
Example Request
curl -X POST "https://your-domain.com/api/v1/contacts" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"first_name": "Jane",
"last_name": "Doe",
"email": "jane@example.com",
"phone": "+1 555-0100",
"custom_fields": {
"company": "Acme Corp"
}
}'const response = await fetch("https://your-domain.com/api/v1/contacts", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_TOKEN",
"Accept": "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify({
first_name: "Jane",
last_name: "Doe",
email: "jane@example.com",
phone: "+1 555-0100",
custom_fields: {
company: "Acme Corp"
}
})
});
const data = await response.json();$ch = curl_init('https://your-domain.com/api/v1/contacts');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_TOKEN',
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'first_name' => 'Jane',
'last_name' => 'Doe',
'email' => 'jane@example.com',
'phone' => '+1 555-0100',
'custom_fields' => [
'company' => 'Acme Corp',
],
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);import requests
response = requests.post(
"https://your-domain.com/api/v1/contacts",
headers={
"Authorization": "Bearer YOUR_API_TOKEN",
"Accept": "application/json"
},
json={
"first_name": "Jane",
"last_name": "Doe",
"email": "jane@example.com",
"phone": "+1 555-0100",
"custom_fields": {
"company": "Acme Corp"
}
}
)
data = response.json()Example Response 201 Created
{
"data": {
"id": 42,
"first_name": "Jane",
"last_name": "Doe",
"email": "jane@example.com",
"phone": "+1 555-0100",
"custom_fields": { "company": "Acme Corp" },
"tags": [],
"created_at": "2025-03-20T14:00:00.000000Z",
"updated_at": "2025-03-20T14:00:00.000000Z"
}
}
Get Contact
GET /api/v1/contacts/{id} — Permission: contacts.view
Example Request
curl -X GET "https://your-domain.com/api/v1/contacts/42" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"const response = await fetch("https://your-domain.com/api/v1/contacts/42", {
headers: {
"Authorization": "Bearer YOUR_API_TOKEN",
"Accept": "application/json"
}
});
const data = await response.json();$ch = curl_init('https://your-domain.com/api/v1/contacts/42');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_TOKEN',
'Accept: application/json',
],
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);import requests
response = requests.get(
"https://your-domain.com/api/v1/contacts/42",
headers={
"Authorization": "Bearer YOUR_API_TOKEN",
"Accept": "application/json"
}
)
data = response.json()Returns the same shape as the create response.
Update Contact
PUT /api/v1/contacts/{id} — Permission: contacts.edit
Send only the fields you want to change. Set a field to null to clear it.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
first_name | string | Sometimes | Contact’s first name (max 255) |
last_name | string | No | Contact’s last name (max 255) |
email | string | No | Valid email address (max 255) |
phone | string | No | Phone number (max 50) |
custom_fields | object | No | Key-value pairs matching your custom field keys |
Example Request
curl -X PUT "https://your-domain.com/api/v1/contacts/42" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{
"phone": "+1 555-0200",
"custom_fields": { "company": "New Corp" }
}'const response = await fetch("https://your-domain.com/api/v1/contacts/42", {
method: "PUT",
headers: {
"Authorization": "Bearer YOUR_API_TOKEN",
"Accept": "application/json",
"Content-Type": "application/json"
},
body: JSON.stringify({
phone: "+1 555-0200",
custom_fields: { company: "New Corp" }
})
});
const data = await response.json();$ch = curl_init('https://your-domain.com/api/v1/contacts/42');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_TOKEN',
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'phone' => '+1 555-0200',
'custom_fields' => ['company' => 'New Corp'],
]),
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);import requests
response = requests.put(
"https://your-domain.com/api/v1/contacts/42",
headers={
"Authorization": "Bearer YOUR_API_TOKEN",
"Accept": "application/json"
},
json={
"phone": "+1 555-0200",
"custom_fields": {"company": "New Corp"}
}
)
data = response.json()Delete Contact
DELETE /api/v1/contacts/{id} — Permission: contacts.delete
Example Request
curl -X DELETE "https://your-domain.com/api/v1/contacts/42" \
-H "Authorization: Bearer YOUR_API_TOKEN" \
-H "Accept: application/json"const response = await fetch("https://your-domain.com/api/v1/contacts/42", {
method: "DELETE",
headers: {
"Authorization": "Bearer YOUR_API_TOKEN",
"Accept": "application/json"
}
});
// 204 No Content$ch = curl_init('https://your-domain.com/api/v1/contacts/42');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_TOKEN',
'Accept: application/json',
],
]);
$response = curl_exec($ch);
curl_close($ch);
// 204 No Contentimport requests
response = requests.delete(
"https://your-domain.com/api/v1/contacts/42",
headers={
"Authorization": "Bearer YOUR_API_TOKEN",
"Accept": "application/json"
}
)
# 204 No ContentReturns 204 No Content on success.
Was this article helpful?