Skip to main content

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.

Cold outbound is your responsibility at the REST layer

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.

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.

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 :phone path parameter must be URL-encoded E.164 (for example %2B15551234567 for +15551234567).
  • The body must include confirm_written_consent: true; without it the endpoint returns 400.
  • 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"
}
  • DELETE /api/v1/leads/:id is a soft delete: it sets status=opted_out and opted_out_at, and the row is preserved so TCPA records persist.
  • The sms.received webhook payload includes an is_opt_out flag on inbound messages; campaign stats track opt_outs per campaign.