Manage Contacts
Organize recipients, track conversations, and manage your audience with the Contacts API.
Create Contact
Add a new contact to your workspace.
Endpoint
POST /api/v1/contactsAuthentication
Requires JWT token via Authorization: Bearer header.
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Phone number in E.164 format |
email | string | No | Email address |
name | string | No | Contact name |
tags | array | No | Array of tag strings for organization |
custom_fields | object | No | Custom key-value pairs |
Example Requests
bash
curl -X POST https://api.yebolink.com/api/v1/contacts \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"phone": "+1234567890",
"email": "[email protected]",
"name": "John Doe",
"tags": ["customer", "vip"],
"custom_fields": {
"customer_id": "12345",
"signup_date": "2025-11-01"
}
}'javascript
const createContact = async (contactData) => {
const response = await fetch('https://api.yebolink.com/api/v1/contacts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${jwtToken}`
},
body: JSON.stringify(contactData)
});
return await response.json();
};
// Usage
const contact = await createContact({
phone: '+1234567890',
email: '[email protected]',
name: 'John Doe',
tags: ['customer', 'vip'],
custom_fields: {
customer_id: '12345',
signup_date: '2025-11-01'
}
});python
import requests
def create_contact(jwt_token: str, contact_data: dict):
response = requests.post(
'https://api.yebolink.com/api/v1/contacts',
headers={
'Authorization': f'Bearer {jwt_token}'
},
json=contact_data
)
return response.json()
# Usage
contact = create_contact(jwt_token, {
'phone': '+1234567890',
'email': '[email protected]',
'name': 'John Doe',
'tags': ['customer', 'vip'],
'custom_fields': {
'customer_id': '12345',
'signup_date': '2025-11-01'
}
})php
<?php
function createContact($jwtToken, $contactData) {
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'https://api.yebolink.com/api/v1/contacts',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
"Authorization: Bearer $jwtToken"
],
CURLOPT_POSTFIELDS => json_encode($contactData)
]);
$response = curl_exec($curl);
curl_close($curl);
return json_decode($response, true);
}
// Usage
$contact = createContact($jwtToken, [
'phone' => '+1234567890',
'email' => '[email protected]',
'name' => 'John Doe',
'tags' => ['customer', 'vip'],
'custom_fields' => [
'customer_id' => '12345',
'signup_date' => '2025-11-01'
]
]);
?>Response
json
{
"success": true,
"data": {
"contact": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"workspace_id": "workspace-id",
"phone": "+1234567890",
"email": "[email protected]",
"name": "John Doe",
"tags": ["customer", "vip"],
"custom_fields": {
"customer_id": "12345",
"signup_date": "2025-11-01"
},
"created_at": "2025-11-02T12:00:00Z",
"updated_at": "2025-11-02T12:00:00Z"
}
}
}List Contacts
Retrieve all contacts with optional filtering.
Endpoint
GET /api/v1/contactsQuery Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
search | string | No | Search by name, phone, or email |
tags | array | No | Filter by tags (comma-separated) |
page | number | No | Page number (default: 1) |
limit | number | No | Results per page (default: 50, max: 100) |
Example Requests
bash
# Get all contacts
curl "https://api.yebolink.com/api/v1/contacts" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
# Search contacts
curl "https://api.yebolink.com/api/v1/contacts?search=john" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
# Filter by tags
curl "https://api.yebolink.com/api/v1/contacts?tags=customer,vip" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"javascript
const listContacts = async (filters = {}) => {
const params = new URLSearchParams(filters);
const response = await fetch(
`https://api.yebolink.com/api/v1/contacts?${params}`,
{
headers: {
'Authorization': `Bearer ${jwtToken}`
}
}
);
return await response.json();
};
// Usage
const allContacts = await listContacts();
const vipContacts = await listContacts({ tags: 'vip' });
const searchResults = await listContacts({ search: 'john' });python
def list_contacts(jwt_token: str, filters: dict = None):
params = filters or {}
response = requests.get(
'https://api.yebolink.com/api/v1/contacts',
headers={'Authorization': f'Bearer {jwt_token}'},
params=params
)
return response.json()
# Usage
all_contacts = list_contacts(jwt_token)
vip_contacts = list_contacts(jwt_token, {'tags': 'vip'})Response
json
{
"success": true,
"data": {
"contacts": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"phone": "+1234567890",
"email": "[email protected]",
"name": "John Doe",
"tags": ["customer", "vip"],
"custom_fields": {
"customer_id": "12345"
},
"created_at": "2025-11-02T12:00:00Z",
"updated_at": "2025-11-02T12:00:00Z"
}
],
"pagination": {
"total": 150,
"page": 1,
"pages": 3,
"limit": 50
}
}
}Get Contact
Retrieve a specific contact by ID.
Endpoint
GET /api/v1/contacts/:idExample
bash
curl "https://api.yebolink.com/api/v1/contacts/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Update Contact
Update contact information.
Endpoint
PUT /api/v1/contacts/:idRequest Body
All fields are optional. Only provided fields will be updated.
Example
bash
curl -X PUT "https://api.yebolink.com/api/v1/contacts/550e8400-e29b-41d4-a716-446655440000" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"name": "John Smith",
"tags": ["customer", "vip", "premium"],
"custom_fields": {
"last_order": "2025-11-02"
}
}'javascript
const updateContact = async (contactId, updates) => {
const response = await fetch(
`https://api.yebolink.com/api/v1/contacts/${contactId}`,
{
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${jwtToken}`
},
body: JSON.stringify(updates)
}
);
return await response.json();
};
// Usage
await updateContact('550e8400-e29b-41d4-a716-446655440000', {
tags: ['customer', 'vip', 'premium'],
custom_fields: {
last_order: '2025-11-02'
}
});Delete Contact
Delete a contact permanently.
Endpoint
DELETE /api/v1/contacts/:idExample
bash
curl -X DELETE "https://api.yebolink.com/api/v1/contacts/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Response
json
{
"success": true,
"data": {
"message": "Contact deleted successfully"
}
}Use Cases
Import Contacts from CSV
javascript
const importContactsFromCSV = async (csvData) => {
const contacts = parseCSV(csvData); // Your CSV parser
for (const contact of contacts) {
try {
await createContact({
phone: contact.phone,
email: contact.email,
name: contact.name,
tags: ['imported'],
custom_fields: {
import_date: new Date().toISOString(),
source: 'csv_import'
}
});
} catch (error) {
console.error(`Failed to import ${contact.phone}:`, error);
}
}
};Segment Contacts by Tags
javascript
const getContactsBySegment = async (segment) => {
const response = await listContacts({ tags: segment });
return response.data.contacts;
};
// Get VIP customers
const vipCustomers = await getContactsBySegment('vip');
// Get recent signups
const newUsers = await getContactsBySegment('new_user');Sync Contacts with CRM
javascript
const syncWithCRM = async () => {
// Get all contacts from YeboLink
const yeboContacts = await listContacts({ limit: 100 });
for (const contact of yeboContacts.data.contacts) {
// Check if exists in CRM
const crmContact = await crm.findByPhone(contact.phone);
if (crmContact) {
// Update YeboLink with CRM data
await updateContact(contact.id, {
custom_fields: {
crm_id: crmContact.id,
last_sync: new Date().toISOString()
}
});
}
}
};Send to Tagged Contacts
javascript
const sendToSegment = async (tags, message) => {
const contacts = await listContacts({ tags });
const recipients = contacts.data.contacts.map(contact => ({
to: contact.phone,
name: contact.name,
...contact.custom_fields
}));
return await sendBulkSMS(message, recipients);
};
// Send promotion to VIP customers
await sendToSegment('vip', 'Hi {{name}}, exclusive VIP offer inside!');Best Practices
1. Use Tags for Organization
Organize contacts with meaningful tags:
javascript
const tags = {
lifecycle: ['lead', 'customer', 'churned'],
value: ['vip', 'premium', 'standard'],
engagement: ['active', 'inactive', 'bounced'],
source: ['website', 'referral', 'event']
};2. Store Important Data in Custom Fields
javascript
await createContact({
phone: '+1234567890',
name: 'John Doe',
custom_fields: {
customer_id: '12345',
lifetime_value: 5000,
last_purchase: '2025-11-01',
preferred_channel: 'sms',
timezone: 'America/New_York'
}
});3. Keep Contacts Up to Date
javascript
const updateContactAfterPurchase = async (contactId, orderData) => {
const contact = await getContact(contactId);
await updateContact(contactId, {
tags: [...contact.data.contact.tags, 'customer'],
custom_fields: {
...contact.data.contact.custom_fields,
last_order: orderData.id,
last_purchase: new Date().toISOString(),
total_orders: (contact.data.contact.custom_fields.total_orders || 0) + 1
}
});
};4. Handle Duplicates
javascript
const findOrCreateContact = async (phone, contactData) => {
// Search for existing contact
const existing = await listContacts({ search: phone });
if (existing.data.contacts.length > 0) {
// Update existing contact
return await updateContact(existing.data.contacts[0].id, contactData);
} else {
// Create new contact
return await createContact({ phone, ...contactData });
}
};Error Responses
Contact Not Found (404)
json
{
"success": false,
"error": "not_found",
"message": "Contact not found"
}Duplicate Phone Number (400)
json
{
"success": false,
"error": "validation_error",
"message": "Contact with this phone number already exists"
}Next Steps
- Send Bulk Messages - Message your contacts
- Setup Webhooks - Track message delivery
- API Reference - Complete API documentation