Skip to content

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/contacts

Authentication

Requires JWT token via Authorization: Bearer header.

Request Body

ParameterTypeRequiredDescription
phonestringYesPhone number in E.164 format
emailstringNoEmail address
namestringNoContact name
tagsarrayNoArray of tag strings for organization
custom_fieldsobjectNoCustom 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": "john@example.com",
    "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: 'john@example.com',
  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': 'john@example.com',
    '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' => 'john@example.com',
    '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": "john@example.com",
      "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/contacts

Query Parameters

ParameterTypeRequiredDescription
searchstringNoSearch by name, phone, or email
tagsarrayNoFilter by tags (comma-separated)
pagenumberNoPage number (default: 1)
limitnumberNoResults 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": "john@example.com",
        "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/:id

Example

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/:id

Request 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/:id

Example

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

Built with VitePress