Contacts
Create, search, update, and manage contact records
Contacts
Contacts represent the people who interact with your team. Every conversation is linked to a contact.
Base path: /api/v1/accounts/:account_id/contacts
List contacts
Returns a paginated list of all contacts.
GET /api/v1/accounts/:account_id/contactsQuery parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
page | number | No | Page number. Default: 1 (15 per page) |
sort | string | No | Sort by: name, email, phone_number, last_activity_at, created_at |
include_contact_inboxes | boolean | No | Include inbox associations in the response |
Response
{
"payload": [
{
"id": 10,
"name": "Jane Doe",
"email": "[email protected]",
"phone_number": "+1234567890",
"identifier": "user_123",
"blocked": false,
"thumbnail": "https://...",
"last_activity_at": 1712001000,
"created_at": 1711000000,
"custom_attributes": {}
}
],
"meta": {
"count": 200,
"current_page": 1
}
}const response = await fetch(
'https://app.usendoto.com/api/v1/accounts/1/contacts?page=1',
{
headers: { 'api_access_token': 'YOUR_TOKEN' },
}
);
const data = await response.json();
console.log(data.payload);import requests
response = requests.get(
'https://app.usendoto.com/api/v1/accounts/1/contacts',
headers={'api_access_token': 'YOUR_TOKEN'},
params={'page': 1},
)
print(response.json())<?php
$ch = curl_init('https://app.usendoto.com/api/v1/accounts/1/contacts?page=1');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['api_access_token: YOUR_TOKEN'],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);import 'package:http/http.dart' as http;
import 'dart:convert';
final response = await http.get(
Uri.parse('https://app.usendoto.com/api/v1/accounts/1/contacts?page=1'),
headers: {'api_access_token': 'YOUR_TOKEN'},
);
print(jsonDecode(response.body));require 'net/http'
require 'json'
uri = URI('https://app.usendoto.com/api/v1/accounts/1/contacts')
uri.query = URI.encode_www_form(page: 1)
req = Net::HTTP::Get.new(uri)
req['api_access_token'] = 'YOUR_TOKEN'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)Search contacts
Searches contacts by name, email, or phone number.
GET /api/v1/accounts/:account_id/contacts/searchQuery parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
q | string | Yes | Search query |
page | number | No | Page number |
include_contacts | boolean | No | Include full contact objects (default true) |
const response = await fetch(
'https://app.usendoto.com/api/v1/accounts/1/contacts/search?q=jane',
{
headers: { 'api_access_token': 'YOUR_TOKEN' },
}
);
const data = await response.json();
console.log(data.payload);response = requests.get(
'https://app.usendoto.com/api/v1/accounts/1/contacts/search',
headers={'api_access_token': 'YOUR_TOKEN'},
params={'q': 'jane'},
)
print(response.json())<?php
$ch = curl_init('https://app.usendoto.com/api/v1/accounts/1/contacts/search?q=jane');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['api_access_token: YOUR_TOKEN'],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);final uri = Uri.parse('https://app.usendoto.com/api/v1/accounts/1/contacts/search')
.replace(queryParameters: {'q': 'jane'});
final response = await http.get(
uri,
headers: {'api_access_token': 'YOUR_TOKEN'},
);
print(jsonDecode(response.body));uri = URI('https://app.usendoto.com/api/v1/accounts/1/contacts/search')
uri.query = URI.encode_www_form(q: 'jane')
req = Net::HTTP::Get.new(uri)
req['api_access_token'] = 'YOUR_TOKEN'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)Get a contact
Returns a single contact by ID.
GET /api/v1/accounts/:account_id/contacts/:idconst response = await fetch(
'https://app.usendoto.com/api/v1/accounts/1/contacts/10',
{
headers: { 'api_access_token': 'YOUR_TOKEN' },
}
);
const contact = await response.json();
console.log(contact);response = requests.get(
'https://app.usendoto.com/api/v1/accounts/1/contacts/10',
headers={'api_access_token': 'YOUR_TOKEN'},
)
print(response.json())<?php
$ch = curl_init('https://app.usendoto.com/api/v1/accounts/1/contacts/10');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['api_access_token: YOUR_TOKEN'],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);final response = await http.get(
Uri.parse('https://app.usendoto.com/api/v1/accounts/1/contacts/10'),
headers: {'api_access_token': 'YOUR_TOKEN'},
);
print(jsonDecode(response.body));uri = URI('https://app.usendoto.com/api/v1/accounts/1/contacts/10')
req = Net::HTTP::Get.new(uri)
req['api_access_token'] = 'YOUR_TOKEN'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)Create a contact
Creates a new contact.
POST /api/v1/accounts/:account_id/contactsBody parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Full name of the contact |
email | string | No | Email address |
phone_number | string | No | Phone number in E.164 format (e.g. +1234567890) |
identifier | string | No | Your own unique identifier for this contact |
blocked | boolean | No | Whether the contact is blocked |
custom_attributes | object | No | Key-value pairs of custom attribute values |
additional_attributes | object | No | Extra metadata |
const response = await fetch(
'https://app.usendoto.com/api/v1/accounts/1/contacts',
{
method: 'POST',
headers: {
'api_access_token': 'YOUR_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Jane Doe',
email: '[email protected]',
phone_number: '+1234567890',
identifier: 'user_123',
custom_attributes: { plan: 'premium' },
}),
}
);
const contact = await response.json();
console.log(contact);response = requests.post(
'https://app.usendoto.com/api/v1/accounts/1/contacts',
headers={'api_access_token': 'YOUR_TOKEN'},
json={
'name': 'Jane Doe',
'email': '[email protected]',
'phone_number': '+1234567890',
'identifier': 'user_123',
'custom_attributes': {'plan': 'premium'},
},
)
print(response.json())<?php
$payload = json_encode([
'name' => 'Jane Doe',
'email' => '[email protected]',
'phone_number' => '+1234567890',
'identifier' => 'user_123',
'custom_attributes' => ['plan' => 'premium'],
]);
$ch = curl_init('https://app.usendoto.com/api/v1/accounts/1/contacts');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'api_access_token: YOUR_TOKEN',
'Content-Type: application/json',
],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);final response = await http.post(
Uri.parse('https://app.usendoto.com/api/v1/accounts/1/contacts'),
headers: {
'api_access_token': 'YOUR_TOKEN',
'Content-Type': 'application/json',
},
body: jsonEncode({
'name': 'Jane Doe',
'email': '[email protected]',
'phone_number': '+1234567890',
'identifier': 'user_123',
'custom_attributes': {'plan': 'premium'},
}),
);
print(jsonDecode(response.body));uri = URI('https://app.usendoto.com/api/v1/accounts/1/contacts')
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
req['api_access_token'] = 'YOUR_TOKEN'
req.body = JSON.dump(
name: 'Jane Doe',
email: '[email protected]',
phone_number: '+1234567890',
identifier: 'user_123',
custom_attributes: { plan: 'premium' }
)
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)Update a contact
Updates an existing contact's details.
PATCH /api/v1/accounts/:account_id/contacts/:idBody parameters
Same as create — include only the fields you want to update.
const response = await fetch(
'https://app.usendoto.com/api/v1/accounts/1/contacts/10',
{
method: 'PATCH',
headers: {
'api_access_token': 'YOUR_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Jane Smith',
custom_attributes: { plan: 'enterprise' },
}),
}
);
const updated = await response.json();
console.log(updated);response = requests.patch(
'https://app.usendoto.com/api/v1/accounts/1/contacts/10',
headers={'api_access_token': 'YOUR_TOKEN'},
json={
'name': 'Jane Smith',
'custom_attributes': {'plan': 'enterprise'},
},
)
print(response.json())<?php
$ch = curl_init('https://app.usendoto.com/api/v1/accounts/1/contacts/10');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_POSTFIELDS => json_encode([
'name' => 'Jane Smith',
'custom_attributes' => ['plan' => 'enterprise'],
]),
CURLOPT_HTTPHEADER => [
'api_access_token: YOUR_TOKEN',
'Content-Type: application/json',
],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);final response = await http.patch(
Uri.parse('https://app.usendoto.com/api/v1/accounts/1/contacts/10'),
headers: {
'api_access_token': 'YOUR_TOKEN',
'Content-Type': 'application/json',
},
body: jsonEncode({
'name': 'Jane Smith',
'custom_attributes': {'plan': 'enterprise'},
}),
);
print(jsonDecode(response.body));uri = URI('https://app.usendoto.com/api/v1/accounts/1/contacts/10')
req = Net::HTTP::Patch.new(uri, 'Content-Type' => 'application/json')
req['api_access_token'] = 'YOUR_TOKEN'
req.body = JSON.dump(
name: 'Jane Smith',
custom_attributes: { plan: 'enterprise' }
)
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)Delete a contact
Permanently deletes a contact and all their associated data.
DELETE /api/v1/accounts/:account_id/contacts/:idconst response = await fetch(
'https://app.usendoto.com/api/v1/accounts/1/contacts/10',
{
method: 'DELETE',
headers: { 'api_access_token': 'YOUR_TOKEN' },
}
);
console.log(response.status); // 200response = requests.delete(
'https://app.usendoto.com/api/v1/accounts/1/contacts/10',
headers={'api_access_token': 'YOUR_TOKEN'},
)
print(response.status_code) # 200<?php
$ch = curl_init('https://app.usendoto.com/api/v1/accounts/1/contacts/10');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'DELETE',
CURLOPT_HTTPHEADER => ['api_access_token: YOUR_TOKEN'],
]);
curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);final response = await http.delete(
Uri.parse('https://app.usendoto.com/api/v1/accounts/1/contacts/10'),
headers: {'api_access_token': 'YOUR_TOKEN'},
);
print(response.statusCode); // 200uri = URI('https://app.usendoto.com/api/v1/accounts/1/contacts/10')
req = Net::HTTP::Delete.new(uri)
req['api_access_token'] = 'YOUR_TOKEN'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts res.code # 200Get contact conversations
Returns all conversations for a specific contact.
GET /api/v1/accounts/:account_id/contacts/:id/conversationsconst response = await fetch(
'https://app.usendoto.com/api/v1/accounts/1/contacts/10/conversations',
{
headers: { 'api_access_token': 'YOUR_TOKEN' },
}
);
const data = await response.json();
console.log(data.payload);response = requests.get(
'https://app.usendoto.com/api/v1/accounts/1/contacts/10/conversations',
headers={'api_access_token': 'YOUR_TOKEN'},
)
print(response.json())<?php
$ch = curl_init('https://app.usendoto.com/api/v1/accounts/1/contacts/10/conversations');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['api_access_token: YOUR_TOKEN'],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);final response = await http.get(
Uri.parse('https://app.usendoto.com/api/v1/accounts/1/contacts/10/conversations'),
headers: {'api_access_token': 'YOUR_TOKEN'},
);
print(jsonDecode(response.body));uri = URI('https://app.usendoto.com/api/v1/accounts/1/contacts/10/conversations')
req = Net::HTTP::Get.new(uri)
req['api_access_token'] = 'YOUR_TOKEN'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)Add a note to a contact
Adds an internal note to a contact's profile.
POST /api/v1/accounts/:account_id/contacts/:id/notesBody parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
content | string | Yes | The note text |
const response = await fetch(
'https://app.usendoto.com/api/v1/accounts/1/contacts/10/notes',
{
method: 'POST',
headers: {
'api_access_token': 'YOUR_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({ content: 'Customer is on enterprise plan, handle with priority.' }),
}
);
const note = await response.json();
console.log(note);response = requests.post(
'https://app.usendoto.com/api/v1/accounts/1/contacts/10/notes',
headers={'api_access_token': 'YOUR_TOKEN'},
json={'content': 'Customer is on enterprise plan, handle with priority.'},
)
print(response.json())<?php
$ch = curl_init('https://app.usendoto.com/api/v1/accounts/1/contacts/10/notes');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(['content' => 'Customer is on enterprise plan, handle with priority.']),
CURLOPT_HTTPHEADER => [
'api_access_token: YOUR_TOKEN',
'Content-Type: application/json',
],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);final response = await http.post(
Uri.parse('https://app.usendoto.com/api/v1/accounts/1/contacts/10/notes'),
headers: {
'api_access_token': 'YOUR_TOKEN',
'Content-Type': 'application/json',
},
body: jsonEncode({'content': 'Customer is on enterprise plan, handle with priority.'}),
);
print(jsonDecode(response.body));uri = URI('https://app.usendoto.com/api/v1/accounts/1/contacts/10/notes')
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
req['api_access_token'] = 'YOUR_TOKEN'
req.body = JSON.dump(content: 'Customer is on enterprise plan, handle with priority.')
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)