WebFones Documentation

Administrator Guide

Menu

Switch to User Guide

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

ParameterTypeDescription
—————-—————————-
contactIdstringUUID of the contact
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": [
{
"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

ParameterTypeDescription
—————-—————————-
contactIdstringUUID of the contact to update
Request Body

Same structure as Create Contact.

Response

json
{ "message": "Contact updated successfully."
}

Delete Contact

http
DELETE /contacts/contacts/

Delete a contact.

Path Parameters

ParameterTypeDescription
—————-—————————-
contactIdstringUUID of the contact to delete
Response

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

ParameterTypeDescription
—————-—————————-
searchStringstringText to search across name, organization, and other fields
letterstringFilter by first letter of last name
groupUUIDstringFilter by group membership
Response

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

ParameterTypeDescription
—————-—————————-
versionintegerVersion number to get updates after
Response

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

ParameterTypeDescription
—————-—————————-
groupUuidstringUUID of the group to delete
Response

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

ParameterTypeDescription
—————-—————————-
groupUuidstringUUID of the group
Response

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

ParameterTypeDescription
—————-—————————-
externalIdstringExternal ID of the contact
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": "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

ParameterTypeDescription
—————-—————————-
externalIdstringExternal ID of the contact to update
Request Body

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

ParameterTypeDescription
—————-—————————-
externalIdstringExternal ID of the contact to delete
Response

json
{ "success": true,
"uuid": "123e4567-e89b-12d3-a456-426614174000"
}
  • Data Models
  • Contact
FieldTypeDescription
———-—————————-
uuidstringUnique identifier (UUID)
firstnamestringFirst name
lastnamestringLast name
organizationstringOrganization name
organization_flagbooleanWhether this is an organization contact
user_idintegerAssociated user ID
phone_numbersarrayArray of phone numbers
mobile_phonestringPrimary mobile phone number
emailstringEmail address
addressstringStreet address
citystringCity
statestringState/Province
zipstringZIP/Postal code
countrystringCountry
notestringNotes
versionintegerVersion number for sync
profile_urlstringProfile image URL
external_idstringExternal system identifier
groupsarrayArray of group UUIDs
1. Group

FieldTypeDescription
———-—————————-
uuidstringUnique identifier (UUID)
namestringGroup name
versionintegerVersion number for sync
1. Error Codes

  • 401 Unauthorized
API key is missing or invalid.

json
{ "error": "API key is required",
"message": "Please provide API key in x-api-key header or Authorization header"
}
  • 403 Forbidden
API key is not valid or has been revoked.

json
{ "error": "Invalid API key",
"message": "The provided API key is not valid or has been revoked"
}
  • 404 Not Found
Requested resource was not found.

json
{ "error": "Contact not found"
}
  • 429 Too Many Requests
Rate limit exceeded.

json
{ "error": "Too many requests from this IP, please try again later."
}
  • 500 Internal Server Error
An unexpected error occurred.

json
{ "error": "Internal server error",
"message": "An unexpected error occurred",
"timestamp": "2025-06-19T10:30:00.000Z"
}
  • 503 Service Unavailable
Backend service is 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
new_contact = create_contact({
‘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
contact = search_by_phone(‘5551234567’)

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
updated = update_contact_by_external_id(‘CRM-12345’, {
‘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
contact = get_contact_by_external_id(‘CRM-12345’)

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_numbers field 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

AI Documentation Assistant

Suggested Questions

How do I set up call forwarding? What is a ring group? How do I check voicemail? How do I add a new extension?
Thinking...