Skip to content
Beta — the Waasl API is in private beta. Endpoints marked Coming soon are designed but not live yet. Request early access

Contacts

People you talk to. A contact has one or more channel identities (WhatsApp number, Instagram handle, email…).

GET/v1/contactsAvailable

Newest activity first. q matches name, phone and email with Arabic-aware folding (أحمد = احمد = إحمد).

Query parameters

Field Type Description
q string Free-text search.
tag string Only contacts with this tag.
stage_id string Only contacts in this lifecycle stage.
channel_type “whatsapp” | “instagram” | “messenger” | “sms” | “email” | “webchat”
limit integer
cursor string The next_cursor from the previous page.
Terminal window
curl "https://api.waasl.io/v1/contacts" \
-H "Authorization: Bearer $WAASL_API_KEY"
Response 200 — A page of contacts
{
"data": [
{
"id": "ct_8Jk2Lm",
"name": "Sara Al-Mutairi",
"identities": [
{
"channel_type": null,
"identifier": null,
"display_name": null
}
],
"email": "string",
"language": "ar",
"dialect": "kuwaiti",
"vip": true,
"blocked": true,
"tags": [
"vip"
],
"stage_id": "customer",
"consents": {},
"custom_fields": {},
"last_activity_at": "2026-10-01T08:15:00Z"
}
],
"next_cursor": "MjAyNi0xMC0wMVQwODoxNTowMC4wMDBafGN2XzNQekE5MQ",
"has_more": true
}

Errors: 401 Missing, invalid or revoked API key

POST/v1/contactsBeta

Upserts by identity: if a contact already owns one of the given identities it is updated, otherwise a new contact is created. Phone numbers are normalised to E.164. Returns 201 when created and 200 when an existing contact was updated.

Headers

Field Type Description
Idempotency-Key string A unique key (UUID recommended). Retrying with the same key returns the original result instead of acting twice. Kept for 24 hours.

Request body

Field Type Description
name string
identities required object[]
identities[].channel_type “whatsapp” | “instagram” | “messenger” | “sms” | “email” | “webchat” Only whatsapp is live; the others are coming soon.
identities[].identifier string Phone in E.164 (or a local 8-digit Kuwaiti number), handle or email.
identities[].display_name string
email string (email)
language string
vip boolean
tags string[]
stage_id string
custom_fields object Keys must exist in /custom-fields (coming soon).
consents object Marketing opt-in per channel — required before sending marketing templates.
Terminal window
curl -X POST "https://api.waasl.io/v1/contacts" \
-H "Authorization: Bearer $WAASL_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"name": "Sara Al-Mutairi",
"identities": [
{
"channel_type": "whatsapp",
"identifier": "+96550001234"
}
],
"email": "sara@example.com",
"language": "ar",
"tags": [
"vip",
"ramadan-2026"
],
"custom_fields": {
"plan": "Keto 30",
"city": "Salmiya"
}
}'
Response 200 — Existing contact updated
{
"id": "ct_8Jk2Lm",
"name": "Sara Al-Mutairi",
"identities": [
{
"channel_type": "whatsapp",
"identifier": "+96550001234",
"display_name": "string"
}
],
"email": "string",
"language": "ar",
"dialect": "kuwaiti",
"vip": true,
"blocked": true,
"tags": [
"vip"
],
"stage_id": "customer",
"consents": {},
"custom_fields": {},
"last_activity_at": "2026-10-01T08:15:00Z"
}

Errors: 422 The request body is invalid

POST/v1/contacts/importAvailable

Upserts up to 1,000 contacts per call. Rows that fail validation are reported individually; the rest are imported.

Request body

Field Type Description
contacts required object[]
contacts[].name string
contacts[].identities object[]
contacts[].email string (email)
contacts[].language string
contacts[].vip boolean
contacts[].tags string[]
contacts[].stage_id string
contacts[].custom_fields object Keys must exist in /custom-fields (coming soon).
contacts[].consents object Marketing opt-in per channel — required before sending marketing templates.
Terminal window
curl -X POST "https://api.waasl.io/v1/contacts/import" \
-H "Authorization: Bearer $WAASL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contacts": [
{
"name": "Sara",
"identities": [
{
"channel_type": "whatsapp",
"identifier": "+96550001234"
}
]
},
{
"name": "Omar",
"identities": [
{
"channel_type": "whatsapp",
"identifier": "55512345"
}
],
"tags": [
"lead"
]
}
]
}'
Response 200 — Import result
{
"created": 1,
"updated": 1,
"failed": [
{
"index": 0,
"code": "invalid_phone"
}
]
}
GET/v1/contacts/{contact_id}Available

Path parameters

Field Type Description
contact_id required string
Terminal window
curl "https://api.waasl.io/v1/contacts/ct_8Jk2Lm" \
-H "Authorization: Bearer $WAASL_API_KEY"
Response 200 — The contact
{
"id": "ct_8Jk2Lm",
"name": "Sara Al-Mutairi",
"identities": [
{
"channel_type": "whatsapp",
"identifier": "+96550001234",
"display_name": "string"
}
],
"email": "string",
"language": "ar",
"dialect": "kuwaiti",
"vip": true,
"blocked": true,
"tags": [
"vip"
],
"stage_id": "customer",
"consents": {},
"custom_fields": {},
"last_activity_at": "2026-10-01T08:15:00Z"
}

Errors: 404 Not found in this workspace

PATCH/v1/contacts/{contact_id}Available

Only the fields you send change. Send tags to replace the tag set; set blocked to stop all outbound messages to this contact.

Path parameters

Field Type Description
contact_id required string

Request body

Field Type Description
name string
email string (email)
language string
vip boolean
blocked boolean
tags string[]
stage_id string | null
custom_fields object
Terminal window
curl -X PATCH "https://api.waasl.io/v1/contacts/ct_8Jk2Lm" \
-H "Authorization: Bearer $WAASL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"vip": true,
"tags": [
"vip",
"renewed"
],
"stage_id": "customer"
}'
Response 200 — Updated contact
{
"id": "ct_8Jk2Lm",
"name": "Sara Al-Mutairi",
"identities": [
{
"channel_type": "whatsapp",
"identifier": "+96550001234",
"display_name": "string"
}
],
"email": "string",
"language": "ar",
"dialect": "kuwaiti",
"vip": true,
"blocked": true,
"tags": [
"vip"
],
"stage_id": "customer",
"consents": {},
"custom_fields": {},
"last_activity_at": "2026-10-01T08:15:00Z"
}

Errors: 404 Not found in this workspace · 422 The request body is invalid

DELETE/v1/contacts/{contact_id}Coming soon

Permanently erases the contact, its identities and its conversation history (GDPR / PDPL right to erasure).

Path parameters

Field Type Description
contact_id required string
Terminal window
curl -X DELETE "https://api.waasl.io/v1/contacts/ct_8Jk2Lm" \
-H "Authorization: Bearer $WAASL_API_KEY"

Returns 204 — Deleted.

Errors: 404 Not found in this workspace

POST/v1/contacts/{contact_id}/mergeComing soon

Folds source_contact_id into this contact — identities, tags and conversations move over; the source is deleted.

Path parameters

Field Type Description
contact_id required string

Request body

Field Type Description
source_contact_id required string
Terminal window
curl -X POST "https://api.waasl.io/v1/contacts/ct_8Jk2Lm/merge" \
-H "Authorization: Bearer $WAASL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source_contact_id": "ct_8Jk2Lm"
}'
Response 200 — The surviving contact
{
"id": "ct_8Jk2Lm",
"name": "Sara Al-Mutairi",
"identities": [
{
"channel_type": "whatsapp",
"identifier": "+96550001234",
"display_name": "string"
}
],
"email": "string",
"language": "ar",
"dialect": "kuwaiti",
"vip": true,
"blocked": true,
"tags": [
"vip"
],
"stage_id": "customer",
"consents": {},
"custom_fields": {},
"last_activity_at": "2026-10-01T08:15:00Z"
}
GET/v1/custom-fieldsComing soon
Terminal window
curl "https://api.waasl.io/v1/custom-fields" \
-H "Authorization: Bearer $WAASL_API_KEY"
Response 200 — Field definitions
{
"data": [
{
"key": "string",
"label": "string",
"type": "text",
"options": [
"string"
]
}
]
}
POST/v1/custom-fieldsComing soon

Request body

Field Type Description
key required string
label string
type required “text” | “number” | “date” | “boolean” | “select”
options string[]
Terminal window
curl -X POST "https://api.waasl.io/v1/custom-fields" \
-H "Authorization: Bearer $WAASL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"key": "plan",
"label": "Subscription plan",
"type": "text"
}'
Response 201 — Created
{
"key": "string",
"label": "string",
"type": "text",
"options": [
"string"
]
}
GET/v1/tagsComing soon

Every tag used in the workspace, with how many contacts carry it.

Terminal window
curl "https://api.waasl.io/v1/tags" \
-H "Authorization: Bearer $WAASL_API_KEY"
Response 200 — Tags
{
"data": [
{
"name": "vip",
"contacts": 42
}
]
}
GET/v1/stagesAvailable

The pipeline stages a contact or conversation can be in (New lead → Hot lead → Customer…).

Terminal window
curl "https://api.waasl.io/v1/stages" \
-H "Authorization: Bearer $WAASL_API_KEY"
Response 200 — Stages, in order
[
{
"id": "hot_lead",
"name": "عميل مهتم",
"emoji": "🔥",
"order": 0
}
]