Contacts
هذا المحتوى غير متوفر بلغتك بعد.
GET /v1/contacts
Section titled “GET /v1/contacts”Scope: contacts:read
| Query | Notes |
|---|---|
search | Matches phone number or name |
phone | Exact phone number |
tag | Contacts carrying this tag |
updated_since | RFC 3339 timestamp. Only contacts changed at or after it. |
limit | 1 to 200, default 50 |
cursor | From next_cursor |
updated_since is what makes a nightly sync possible without pulling the whole
book every night. See Sync contacts from your CRM.
{ "data": [ { "id": "3f2a...", "phone_number": "+966500000000", "name": "Sara", "channel": "whatsapp", "account": "Main", "tags": ["vip", "riyadh"], "metadata": { "crm_id": "C-4471" }, "marketing_opt_out": false, "last_message_at": "2026-08-20T09:12:00Z", "created_at": "2026-05-02T11:00:00Z", "updated_at": "2026-08-20T09:12:00Z" } ], "has_more": false}GET /v1/contacts/{id}
Section titled “GET /v1/contacts/{id}”Scope: contacts:read
POST /v1/contacts
Section titled “POST /v1/contacts”Scope: contacts:write · Accepts Idempotency-Key
{ "phone_number": "+966500000000", "name": "Sara", "tags": ["vip"], "metadata": { "crm_id": "C-4471" }}phone_number is required. Everything else is optional.
A duplicate returns 409 with contact_exists, and the message includes the
existing contact’s id so you can recover without a second call. Nothing is
merged silently, because an integration creating the same customer twice has a
bug worth seeing.
You often do not need this endpoint at all: sending to a number that has no contact creates one.
metadata
Section titled “metadata”A free-form JSON object for your own identifiers. Put your CRM’s primary key here and every later sync becomes a lookup rather than a fuzzy match on a phone number.
PUT /v1/contacts/{id}
Section titled “PUT /v1/contacts/{id}”Scope: contacts:write
A partial update despite the verb: fields you omit are left alone. Only what you send changes.
{ "name": "Sara Al-Ahmed" }That changes the name and leaves the tags untouched. To clear a field, send it
explicitly as "" or [].
The phone number cannot be changed. It is identity here, and editing it would redirect an existing conversation’s history to a different person. Create a new contact instead.
PUT /v1/contacts/{id}/tags
Section titled “PUT /v1/contacts/{id}/tags”Replaces the whole tag list.
Scope: contacts:write
{ "tags": ["vip", "riyadh"] }tags is required; send [] to clear them. It is required rather than
optional precisely so that omitting it cannot be confused with clearing.
Blanks and duplicates are dropped, so the same set always reads back the same.
DELETE /v1/contacts/{id}
Section titled “DELETE /v1/contacts/{id}”Scope: contacts:delete
Returns 204. This takes the conversation history with it, which is why it has
a scope of its own rather than being folded into contacts:write.