Opt-outs & consent
How Beep suppresses opted-out recipients and how to manage consent programmatically.
Recipients can revoke consent to be texted at any time, and senders are obligated to honor it (TCPA and carrier rules). Beep enforces this for you: opted-out recipients are suppressed at send time, never delivered, and recorded so the outcome is auditable. This is operational guidance, not legal advice.
The two-level model
A send is suppressed if either condition holds:
| Level | Suppressed when | Scope |
|---|---|---|
| Person | The linked person is opted out | Covers every number linked to that person — current and future-linked |
| Endpoint | The specific number/endpoint is opted out | That one number only |
Person-level takes precedence, so a person who opts out stays suppressed across all of their numbers even as new ones are linked.
How recipients opt out
Recipients manage their own consent over SMS. Replying STOP (and standard synonyms) opts the recipient out automatically and suppresses future sends; replying START re-subscribes. No API call is required — Beep applies these inbound keywords for you.
Managing consent programmatically
Use POST /api/v1/opt-outs to apply opt-outs or opt-ins in bulk — up to 1000 entries per request. Each entry is keyed by phone_number or by { external_id, source_system }, with an explicit action of opt_out or opt_in. Applies are idempotent (repeating an action is a no-op), and each entry returns an independent result so one bad entry never fails the batch.
curl -X POST https://api.example.com/api/v1/opt-outs \
-H "Authorization: Bearer beep_live_..." \
-H "Content-Type: application/json" \
-d '{
"entries": [
{ "phone_number": "+15555550123", "action": "opt_out" },
{ "external_id": "a1b2c3d4-0000-0000-0000-000000000000", "source_system": "salesforce", "action": "opt_in" }
]
}'{
"total": 2,
"results": [
{ "status": "ok", "action": "opt_out", "phone_number": "+15555550123" },
{
"status": "error",
"action": "opt_in",
"external_id": "a1b2c3d4-0000-0000-0000-000000000000",
"error": "not_found"
}
]
}Per-entry error codes are not_found, ambiguous_external_id, and invalid_entry. See the Opt-Outs API reference for the full request and response schema.
Sending to an opted-out recipient
When you call POST /api/v1/messages for a suppressed recipient, that item comes back with status: "suppressed" instead of "queued". A terminal message row is recorded with error_code: "opted_out" and is retrievable via GET /api/v1/messages/{id}. The message is never delivered. If a status callback URL is configured, Beep also sends a failed event carrying error_code: "opted_out".
Resuming
Opting a recipient back in clears suppression — either by the recipient replying START, or by an opt_in action through POST /api/v1/opt-outs. Subsequent sends to that recipient return queued again.
One limitation
Person-level suppression applies to the numbers linked to a person at send time. A brand-new number that is not yet attributable to a known person is treated as new until it is linked, at which point the person's opt-out begins covering it.
Updated 3 months ago