Opt Outs API

Create, get and delete numbers from your Opt Out List

The Opt Outs API lets you manage the list of recipients who have opted out of receiving messages on a given channel. Use it to query existing opt-outs, create new ones, and remove them — for example, to honour an unsubscribe request, sync opt-out state from another system, or audit who is currently suppressed.

Account-level vs asset-level opt-outs

Every opt-out is recorded at one of two scopes:

Account-level — the opt-out applies across all assets on the account for that channel. A recipient who is opted out at the account level will not receive messages on that channel from any of your numbers or WhatsApp profiles.
Asset-level — the opt-out is scoped to a single asset (a specific inbound number or WhatsApp profile). The recipient remains contactable on that channel via your other assets.

In responses, the account_level_opt_out field tells you which scope a record uses. Asset-level records additionally return inbound_asset_id and inbound_number identifying the asset they are tied to.

Channels

Opt-outs are tracked per channel. The API currently supports SMS and WHATSAPP. The same phone number can hold separate opt-out records on each channel, and at different scopes — for example, an account-level WhatsApp opt-out alongside an asset-level SMS opt-out.

Synchronous processing

All three endpoints process requests synchronously. The create and delete endpoints accept arrays so you can submit multiple entries in a single request, but there is no background job — the response always reflects the final outcome of every entry. Each result is reported individually in an items array, so you should inspect the per-entry status rather than relying on the HTTP status alone, particularly when submitting in bulk.

Endpoints

MethodEndpointDescription
GET/optouts/Query the opt-outs on an account, with optional filtering and paging.
POST/optouts/Create one or more opt-outs at account or asset level.
DELETE/optouts/Remove one or more opt-outs, optionally scoped by channel or asset

Query the opt-outs

Method: GET

Rate Limit: 10 transactions per second.

Parameters

Parameter nameTypeMandatoryExample valuesDescription
numberstringNo+447807127121
447807127121
Exact match phone number search. Accepts either E.164 format (with + and country code) or a national number with country code.
opt_out_typestringNokeyword
web_opt_out
account_import
api_import
Filter by how the opt-out was created.

keyword - The recipient replied to an inbound asset with an opt-out keyword (for example, STOP).

web_opt_out - The recipient opted out via a web form.

account_import - The opt-out was added through a bulk import in the Webex Interact app.

api_import - The opt-out was added via the Opt Outs API.

Single value only.
channelstringNoSMS
WHATSAPP
Filter by communication channel. Case-insensitive.
inbound_numberstringNo447860000001Returned only when opt_out_type is keyword.

The inbound number associated with the asset. Can be either an E.164 long number (for example, +447860008141) or a short code (for example, 66777). Always treat as a string.
asset_idstringNonum_2AkZZTFulHFfIEHVYteKKsTdymoReturned only when opt_out_type is keyword.

The UID of the inbound asset (SMS dedicated inbound number or WhatsApp Business Profile) that received the opt-out keyword.
start_timestringNo2026-05-28T09:17:53ZFilter to opt-outs created at or after this time. ISO 8601 UTC format. Inclusive bound. Filters on opt_out_time.
end_timestringNo2026-05-28T09:17:53ZFilter to opt-outs created at or before this time. ISO 8601 UTC format. Inclusive bound. Filters on opt_out_time.
page_numberintegerNo1Determines which page is returned. Use in conjunction with page_size to control the set of opt-outs you want to get.

Defaults to 1 if not given.
page_sizeintegerNo10Determines how many items will be returned per page. Min: 1
Max: 1000

Defaults to 10 if not given.
sort_orderstringNoASC, DESCDetermines the sort order by opt_out_time. Defaults to DESC if not given.

📘

Default behaviour

If no parameters are supplied, the 10 most recently created opt-outs are returned.

Response fields

Field nameTypeDescription
numberstringThe phone number that has opted out, in E.164 format.
channelstringThe communication channel the opt-out applies to. Either SMS or WHATSAPP.
account_level_opt_outbooleantrue - The opt-out applies to all communications sent from your account on this channel.

false - The opt-out applies only to communications sent via the specific inbound asset returned in inbound_asset.
opt_out_typestringHow the opt-out was created. One of: keyword, web_opt_out, account_import, api_import.
inbound_assetstringReturned only when opt_out_type is keyword.

The UID of the inbound asset (SMS dedicated inbound number or WhatsApp Business Profile) that received the opt-out keyword.
inbound_numberstringReturned only when opt_out_type is keyword.

The inbound number associated with the asset. Can be either an E.164 long number (for example, +447860008141) or a short code (for example, 66777). Always treat as a string.
opt_out_timestringThe time the opt-out was created, in ISO 8601 UTC format.

Sample request

GET https://api.webexinteract.com/contacts/v1/optouts?opt_out_type=keyword&page_size=10

Sample responses

{
  "paging": {
    "current_page": 1,
    "total_items": 6,
    "total_pages": 1
  },
  "items": [
    {
      "number": "+447944638173",
      "channel": "SMS",
      "account_level_opt_out": true,
      "opt_out_type": "keyword",
      "inbound_asset_id": "num_397K0l3HrujnEtVfLFtaECRqFjV",
      "inbound_number": "66777",
      "opt_out_time": "2026-05-27T07:32:56Z"
    },
    {
      "number": "+447944638173",
      "channel": "SMS",
      "account_level_opt_out": false,
      "opt_out_type": "keyword",
      "inbound_asset_id": "num_3DNr8KIVDwMtQKYtYvRtQCXbc5x",
      "inbound_number": "+447860008141",
      "opt_out_time": "2026-05-27T07:29:13Z"
    },
    {
      "number": "+918074948043",
      "channel": "WHATSAPP",
      "account_level_opt_out": false,
      "opt_out_type": "keyword",
      "inbound_asset_id": "wbp_2k8U5Sdg3fM615QpOvEgzFiJZ1C",
      "inbound_number": "+447488865097",
      "opt_out_time": "2025-06-04T02:34:30Z"
    }
  ]
}
{
  "paging": {
    "current_page": 1,
    "total_items": 8861,
    "total_pages": 887
  },
  "items": [
    {
      "number": "+447807127121",
      "channel": "WHATSAPP",
      "account_level_opt_out": true,
      "opt_out_type": "api_import",
      "opt_out_time": "2026-05-28T09:17:53Z"
    },
    {
      "number": "+447944638175",
      "channel": "SMS",
      "account_level_opt_out": false,
      "opt_out_type": "api_import",
      "opt_out_time": "2026-05-27T07:38:45Z"
    }
  ]
}
{
  "trace_id": "no-trace-id",
  "code": "ERR_CNT_VAL_001",
  "error": "VALIDATION_ERROR",
  "message": "Invalid number. Supply a valid E.164 number, or a national number with country_code.",
  "status": 400,
  "timestamp": "2026-05-28T11:13:31.798355228Z",
  "validation_errors": null
}
{
  "trace_id": "no-trace-id",
  "code": "ERR_CNT_VAL_001",
  "error": "VALIDATION_ERROR",
  "message": "Invalid opt_out_type. Allowed values: keyword, web_opt_out, account_import, api_import.",
  "status": 400,
  "timestamp": "2026-05-28T11:02:15.336680287Z",
  "validation_errors": null
}
{
  "trace_id": "no-trace-id",
  "code": "ERR_CNT_VAL_001",
  "error": "VALIDATION_ERROR",
  "message": "Invalid channel. Must be SMS or WHATSAPP.",
  "status": 400,
  "timestamp": "2026-05-28T11:23:17.146338088Z",
  "validation_errors": null
}
{
  "trace_id": "no-trace-id",
  "code": "ERR_CNT_VAL_001",
  "error": "VALIDATION_ERROR",
  "message": "Request validation failed",
  "status": 400,
  "timestamp": "2026-05-28T11:18:49.836191335Z",
  "validation_errors": [
    {
      "field": "getOptOuts.pageSize",
      "message": "page.size.generic",
      "rejected_value": 1001
    }
  ]
}

Create an opt-out

Method: POST

ℹ️

One opt-out per request

The request body accepts an optouts array, but the endpoint processes a single entry per request. To create multiple opt-outs, send one request per opt-out.

📘

Existing opt-outs are replaced

If you create an opt-out for a number that is already opted out on the same channel and asset, the existing record is replaced and opt_out_time is updated to the latest timestamp.

Rate Limit: 10 transactions per second.

Parameters

Parameter nameTypeMandatoryExample valuesDescription
optoutsarrayYesN/AAn array containing one opt-out object.
numberstringYes+447807127121
447807127121
The phone number to opt out. Accepts either E.164 format (with + and country code) or a national number with country code. The number is normalised to E.164 in the response.
channelstringNoSMS
WHATSAPP
The communication channel the opt-out applies to. Case-insensitive.

Defaults to SMS if not given.
asset_idstringNonum_3DNr8KIVDwMtQKYtYvRtQCXbc5x
wbp_2k8U5Sdg3fM615QpOvEgzFiJZ1C
The UID of the inbound asset to associate the opt-out with. Use a num_ UID for SMS dedicated inbound numbers and a wbp_ UID for WhatsApp Business Profiles. The asset's channel must match the channel value.

If not given, the opt-out is applied at account level and applies to all communications sent on the specified channel.

Response fields

Field nameTypeDescription
total_submittedintegerThe number of opt-out entries submitted in the request.
total_succeededintegerThe number of opt-out entries that were successfully created.
total_failedintegerThe number of opt-out entries that failed to be created.
itemsarrayAn array containing the outcome of each submitted opt-out.
numberstringThe phone number, normalised to E.164 format.
channelstringThe communication channel the opt-out applies to. Either SMS or WHATSAPP.
statusstringThe outcome for this entry. Either success or failure.
messagestringA human-readable description of the outcome.
account_level_opt_outbooleanReturned only when status is success.

true - The opt-out applies to all communications sent from your account on this channel.

false - The opt-out applies only to the specific inbound asset.
opt_out_typestringReturned only when status is success.

Always api_import for opt-outs created via this endpoint.
opt_out_timestringReturned only when status is success.

The time the opt-out was created, in ISO 8601 UTC format.

ℹ️

HTTP 201 with failed entries

The endpoint returns HTTP 201 Created whenever the request body is well-formed, regardless of whether the opt-out was successfully created. Always inspect total_failed and results[].status to determine the outcome.

Sample requests

{
  "optouts": [
    {
      "number": "447807127121"
    }
  ]
}
{
  "optouts": [
    {
      "number": "447807127122",
      "channel": "sms",
      "asset_id": "num_3DNr8KIVDwMtQKYtYvRtQCXbc5x"
    }
  ]
}
{
  "optouts": [
    {
      "number": "447807127122",
      "channel": "whatsapp",
      "asset_id": "wbp_2k8U5Sdg3fM615QpOvEgzFiJZ1C"
    }
  ]
}

Sample responses

{
  "total_submitted": 1,
  "total_succeeded": 1,
  "total_failed": 0,
  "items": [
    {
      "number": "+447807127121",
      "channel": "SMS",
      "status": "success",
      "message": "Successfully opted out at account level for SMS",
      "account_level_opt_out": true,
      "opt_out_type": "api_import",
      "opt_out_time": "2026-05-28T12:01:29Z"
    }
  ]
}
{
  "total_submitted": 1,
  "total_succeeded": 1,
  "total_failed": 0,
  "items": [
    {
      "number": "+447807127122",
      "channel": "SMS",
      "status": "success",
      "message": "Successfully opted out for asset num_3DNr8KIVDwMtQKYtYvRtQCXbc5x",
      "account_level_opt_out": false,
      "opt_out_type": "api_import",
      "opt_out_time": "2026-05-28T12:00:46Z"
    }
  ]
}
{
  "total_submitted": 1,
  "total_succeeded": 0,
  "total_failed": 1,
  "items": [
    {
      "number": "sdc447807127121",
      "channel": "SMS",
      "status": "failure",
      "message": "Invalid phone number. Number must be in E.164 format."
    }
  ]
}
{
  "total_submitted": 1,
  "total_succeeded": 0,
  "total_failed": 1,
  "items": [
    {
      "number": "+447807127121",
      "channel": "SMS",
      "status": "failure",
      "message": "Invalid asset ID"
    }
  ]
}
{
  "total_submitted": 1,
  "total_succeeded": 0,
  "total_failed": 1,
  "items": [
    {
      "number": "+447807127122",
      "channel": "WHATSAPP",
      "status": "failure",
      "message": "Channel mismatch: the specified asset does not match the requested channel"
    }
  ]
}
{
  "trace_id": "no-trace-id",
  "code": "ERR_CNT_VAL_001",
  "error": "MISSING_REQUIRED_FIELD",
  "message": "Required field 'optOuts[0].number' is missing",
  "status": 400,
  "timestamp": "2026-05-28T12:08:22.598046993Z",
  "validation_errors": [
    {
      "field": "optOuts[0].number",
      "message": "Phone number is required",
      "rejected_value": null
    }
  ]
}
{
  "trace_id": "no-trace-id",
  "code": "ERR_CNT_REQ_002",
  "error": "INVALID_REQUEST_BODY",
  "message": "Invalid or malformed request body. Please check your JSON format and ensure all required fields are provided.",
  "status": 400,
  "timestamp": "2026-05-28T12:03:18.652549805Z",
  "validation_errors": null
}

Delete an opt-out

Method: DELETE

ℹ️

Bulk deletion is supported

Unlike the create endpoint, DELETE accepts multiple numbers per request and processes each entry independently. Inspect total_failed and results[].status to determine the outcome for each entry.

Rate Limit: 10 transactions per second.

Parameters

Parameter nameTypeMandatoryExample valuesDescription
numbersarray of stringsYes["+447807127121", "+447807127122"]The phone numbers to remove from opt-outs. Each entry accepts either E.164 format (with + and country code) or a national number with country code.
channelstringNoSMS
WHATSAPP
The communication channel to remove opt-outs from. Case-insensitive.

If not given, opt-outs are removed across both SMS and WHATSAPP channels.
asset_idstringNonum_3DNr8KIVDwMtQKYtYvRtQCXbc5x
wbp_2k8U5Sdg3fM615QpOvEgzFiJZ1C
The UID of the inbound asset to remove the opt-out from. Use a num_ UID for SMS dedicated inbound numbers and a wbp_ UID for WhatsApp Business Profiles. The asset's channel must match the channel value.

If not given, all opt-outs for the number on the specified channel(s) are removed, including account-level opt-outs and opt-outs against any asset.

📘

Account-level and asset-level opt-outs are independent

If a number has both an account-level opt-out and asset-level opt-outs:

  • Removing only the account-level opt-out (by specifying an asset_id of an asset where no opt-out exists) leaves asset-level opt-outs intact.
  • Removing only an asset-level opt-out leaves the account-level opt-out intact.
  • Omitting asset_id removes both account-level and all asset-level opt-outs for the number on the specified channel(s).

Response fields

Field nameTypeDescription
total_submittedintegerThe number of phone numbers submitted in the request.
total_succeededintegerThe number of opt-outs that were successfully removed.
total_failedintegerThe number of entries that failed to be removed.
itemsarrayAn array containing the outcome for each submitted number.
numberstringThe phone number, normalised to E.164 format on success or returned as submitted on failure.
statusstringThe outcome for this entry. Either success or failure.
messagestringA human-readable description of the outcome.

Sample requests

{
  "numbers": [
    "+447807127121",
    "+447807127122"
  ],
  "channel": "SMS"
}
{
  "numbers": [
    "+447807127123"
  ],
  "asset_id": "num_3DNr8KIVDwMtQKYtYvRtQCXbc5x",
  "channel": "SMS"
}

Sample responses

{
  "total_submitted": 2,
  "total_succeeded": 2,
  "total_failed": 0,
  "items": [
    {
      "number": "+447807127121",
      "status": "success",
      "message": "Opt-out entry deleted successfully"
    },
    {
      "number": "+447807127122",
      "status": "success",
      "message": "Opt-out entry deleted successfully"
    }
  ]
}
{
  "total_submitted": 1,
  "total_succeeded": 0,
  "total_failed": 1,
  "items": [
    {
      "number": "+447807127123",
      "status": "failure",
      "message": "Number not found on SMS channel"
    }
  ]
}
{
  "total_submitted": 1,
  "total_succeeded": 0,
  "total_failed": 1,
  "items": [
    {
      "number": "+447807127123",
      "status": "failure",
      "message": "Number not found for the specified SMS asset"
    }
  ]
}
{
  "total_submitted": 1,
  "total_succeeded": 0,
  "total_failed": 1,
  "items": [
    {
      "number": "+447807127123a",
      "status": "failure",
      "message": "Invalid phone number. Number must be in E.164 format."
    }
  ]
}
{
  "trace_id": "no-trace-id",
  "code": "ERR_CNT_VAL_001",
  "error": "MISSING_REQUIRED_FIELD",
  "message": "Required field 'numbers' is missing",
  "status": 400,
  "timestamp": "2026-05-28T15:43:26.377057543Z",
  "validation_errors": [
    {
      "field": "numbers",
      "message": "The numbers list must not be empty",
      "rejected_value": null
    }
  ]
}
{
  "trace_id": "no-trace-id",
  "code": "ERR_CNT_VAL_001",
  "error": "VALIDATION_ERROR",
  "message": "Channel mismatch: the specified asset does not match the requested channel",
  "status": 400,
  "timestamp": "2026-05-28T15:43:49.984931494Z",
  "validation_errors": null
}
{
  "trace_id": "no-trace-id",
  "code": "ERR_CNT_REQ_002",
  "error": "INVALID_REQUEST_BODY",
  "message": "Invalid or malformed request body. Please check your JSON format and ensure all required fields are provided.",
  "status": 400,
  "timestamp": "2026-05-28T15:44:24.687216601Z",
  "validation_errors": null
}