Contact & Group Management
Full CRUD over contacts and groups — single or bulk (up to 50,000 per request), with tags, custom fields and opt-out controls.
Reference
Manage your contacts and groups programmatically using your vendor API key. All endpoints accept and return JSON, are scoped to a single WhatsApp number (encodedPhoneId) and require an r/w-scoped Bearer token.
Resources
Download the collection
Endpoints
Base URLs
| Base URL | Description |
|---|---|
https://your-api.com/api | Backend API — direct connection |
https://your-domain.com/api | Frontend Proxy — same body format, same token |
Security
Authentication
Every request must include a valid Bearer token. Generate one from WhatsApp Settings → API & Webhook → API Keys.
curl https://your-api.com/api/external/contacts/{encodedPhoneId} \
-H "Authorization: Bearer <your_api_token>"
Access control
Permissions
| Permission | Grants access to |
|---|---|
read_contacts | GET (list, get single, list groups, get group) |
write_contacts | POST, PUT, DELETE (create, update, delete contacts & groups; bulk import) |
Routes
Endpoints overview
| Method | Path | Permission |
|---|---|---|
GET | /api/external/contacts/{phoneId} | read_contacts |
POST | /api/external/contacts/{phoneId} | write_contacts |
GET | /api/external/contacts/{phoneId}/{id} | read_contacts |
PUT | /api/external/contacts/{phoneId}/{id} | write_contacts |
DELETE | /api/external/contacts/{phoneId}/{id} | write_contacts |
POST | /api/external/contacts/{phoneId}/bulk | write_contacts |
GET | /api/external/contacts/{phoneId}/groups | read_contacts |
POST | /api/external/contacts/{phoneId}/groups | write_contacts |
GET | /api/external/contacts/{phoneId}/groups/{groupId} | read_contacts |
PUT | /api/external/contacts/{phoneId}/groups/{groupId} | write_contacts |
DELETE | /api/external/contacts/{phoneId}/groups/{groupId} | write_contacts |
POST | /api/external/contacts/{phoneId}/groups/{groupId}/add | write_contacts |
POST | /api/external/contacts/{phoneId}/groups/{groupId}/remove | write_contacts |
Schema
Contact object
{
"_id": "64f1a2b3c4d5e6f7a8b9c0d1",
"name": "John Doe",
"phone": "919876543210",
"email": "john@example.com",
"language_code": "en",
"tags": ["vip", "newsletter"],
"notes": "Preferred contact via WhatsApp.",
"opt_out": false,
"opt_out_marketing": false,
"reply_bot_enabled": true,
"custom_fields": {
"city": "Mumbai",
"loyalty_tier": "gold"
},
"createdAt": "2024-01-15T10:30:00.000Z",
"updatedAt": "2024-01-20T14:22:00.000Z"
}GET
1. List contacts
/api/external/contacts/{encodedPhoneId}Query parameters
| Parameter | Type | Description |
|---|---|---|
search | string | Search by name or phone |
tag | string | Filter by a single tag |
opt_out | boolean | Filter opted-out contacts |
page | number | Page number (default: 1) |
limit | number | Results per page (default: 20, max: 100) |
curl "https://your-api.com/api/external/contacts/{phoneId}?search=john&tag=vip&page=1&limit=20" \
-H "Authorization: Bearer <token>"
Response
{
"success": true,
"data": {
"contacts": [
{
"_id": "64f1a2b3c4d5e6f7a8b9c0d1",
"name": "John Doe",
"phone": "919876543210",
"email": "john@example.com",
"tags": ["vip"],
"opt_out": false,
"createdAt": "2024-01-15T10:30:00.000Z"
}
],
"pagination": { "page": 1, "limit": 20, "total": 1, "totalPages": 1 }
},
"message": "Contacts retrieved successfully."
}GET
2. Get contact
/api/external/contacts/{encodedPhoneId}/{contactId}{
"success": true,
"data": { "contact": { /* ...contactObject */ } },
"message": "Contact retrieved successfully."
}POST
3. Create contact
/api/external/contacts/{encodedPhoneId}Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Full name |
phone | string | Yes | Phone in E.164 format (e.g. +919876543210) |
email | string | No | Email address |
language_code | string | No | e.g. en, hi, ar |
tags | string[] | No | Array of label strings |
notes | string | No | Free-text notes (max 2000 chars) |
opt_out | boolean | No | Block all outbound messages (default: false) |
opt_out_marketing | boolean | No | Exclude from campaigns (default: false) |
reply_bot_enabled | boolean | No | Allow chatbot to reply (default: true) |
custom_fields | object | No | Key-value map of custom field values |
curl -X POST https://your-api.com/api/external/contacts/{phoneId} \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Jane Smith",
"phone": "+919876543210",
"email": "jane@example.com",
"language_code": "en",
"tags": ["customer", "vip"],
"notes": "High-value customer",
"reply_bot_enabled": true,
"custom_fields": {
"city": "Delhi",
"loyalty_tier": "platinum"
}
}'
PUT
4. Update contact
/api/external/contacts/{encodedPhoneId}/{contactId}Send only the fields you want to update — everything else is preserved.
curl -X PUT https://your-api.com/api/external/contacts/{phoneId}/{contactId} \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"tags": ["vip", "renewed"],
"custom_fields": { "loyalty_tier": "gold" }
}'
DELETE
5. Delete contact
/api/external/contacts/{encodedPhoneId}/{contactId}Deletes the contact and removes them from all groups.
POST
6. Bulk import contacts
/api/external/contacts/{encodedPhoneId}/bulkImport or update up to 50,000 contacts in a single request. Contacts are upserted by phone number.
{
"contacts": [
{
"name": "John Doe",
"phone": "+919876543210",
"email": "john@example.com",
"language_code": "en",
"tags": ["newsletter"],
"groups": ["VIP Customers"],
"custom_fields": { "city": "Mumbai" }
},
{
"name": "Jane Smith",
"phone": "+919812345678"
}
]
}Bulk field reference
| Field | Type | Required | Description |
|---|---|---|---|
name | string | No | Full name (or use first_name + last_name) |
first_name | string | No | Combined with last_name |
last_name | string | No | Combined with first_name |
phone | string | Yes | E.164 format |
email | string | No | Email address |
language_code | string | No | e.g. en, hi |
tags | string[] | No | Array of tag strings |
groups | string[] | No | Group names — auto-created if missing |
custom_fields | object | No | Key-value custom field values |
{
"success": true,
"data": { "created": 150, "updated": 42, "skipped": 3, "errors": [] },
"message": "Bulk import complete."
}Groups
7-13. Group operations
List groups
/api/external/contacts/{encodedPhoneId}/groups{
"success": true,
"data": {
"groups": [
{
"_id": "64f1a2b3c4d5e6f7a8b9c0d2",
"name": "VIP Customers",
"description": "High-value customers",
"contacts": ["id1", "id2"],
"createdAt": "2024-01-10T08:00:00.000Z"
}
],
"pagination": { "page": 1, "limit": 20, "total": 1, "totalPages": 1 }
},
"message": "Groups retrieved successfully."
}Create group
/api/external/contacts/{encodedPhoneId}/groups{
"name": "Newsletter Subscribers",
"description": "Contacts subscribed to the weekly newsletter"
}Get group
/api/external/contacts/{encodedPhoneId}/groups/{groupId}Returns the group with its full contact list (populated).
Update group
/api/external/contacts/{encodedPhoneId}/groups/{groupId}{
"name": "Premium Subscribers",
"description": "Updated description"
}Delete group
/api/external/contacts/{encodedPhoneId}/groups/{groupId}Deletes the group only — contacts are NOT deleted.
Add / remove contacts
/api/external/contacts/{encodedPhoneId}/groups/{groupId}/add/api/external/contacts/{encodedPhoneId}/groups/{groupId}/remove{
"contact_ids": ["64f1a2b3c4d5e6f7a8b9c0d1", "64f1a2b3c4d5e6f7a8b9c0d4"]
}Edge cases
Errors
| HTTP | Meaning |
|---|---|
400 | Bad Request — missing required fields or invalid data |
401 | Unauthorized — missing, invalid, or expired Bearer token |
403 | Forbidden — token does not have required permission |
404 | Not Found — contact or group id does not exist |
409 | Conflict — phone number already exists (on create) |
500 | Internal Server Error |
{
"success": false,
"message": "A contact with this phone number already exists."
}Advanced
Custom fields
Custom fields must be defined first in the dashboard (Contacts → Fields tab) before values can be stored. The custom_fields object uses the field's internal key as the property name.
{
"custom_fields": {
"city": "Mumbai",
"loyalty_tier": "gold"
}
}