STOP and nothing else. Other wording, such as “please stop”, does nothing by itself: read the reply and opt them out with the API. See Plans for which numbers are Dedicated.
Opt out a contact
POST /v1/contacts/{contact_id}/suppress opts out the contact’s phone number, or their email if they have no phone number. reason is optional (up to 500 characters) and is stored with the opt-out. The body can be empty.
curl
Response (200)
opted_out_at and opted_out_source appear only while the contact is opted out. opted_out_source says how the opt-out was made:
Opting out a contact that is already opted out succeeds again and returns the contact.
Opt out an address
To opt out a phone number or email that may not belong to a contact yet, usePOST /v1/contacts/suppressions with the address. Use this when you import a do-not-contact list from another system.
curl
Response (200)
address must be a US phone number in any accepted format (see Contacts) or an email address; anything else returns 400 VALIDATION_ERROR. If the address belongs to a contact, that contact shows opted_out: true. Opting out an address that is already opted out succeeds again.
Handle RECIPIENT_SUPPRESSED
A send to someone who has opted out returns403 RECIPIENT_SUPPRESSED before anything is queued:
POST /v1/chatschecks every recipient into.POST /v1/chats/{chat_id}/messageschecks the person in a direct chat, and everyone currently in a group chat. One opted-out participant blocks sends to the whole group.
no_op_reason: "contact_opted_out". See Workflows.
Check opt-out status
Every contact you read includesopted_out and messaging_allowed. Check them with GET /v1/contacts/{contact_id}, or look a person up by phone number or email with GET /v1/contacts/search, before you send. See Contacts.
There is no webhook for opt-outs yet, so an integration that mirrors opt-outs into its own system has to poll. Read the contacts you care about and watch opted_out; opted_out_source: "inbound_stop" tells you the person texted STOP.
Remove an opt-out
POST /v1/contacts/{contact_id}/unsuppress removes the contact’s opt-out and returns the contact with opted_out: false. Only do this when the person has agreed to hear from you again.
curl
unsuppress.
Keep opt-outs when contacts are deleted
Opt-outs belong to the phone number or email address, not to the contact record. When you delete an opted-out contact withDELETE /v1/contacts/{contact_id}, the opt-out stays. If you later create a contact with the same phone number, it starts out with opted_out: true, and sends to that number are still rejected.
Limitations
- No webhook for opt-outs.
contact.suppressedandcontact.unsuppressedexist in the schema but return400FEATURE_NOT_ENABLEDon subscribe. Pollopted_out. - No endpoint lists opt-outs, and
GET /v1/contactscan’t filter byopted_out. Keep your own list from the responses you get, or read contacts one by one. - Automatic STOP handling applies to Dedicated numbers and to the exact text
STOPonly. Free Plan and AI Agent numbers, and any other wording, need you to opt the person out. - An opt-out on an address with no contact can only be lifted by creating the contact first.
- An opt-out blocks the whole group:
403RECIPIENT_SUPPRESSEDon every send to a group that contains an opted-out participant.
Next steps
Contacts
Create, find and update the people you message.
Sending rules
Who you can message on each plan.
Group chats
Manage who is in a group before you send to it.
Errors
See every error code and how to fix it.