TCPA & Opt-Outs
AutoRev enforces TCPA opt-out rules server-side on every outbound SMS. This page covers what is enforced automatically, what remains your responsibility, and the endpoints for viewing and managing the opt-out list.
Opt-out enforcement on every send
Every outbound send checks the tenant's opt-out list automatically; no additional client-side check is needed. If the recipient has texted STOP, the send returns 422 and you must skip that contact. Opt-outs cannot be overridden via the API: the customer must text START to re-subscribe (or an admin can opt them back in with documented written consent, see below).
This applies to every send path: POST /api/v1/receptionists/:id/sms, POST /api/v1/sms/send, POST /api/v1/conversations/:id/reply, SMS campaigns, drip campaigns, and nurture campaigns.
Inbound STOP processing is what places a conversation into the opted_out state; it cannot be set via PATCH /api/v1/conversations/:id.
Opt-out enforcement is automatic, but prior-relationship gating is not. Direct REST endpoints do not check whether a contact has a prior relationship with the tenant; if you drive outbound with an AI agent, the agent must gate cold outbound itself. The MCP tool layer does enforce prior-contact. See TCPA rules for agents.
Consent capture on contacts
POST /api/v1/contacts is consent-gated: consent_acknowledged: true is required, and omitting it or setting it to false returns 422. The audit trail is written to custom_fields.consent for TCPA traceability, logging captured_at and captured_by.
Setting consent_acknowledged: true without actual prior consent from the contact is a compliance violation. The API trusts the caller but records the audit trail.
Daily send caps
Outbound SMS is capped at 400 messages per tenant per day by default. Hit the cap? Contact support to bump it. Resuming a paused campaign still respects the daily cap, and messages already in-flight when you pause a campaign are not recalled.
Compliance footer
The compliance footer on outbound messages cannot be suppressed via the public API.
Opt-out endpoints
These endpoints let you view and manage the opt-out list programmatically. Opting a number back in is a TCPA-sensitive write and requires explicit written-consent confirmation.
List opted-out numbers
GET /api/v1/opt-outs lists opted-out numbers (paginated). Scope: read. Optional ?phone= filter (E.164; 10-digit US numbers auto-formatted).
GET /api/v1/opt-outs?limit=50&phone=%2B15551234567
{
"data": [
{
"id": "...",
"phone_number": "+15551234567",
"reason": "STOP",
"opted_out_at": "2026-04-01T12:34:56Z",
"opted_back_in_at": null
}
],
"has_more": false
}
Manually opt out a number
POST /api/v1/opt-outs manually opts out a phone number. Scope: write_crm. Idempotent: if the phone is already on the active opt-out list, it returns the existing row with already_opted_out: true and status 200 (a new opt-out returns 201).
{
"phone": "+15551234567",
"reason": "manual - customer requested"
}
{
"id": "...",
"phone_number": "+15551234567",
"reason": "manual - customer requested",
"source": "api",
"opted_out_at": "2026-04-20T14:30:00Z",
"already_opted_out": false
}
Opt a number back in
DELETE /api/v1/opt-outs/:phone opts a phone back in. Scope: admin.
Requirements:
- The
:phonepath parameter must be URL-encoded E.164 (for example%2B15551234567for+15551234567). - The body must include
confirm_written_consent: true; without it the endpoint returns400. - Provide a
consent_reference(for example a signed-form ID or URL); it is recorded for TCPA audit trails.
DELETE /api/v1/opt-outs/%2B15551234567
Authorization: Bearer ar_live_...
Content-Type: application/json
{
"confirm_written_consent": true,
"consent_reference": "signed-form-2026-04-20-abc123"
}
{
"id": "...",
"phone_number": "+15551234567",
"opted_back_in_at": "2026-04-20T14:30:00Z",
"already_opted_back_in": false,
"consent_reference": "signed-form-2026-04-20-abc123"
}
Related behavior
DELETE /api/v1/leads/:idis a soft delete: it setsstatus=opted_outandopted_out_at, and the row is preserved so TCPA records persist.- The
sms.receivedwebhook payload includes anis_opt_outflag on inbound messages; campaign stats trackopt_outsper campaign.