Skip to content
WbizTool

API v2 (beta)

Opt-outs

An opt-out is a person who doesn't want your workspace's messages. Nothing is ever sent to an opted-out number: a new message to it is refused, and messages queued earlier fail with the error Opted out instead of going out. It works for every way you send: the API (v1 and v2), the dashboard, campaigns, template messages, reminders, Google Sheets and Shopify.

The list is the same as the Opted out tab of Contacts in the dashboard.

OperationEndpointScope
Opt a number outPOST /api/v2/opt-outscontacts
List opt-outsGET /api/v2/opt-outscontacts
Get an opt-outGET /api/v2/opt-outs/{phone}contacts
Opt a number back inDELETE /api/v2/opt-outs/{phone}contacts

STOP replies are added for you#

When someone replies to one of your inbox numbers with a message that is only an opt-out word, they're opted out by themselves, with source reply and their message as keyword. A message that is only START (or Subscribe) opts them back in.

  • The words, in any capitals and with or without punctuation: STOP, Stop all, Unsubscribe, Opt out, Baja, Parar, Sair, Stopp, Abmelden, Arrêt, Désabonner, Basta, Disiscrivi, Стоп, Отписаться, Berhenti, Dur, توقف, إلغاء الاشتراك, עצור, הסר.
  • Only a message that is just the word counts: "please stop sending me the price list" doesn't opt anyone out.
  • It needs the inbox on the number they reply to, because only inbox numbers read incoming messages. Replies older than 7 days, such as those read when an inbox number is added, don't count.
  • Nothing is sent back to them, and no auto-reply answers the STOP.

Opt a number out#

POSThttps://wbiztool.com/api/v2/opt-outs

Body: JSON (application/json)

Body

phonestringrequired

The number in international format with + (+919876543210). Spaces, dashes and brackets are ignored. A Telegram @username works too.

notestringoptional

Why, for your team, up to 200 characters. Shown on the Opted out tab.

curl -X POST https://wbiztool.com/api/v2/opt-outs \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phone": "+919876543210", "note": "Asked by email"}'

Answer: 201 with the opt-out. A number that had opted out already answers 200 with its existing entry, unchanged.

{
  "recipient": "+919876543210",
  "source": "api",
  "keyword": null,
  "note": "Asked by email",
  "created_at": "2026-10-26T09:12:03.120Z"
}

Errors#

HTTPCodeWhen
400validation_failednote isn't text or is longer than 200 characters
422invalid_phonephone is missing or isn't a phone number

List opt-outs#

GEThttps://wbiztool.com/api/v2/opt-outs

Everyone who opted out, newest first, in pages (limit 1 to 100, default 25, and cursor). Add phone to look up one number.

curl "https://wbiztool.com/api/v2/opt-outs?limit=100" \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY"
{
  "data": [
    { "recipient": "+919876543210", "source": "reply", "keyword": "STOP", "note": null, "created_at": "2026-10-26T09:12:03.120Z" }
  ],
  "next_cursor": null
}

Get an opt-out#

GEThttps://wbiztool.com/api/v2/opt-outs/{phone}

The number in the address in international format without + (919876543210). Answers 404 opt_out_not_found when the number hasn't opted out, so it's a quick check before you send.

curl https://wbiztool.com/api/v2/opt-outs/919876543210 \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY"

Opt a number back in#

DELETEhttps://wbiztool.com/api/v2/opt-outs/{phone}

Messages to the number go out again from now on. Messages that already failed as Opted out stay failed. Only do this when the person asked for your messages again.

curl -X DELETE https://wbiztool.com/api/v2/opt-outs/919876543210 \
  -H "Authorization: Bearer $WBIZTOOL_API_KEY"
{ "recipient": "+919876543210", "deleted": true }

A number that hadn't opted out answers 404 opt_out_not_found.

Sending to an opted-out number#

  • POST /messages answers 422 recipient_opted_out, and nothing is queued. In a batch, the whole batch is refused and the error's field names the entry.
  • A message queued before the person opted out fails with error Opted out when its turn comes, and a webhook gets message.failed.
  • API v1 queues the message and it fails with Opted out, as you'll see in message status.
  • Campaigns' Retry failed skips these messages.

The opt-out object#

FieldTypeWhat it is
recipientstring+ and the number, or a Telegram @username
sourcestringreply: they replied STOP to an inbox number. dashboard: added on Contacts. import: from a CSV on Contacts. api: this API
keywordstring or nullThe reply that opted them out, as they wrote it
notestring or nullYour team's note
created_atstringWhen they opted out (ISO 8601, UTC)