Contact API 3.0
The WebFones Contacts API allows for managing contacts and groups with full CRUD operations. It supports search by mobile, name, email, batch queries, and change versioning.
Since most companies use external CRM or software specific to their business, we have designed the API to make it easy to reliably synchronize and integrate the WebFones contact list with other information sources. This includes being able to use an “external ID” or external key for data records so your external software can reliably execute updates to specific records and the utilization of record version numbers which allows external software to pull in records that have been updated directly on WebFones.
General API Description
WebFones uses JSON to communicate back forth between your applications and the WebFones databases. We designed it to use a single API token which you can get from the top of the Contact Preferences page in the admin interface. This allows you to interact with your company-specific data and initiate phone calls through your software.
All the APIs uses an API Key that is specific to your account. The API Key can be found on the top of the API Preferences page on the website.
Contact Versioning
Since the WebFones contact system is designed to be use alongside a CRM or company specific software, it has a versioning system which allows an integrator to fetch only records that have changed since the last fetch. This is done through a version number.
When you select a set of contact records, one of the pieces of information you get back is a version number. This should be stored so that you can later fetch any changes made to those contract records.
For instance, let’s say you select a set of 10 records and you store a version number of 2. In the mean time, users may use their mobile devices to populate customer information, like adding an additional mobile number or an email address. Each time an update is made, those records get a version greater than 2 (such as 3, 4 or 5).
Later, when your company information system wants to synchronize those changes, they just have to select those contact records again with a version of 2 indicating that you want any records that have been updated since the last time records were fetched. This will constrain the fetch to only the updated records.
Updated WebFones Contact API Documentation
Version 3.0.0
Base URL
https://api.webfones.com:2343
Authentication
All API endpoints require authentication using an API key. The API key must be included in the request headers.
Required Headers
http
x-api-key: YOUR_API_KEY
Alternative:
http
Authorization: Bearer YOUR_API_KEY
Rate Limiting
- Limit: 1000 requests per 15-minute window per IP address
- Response Code: 429 when limit exceeded
Quick Start
Example Request
bash
curl -X GET "https://api.webfones.com:2343/contacts/contacts" \
-H "x-api-key: YOUR_API_KEY"
Example Response
json
[
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"firstname": "John",
"lastname": "Doe",
"mobile_phone": "5559999",
"email": "john@example.com"
}
]
Endpoints
System
Check API Health
http
GET /health
Check if the API gateway is running.
Authentication: Not required
Response
json
{
"status": "healthy",
"timestamp": "2025-06-19T10:30:00.000Z",
"services": ["contacts", "sms", "call_logs"]
}
Check Service Status
http
GET /status
Check the status of all backend services.
Authentication: Required
Response
json
{
"status": "ok",
"timestamp": "2025-06-19T10:30:00.000Z",
"services": {
"contacts": {
"status": "online",
"endpoint": "control.webfones.net:4044/api"
}
}
}
Contacts
List All Contacts
http
GET /contacts/contacts
Retrieve all contacts for the authenticated account.
Response
json
[
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"firstname": "John",
"lastname": "Doe",
"organization": "Acme Corp",
"organization_flag": true,
"user_id": 1,
"phone_numbers": ["555-1234", "555-5678"],
"mobile_phone": "555-9999",
"email": "john@example.com",
"address": "123 Main St",
"city": "Anytown",
"state": "CA",
"zip": "12345",
"country": "USA",
"note": "Important client",
"version": 1,
"profile_url": "https://example.com/profile.jpg",
"external_id": "ext_123",
"groups": ["group-uuid-1", "group-uuid-2"]
}
]
Get Contact
http
GET /contacts/contacts/
Retrieve a specific contact by UUID.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| —————- | ——— | ——————- |
contactId | string | UUID of the contact |
json
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"firstname": "John",
"lastname": "Doe",
"organization": "Acme Corp",
"organization_flag": true,
"user_id": 1,
"phone_numbers": ["555-1234", "555-5678"],
"mobile_phone": "555-9999",
"email": "john@example.com",
"address": "123 Main St",
"city": "Anytown",
"state": "CA",
"zip": "12345",
"country": "USA",
"note": "Important client",
"version": 1,
"profile_url": "https://example.com/profile.jpg",
"external_id": "ext_123",
"groups": [
{
"uuid": "group-uuid-1",
"name": "VIP Clients"
}
]
}
Create Contact
http
POST /contacts/contacts
Create a new contact.
Request Body
json
{
"firstname": "Jane",
"lastname": "Smith",
"organization": "Tech Corp",
"organization_flag": false,
"user_id": 1,
"phone_numbers": ["555-1111", "555-2222"],
"mobile_phone": "555-3333",
"email": "jane@techcorp.com",
"address": "456 Oak Ave",
"city": "Somewhere",
"state": "NY",
"zip": "67890",
"country": "USA",
"note": "New prospect",
"profile_url": "https://example.com/jane.jpg",
"external_id": "ext_456",
"groups": ["group-uuid-1"]
}
Response
json
{
"uuid": "456e7890-e89b-12d3-a456-426614174002"
}
Update Contact
http
PUT /contacts/contacts/
Update an existing contact.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| —————- | ——— | ——————- |
contactId | string | UUID of the contact to update |
Same structure as Create Contact.
Response
json
{
"message": "Contact updated successfully."
}
Delete Contact
http
DELETE /contacts/contacts/
Delete a contact.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| —————- | ——— | ——————- |
contactId | string | UUID of the contact to delete |
json
{
"success": true
}
Search
Search by Mobile Phone
http
POST /contacts/contacts/search/mobile
Search for a contact by exact mobile phone number.
Request Body
json
{
"mobile_phone": "5559999"
}
Response
json
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"firstname": "John",
"lastname": "Doe",
"mobile_phone": "5559999",
"email": "john@example.com"
}
Search by Mobile Phone (Partial)
http
POST /contacts/contacts/search/mobile/like
Search for contacts with mobile phone numbers containing the search term.
Request Body
json
{
"mobile_phone": "555"
}
Response
json
[
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"firstname": "John",
"lastname": "Doe",
"mobile_phone": "5559999"
}
]
Search by Name
http
POST /contacts/contacts/search/name
Search for contacts by first name, last name, or both.
Request Body
json
{
"searchString": "John Doe"
}
Response
json
[
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"firstname": "John",
"lastname": "Doe",
"hint_data": "firstname"
}
]
Search by Email
http
POST /contacts/contacts/search/email
Search for a contact by email address.
Request Body
json
{
"email_address": "john@example.com"
}
Response
json
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"firstname": "John",
"lastname": "Doe",
"email": "john@example.com"
}
Batch Search by Mobile Phones
http
POST /contacts/contacts/search/mobile/batch
Search for multiple contacts by an array of mobile phone numbers.
Request Body
json
{
"mobile_phones": ["5559999", "5551234", "5555678"]
}
Response
json
[
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"firstname": "John",
"lastname": "Doe",
"mobile_phone": "5559999",
"api_key": "your_api_key"
}
]
Search by Phone Numbers
http
POST /contacts/contacts/search/phones
Search for contacts by multiple phone numbers (includes mobile_phone and phone_numbers JSON field).
Request Body
json
{
"phone_numbers": ["5559999", "5551234"]
}
Response
json
{
"5559999": [
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"firstname": "John",
"lastname": "Doe",
"mobile_phone": "5559999"
}
],
"5551234": []
}
Search by Phone (Exact)
http
POST /contacts/contacts/search/phone/exact
Search for contacts by exact phone number match in the phone_numbers JSON field.
Request Body
json
{
"phone_number": "5551234"
}
Response
json
[
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"firstname": "John",
"lastname": "Doe",
"phone_numbers": ["5551234", "5555678"]
}
]
Advanced Search
http
POST /contacts/contacts/search
Advanced search across multiple fields with optional filters.
Request Body
json
{
"searchString": "John",
"letter": "d",
"groupUUID": "group-uuid-1"
}
Request Body Parameters
| Parameter | Type | Description |
|---|---|---|
| —————- | ——— | ——————- |
searchString | string | Text to search across name, organization, and other fields |
letter | string | Filter by first letter of last name |
groupUUID | string | Filter by group membership |
json
[
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"firstname": "John",
"lastname": "Doe",
"hint_data": "firstname",
"groups": ["group-uuid-1"]
}
]
Synchronization
Get Contacts After Version
http
GET /contacts/contactsAfterVersion/
Get all contacts updated after a specific version number for synchronization.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| —————- | ——— | ——————- |
version | integer | Version number to get updates after |
json
{
"updated": [
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"firstname": "John",
"lastname": "Doe",
"version": 5,
"groups": ["group-uuid-1"]
}
],
"deleted": [
{
"uuid": "deleted-contact-uuid",
"version": 6,
"deleted_at": "2025-06-19T10:30:00.000Z"
}
]
}
Groups
List All Groups
http
GET /contacts/groups
Get all contact groups.
Response
json
[
{
"uuid": "group-uuid-1",
"name": "VIP Clients",
"version": 1
}
]
Create Group
http
POST /contacts/groups
Create a new contact group.
Request Body
json
{
"name": "New Prospects"
}
Response
json
{
"uuid": "group-uuid-2"
}
Delete Group
http
DELETE /contacts/groups/
Delete a contact group and all its associations.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| —————- | ——— | ——————- |
groupUuid | string | UUID of the group to delete |
json
{
"success": true,
"deleted": 1
}
Get Contacts in Group
http
GET /contacts/groups//contacts
Get all contacts that belong to a specific group.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| —————- | ——— | ——————- |
groupUuid | string | UUID of the group |
json
[
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"firstname": "John",
"lastname": "Doe",
"mobile_phone": "5559999"
}
]
Add Contact to Group
http
POST /contacts/contact_groups
Add a contact to a group.
Request Body
json
{
"fk_contact_uuid": "123e4567-e89b-12d3-a456-426614174000",
"fk_group_uuid": "group-uuid-1"
}
Response
json
{
"id": 1
}
Remove Contact from Group
http
DELETE /contacts/contact_groups
Remove a contact from a group.
Request Body
json
{
"fk_contact_uuid": "123e4567-e89b-12d3-a456-426614174000",
"fk_group_uuid": "group-uuid-1"
}
Response
json
{
"changes": 1
}
External ID Operations
The WebFones API provides convenient endpoints for managing contacts using your own external identifiers instead of UUIDs. This is particularly useful for CRM integrations where you want to use your existing record IDs.
Get Contact by External ID
http
GET /contacts/contacts/external/
Retrieve a specific contact by external ID.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| —————- | ——— | ——————- |
externalId | string | External ID of the contact |
json
{
"uuid": "123e4567-e89b-12d3-a456-426614174000",
"firstname": "John",
"lastname": "Doe",
"organization": "Acme Corp",
"organization_flag": true,
"user_id": 1,
"phone_numbers": ["555-1234", "555-5678"],
"mobile_phone": "555-9999",
"email": "john@example.com",
"address": "123 Main St",
"city": "Anytown",
"state": "CA",
"zip": "12345",
"country": "USA",
"note": "Important client",
"version": 1,
"profile_url": "https://example.com/profile.jpg",
"external_id": "CRM-12345",
"groups": [
{
"uuid": "group-uuid-1",
"name": "VIP Clients"
}
]
}
Update Contact by External ID
http
PUT /contacts/contacts/external/
Update an existing contact by external ID.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| —————- | ——— | ——————- |
externalId | string | External ID of the contact to update |
Same structure as Create Contact.
Response
json
{
"message": "Contact updated successfully.",
"uuid": "123e4567-e89b-12d3-a456-426614174000"
}
Delete Contact by External ID
http
DELETE /contacts/contacts/external/
Delete a contact by external ID.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
| —————- | ——— | ——————- |
externalId | string | External ID of the contact to delete |
json
{
"success": true,
"uuid": "123e4567-e89b-12d3-a456-426614174000"
}
- Data Models
- Contact
| Field | Type | Description |
|---|---|---|
| ———- | ——— | ——————- |
uuid | string | Unique identifier (UUID) |
firstname | string | First name |
lastname | string | Last name |
organization | string | Organization name |
organization_flag | boolean | Whether this is an organization contact |
user_id | integer | Associated user ID |
phone_numbers | array | Array of phone numbers |
mobile_phone | string | Primary mobile phone number |
email | string | Email address |
address | string | Street address |
city | string | City |
state | string | State/Province |
zip | string | ZIP/Postal code |
country | string | Country |
note | string | Notes |
version | integer | Version number for sync |
profile_url | string | Profile image URL |
external_id | string | External system identifier |
groups | array | Array of group UUIDs |
| Field | Type | Description |
|---|---|---|
| ———- | ——— | ——————- |
uuid | string | Unique identifier (UUID) |
name | string | Group name |
version | integer | Version number for sync |
- 401 Unauthorized
json
{
"error": "API key is required",
"message": "Please provide API key in x-api-key header or Authorization header"
}
- 403 Forbidden
json
{
"error": "Invalid API key",
"message": "The provided API key is not valid or has been revoked"
}
- 404 Not Found
json
{
"error": "Contact not found"
}
- 429 Too Many Requests
json
{
"error": "Too many requests from this IP, please try again later."
}
- 500 Internal Server Error
json
{
"error": "Internal server error",
"message": "An unexpected error occurred",
"timestamp": "2025-06-19T10:30:00.000Z"
}
- 503 Service Unavailable
json
{
"error": "Contacts service unavailable",
"message": "The contacts service is currently unreachable."
}
Code Examples
cURL
*Create a contact
bash
curl -X POST "https://api.webfones.com:2343/contacts/contacts" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"firstname": "John",
"lastname": "Doe",
"mobile_phone": "5551234567",
"email": "john@example.com"
}'
Search by phone
bash
curl -X POST "https://api.webfones.com:2343/contacts/contacts/search/mobile" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"mobile_phone": "5551234567"}'
JavaScript
Initialize API client
javascript
const apiKey = ‘YOUR_API_KEY’;
const baseUrl = ‘https://api.webfones.com:2343’;
const headers = {
‘x-api-key’: apiKey,
‘Content-Type’: ‘application/json’
};
Create a contact
javascript
const createContact = async (contactData) => {
const response = await fetch(${ baseUrl }/contacts/contacts, {
method: ‘POST’,
headers: headers,
body: JSON.stringify(contactData)
}); if (!response.ok) {
throw new Error(HTTP error! status: ${response.status});
}
return await response.json();
};
// Usage
const newContact = await createContact({
firstname: ‘John’,
lastname: ‘Doe’,
mobile_phone: ‘5551234567’,
email: ‘john@example.com’
});
Search contacts
javascript
const searchByPhone = async (phoneNumber) => {
const response = await fetch(${ baseUrl }/contacts/contacts/search/mobile, {
method: ‘POST’,
headers: headers,
body: JSON.stringify({ mobile_phone: phoneNumber })
}); if (!response.ok) {
throw new Error(HTTP error! status: ${response.status});
}
return await response.json();
};
// Usage
const contact = await searchByPhone(‘5551234567’);
Python
- Initialize API client
python
import requests
import json
API_KEY = ‘YOUR_API_KEY’
BASE_URL = ‘https://api.webfones.com:2343’
headers = {
‘x-api-key’: API_KEY,
‘Content-Type’: ‘application/json’
}
Create a contact
python
def create_contact(contact_data):
response = requests.post(
f’{BASE_URL}/contacts/contacts’,
headers=headers,
json=contact_data
)
response.raise_for_status()
return response.json()
- Usage
‘firstname’: ‘John’,
‘lastname’: ‘Doe’,
‘mobile_phone’: ‘5551234567’,
‘email’: ‘john@example.com’
})
Search contacts
python
def search_by_phone(phone_number):
response = requests.post(
f’{BASE_URL}/contacts/contacts/search/mobile’,
headers=headers,
json={‘mobile_phone’: phone_number}
)
response.raise_for_status()
return response.json()
- Usage
Update by external ID
bash
curl -X PUT "https://api.webfones.com:2343/contacts/contacts/external/CRM-12345" \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"firstname": "John",
"lastname": "Smith",
"email": "john.smith@example.com"
}'
Delete by external ID
bash
curl -X DELETE "https://api.webfones.com:2343/contacts/contacts/external/CRM-12345" \
-H "x-api-key: YOUR_API_KEY"
Get contact by external ID
bash
curl -X GET "https://api.webfones.com:2343/contacts/contacts/external/CRM-12345" \
-H "x-api-key: YOUR_API_KEY"
Update contact by external ID
javascript
const updateContactByExternalId = async (externalId, contactData) => {
const response = await fetch(${ baseUrl }/contacts/contacts/external/${ externalId }, {
method: ‘PUT’,
headers: headers,
body: JSON.stringify(contactData)
}); if (!response.ok) {
throw new Error(HTTP error! status: ${response.status});
}
return await response.json();
};
// Usage
const updated = await updateContactByExternalId(‘CRM-12345’, {
firstname: ‘John’,
lastname: ‘Smith’,
email: ‘john.smith@example.com’
});
Get contact by external ID
javascript
const getContactByExternalId = async (externalId) => {
const response = await fetch(${ baseUrl }/contacts/contacts/external/${ externalId }, {
method: ‘GET’,
headers: headers
}); if (!response.ok) {
throw new Error(HTTP error! status: ${response.status});
}
return await response.json();
};
// Usage
const contact = await getContactByExternalId(‘CRM-12345’);
Update contact by external ID
python
def update_contact_by_external_id(external_id, contact_data):
response = requests.put(
f’{BASE_URL}/contacts/contacts/external/{external_id}’,
headers=headers,
json=contact_data
)
response.raise_for_status()
return response.json()
- Usage
‘firstname’: ‘John’,
‘lastname’: ‘Smith’,
‘email’: ‘john.smith@example.com’
})
Get contact by external ID
python
def get_contact_by_external_id(external_id):
response = requests.get(
f’{BASE_URL}/contacts/contacts/external/{external_id}’,
headers=headers
)
response.raise_for_status()
return response.json()
- Usage
Notes
- Phone numbers are automatically normalized (leading ‘1’, ‘+’, and formatting characters are removed)
- Version numbers are automatically incremented for all create/update operations
- UUIDs are automatically generated for new contacts and groups
- Phone numbers in the
phone_numbersfield are stored as JSON arrays - Group associations are updated when contacts are created or modified
- Deleted contacts are moved to a separate table for synchronization purposes
- Search operations are case-insensitive for text fields
- The API supports both exact and partial matching for phone number searches