// Endpoints
Contacts
List, create, read and update contacts and their tags.
A contact is one phone number in your project. Each number appears only once: we match on the number, so +91 98765 43210 and +919876543210 are the same person.
/api/v1/contactsList contacts
Scope: contacts:read
Newest first, paginated. Optional filters: search (name or phone) and tag (a tag id).
curl "https://whatsapp.esendblue.com/api/v1/contacts?search=priya&limit=20" \
-H "Authorization: Bearer wacrm_live_YOUR_KEY"/api/v1/contactsCreate (or find) a contact
Scope: contacts:write
Find or create by phone. A new contact returns 201; if the number already exists you get 200 with the existing contact, so it is safe to call on every sign-up in your own system.
| Field | Notes |
|---|---|
phone | Required, E.164 |
name | Optional |
email | Optional |
company | Optional |
tags | Optional array of tag names. Missing tags are created |
curl -X POST https://whatsapp.esendblue.com/api/v1/contacts \
-H "Authorization: Bearer wacrm_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{ "phone": "+919876543210", "name": "Priya Sharma", "tags": ["website-signup"] }'/api/v1/contacts/{id}Read a contact
Scope: contacts:read
One contact. A contact from another project returns 404, not 403, so ids cannot be probed.
{ "data": {
"id": "…",
"phone": "+919876543210",
"name": "Priya Sharma",
"email": "priya@example.com",
"company": "Sharma Traders",
"avatar_url": null,
"tags": [{ "id": "…", "name": "vip", "color": "#3b82f6" }],
"created_at": "…",
"updated_at": "…"
} }/api/v1/contacts/{id}Update a contact
Scope: contacts:write
Updates only the fields you send: name, email, company, tags.
tags replaces, it does not add
"tags": ["paid"] leaves the contact with exactly one tag. To add a tag, read the contact first and send the old tags plus the new one.const API = "https://whatsapp.esendblue.com/api/v1";
const headers = {
Authorization: `Bearer ${process.env.WHATSAPP_API_KEY}`,
"Content-Type": "application/json",
};
const { data: contact } = await (await fetch(`${API}/contacts/${id}`, { headers })).json();
const tags = [...new Set([...contact.tags.map((t) => t.name), "paid"])];
await fetch(`${API}/contacts/${id}`, {
method: "PATCH",
headers,
body: JSON.stringify({ tags }),
});