Appearance
Opt-out List
Manage the numbers that have unsubscribed from — or been blocked from receiving — your messages. Opt-outs are enforced automatically on every send path (single message, campaign, and API), so you never message a recipient who asked to stop.
Why this matters
Messaging recipients who complain or block you drives down your WhatsApp quality rating, which can get a number rate-limited or disabled. Honouring opt-outs protects the deliverability of all your numbers.
How opt-outs happen
| Source | source | Description |
|---|---|---|
| Keyword reply | keyword | The recipient replies with a stop word (e.g. ايقاف, STOP, unsubscribe). Added instantly, before any flow runs. |
| Inbox block | manual | An agent blocks the contact from the live inbox. |
| Manual / dashboard | manual | Added from the Opt-out List page. |
| CSV import | import | Bulk-imported suppression list. |
| API | api | Added via the endpoints below. |
Scope
scope | Effect |
|---|---|
marketing | Suppresses promotional (MARKETING) messages only. Transactional/utility and service messages still send. This is what a keyword STOP sets. |
all | Full block — suppresses every message. This is what an inbox block sets. |
A marketing opt-out never downgrades an existing all block.
Enforcement on send
When you call POST /api/v1/messages/send or create a campaign for an opted-out recipient, the send is rejected (single message) or the recipient is skipped (campaign). The single-message error is RECIPIENT_OPTED_OUT (HTTP 422). A marketing template is blocked by a marketing opt-out; any message is blocked by an all opt-out.
Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/v1/opt-outs | List opted-out numbers |
GET | /api/v1/opt-outs/{phone} | Check whether a number is opted out |
POST | /api/v1/opt-outs | Add a number to the opt-out list |
DELETE | /api/v1/opt-outs/{phone} | Remove a number (re-subscribe) |
List opt-outs
GET /api/v1/opt-outsQuery parameters
| Parameter | Type | Description |
|---|---|---|
per_page | integer | Results per page (max 100, default 50) |
scope | string | Filter by marketing or all |
phone | string | Filter by a phone substring (digits only) |
Example
bash
curl -X GET "https://cubeconnect.io/api/v1/opt-outs?scope=marketing&per_page=20" \
-H "Authorization: Bearer YOUR_API_KEY"json
{
"success": true,
"data": {
"opt_outs": [
{
"phone": "966501234567",
"scope": "marketing",
"source": "keyword",
"opted_out_at": "2026-08-13T10:22:05+00:00"
}
],
"pagination": {
"current_page": 1,
"per_page": 20,
"total": 1,
"last_page": 1
}
}
}Check a single number
GET /api/v1/opt-outs/{phone}bash
curl -X GET "https://cubeconnect.io/api/v1/opt-outs/966501234567" \
-H "Authorization: Bearer YOUR_API_KEY"json
{
"success": true,
"data": {
"phone": "966501234567",
"opted_out": true,
"scope": "marketing",
"source": "keyword",
"opted_out_at": "2026-08-13T10:22:05+00:00"
}
}For a number that is not opted out, opted_out is false and the other fields are null.
Add a number
POST /api/v1/opt-outsBody
| Field | Type | Required | Description |
|---|---|---|---|
phone | string | Yes | Recipient phone in international format |
scope | string | No | marketing (default) or all |
bash
curl -X POST "https://cubeconnect.io/api/v1/opt-outs" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "phone": "966501234567", "scope": "marketing" }'json
{
"success": true,
"data": {
"phone": "966501234567",
"scope": "marketing",
"opted_out_at": "2026-08-13T10:22:05+00:00"
}
}Adding is idempotent — re-adding an existing number updates its record, and an all block is never downgraded to marketing.
Remove a number (re-subscribe)
DELETE /api/v1/opt-outs/{phone}bash
curl -X DELETE "https://cubeconnect.io/api/v1/opt-outs/966501234567" \
-H "Authorization: Bearer YOUR_API_KEY"json
{
"success": true,
"data": {
"phone": "966501234567",
"removed": true
}
}removed is false when the number was not on the list.