Skip to content

SMS Compliance Audit

CleanerHQ — TCPA & SMS Compliance Audit Report

Complete documentation of SMS consent collection, opt-out handling, and compliance controls
Generated: March 19, 2026  |  Platform: app.cleanerhq.com  |  SMS Provider: Twilio

1. Overview

CleanerHQ is a vertical SaaS platform for the cleaning industry — a complete Quote-to-Cash operating system. The platform sends transactional SMS notifications to cleaning business customers and staff.

SMS Message Types

Message TypeTriggerTemplate
Appointment ReminderDay before scheduled jobjob_reminder
“On My Way” AlertCrew starts traveling to jobon_my_way
Job CompletionJob marked as completedjob_completed
Invoice Payment ReminderInvoice past dueinvoice_reminder
Booking ConfirmationQuote converted to jobbooking_confirmation
Schedule ChangeJob rescheduled or cancelledschedule_change_*
Review RequestPost-service follow-upreview_request
Running LateCrew reports delayrunning_late

All messages are transactional (not marketing). Message frequency: typically 2–6 per service visit, up to 20 per month per phone number (hard cap enforced).

4. Admin Controls — SMS Settings Dashboard

Workspace owners have a dedicated SMS settings page at /settings/sms with 4 management sections:

SMS Settings page showing SMS Feature Status and Monthly SMS Budget sections
Screenshot: SMS Settings page (top) — SMS Feature Status badge showing “Enabled” and Monthly SMS Budget card showing default $50/month limit.
SMS Settings page showing TCPA consent language preview and Opt-Out Registry
Screenshot: SMS Settings page (bottom) — TCPA-compliant consent language preview (read-only, cannot be modified) and Opt-Out Registry showing opted-out phone numbers.
SectionPurpose
SMS Feature StatusShows whether SMS is enabled/disabled for the workspace. Links to Company Settings to toggle.
Monthly SMS BudgetSpend vs. limit with progress bar. Alert when approaching threshold. Default: $50/month.
SMS Consent LanguageRead-only preview of TCPA-compliant consent text. Cannot be modified (regulatory requirement).
Opt-Out RegistryTable of all phone numbers that have opted out via STOP keyword. Read-only.

5. Opt-Out Handling

Keyword Processing

All inbound SMS messages are processed by the Twilio webhook at /api/webhooks/twilio/inbound with HMAC-SHA1 signature validation.

Keyword(s)ActionAuto-Reply
STOP, END, QUIT, UNSUBSCRIBEOpt-out: set sms_opt_outs.opted_out = true, revoke contacts.sms_consent for all matching contacts“You have been unsubscribed from CleanerHQ SMS notifications. You will not receive any more messages. Reply START to re-subscribe.”
START, YES, SUBSCRIBEOpt-in: set sms_opt_outs.opted_out = false“You have been re-subscribed to CleanerHQ SMS notifications. Reply STOP to opt out at any time.”
HELP, INFONo state change“CleanerHQ SMS notifications for your cleaning appointments. Reply STOP to opt out. For support, visit cleanerhq.com or email support@cleanerhq.com.”

All keywords are processed case-insensitively. Opt-outs are honored immediately — the opted-out phone number is checked before every SMS send.

6. Send-Time Compliance Checks

Every SMS message passes through a compliance pipeline before being sent. Implemented in lib/notifications/sms-sender.ts and lib/sms/twilio.ts.

CheckRuleFile
Consent Requiredcontacts.sms_consent === truesms-sender.ts
Opt-Out HonoredCheck sms_opt_outs.opted_out before every sendsms-sender.ts
Time Restrictions8:00 AM – 9:00 PM in recipient’s local timezonetime-restrictions.ts
STOP Footer“Reply STOP to opt out” appended to every messagemessage-footer.ts
Per-Phone CapMax 20 messages per phone number per monthtwilio.ts
Workspace BudgetChecked via checkSMSBudget() RPC, default $50/monthbudget.ts
Budget AlertAlert sent when spend reaches threshold (default 80%)budget.ts
Pipeline order: Opt-out check → Consent check → Time restriction check → Budget check → Per-phone cap check → Send via Twilio API → Log to sms_usage_log

7. Public SMS Consent Proof Page

A publicly accessible page at /sms-consent (no login required) documents all SMS consent collection flows for Twilio A2P 10DLC reviewers.

Public SMS Consent and Opt-In Disclosure page showing 3 consent collection flows
Screenshot: Public SMS Consent & Opt-In Disclosure page (top) — documents the 3 primary consent collection flows: booking widget, client portal, and CRM contact entry.
Public SMS Consent page showing TCPA disclosure text opt-out instructions and footer links
Screenshot: Public SMS Consent page (bottom) — full TCPA disclosure text, opt-out instructions (STOP/HELP), and footer links to Privacy Policy and Terms & Conditions.

URL: https://app.cleanerhq.com/sms-consent
Authentication: None required (publicly accessible)
Purpose: Twilio A2P 10DLC compliance reviewer verification

8. Backend Infrastructure Summary

Database Tables

TablePurposeKey Columns
contactsContact-level consent trackingsms_consent, sms_consent_date, sms_consent_method, sms_consent_ip_address
sms_opt_outsPhone-level opt-out registryphone_number, opted_out, opted_out_at, last_message_received
sms_budgetsWorkspace monthly budgetmonthly_limit_cents, current_month_spend_cents, alert_threshold_percent
sms_usage_logPer-message audit trailphone_number, direction, message_sid, template_id, cost_cents

Server Actions & API Routes

ComponentFileStatus
SMS sending (Twilio direct HTTP)lib/sms/twilio.tsComplete
16 SMS templateslib/sms/templates.tsComplete
STOP footer on all messageslib/sms/message-footer.tsComplete
TCPA 8AM–9PM time restrictionslib/sms/time-restrictions.tsComplete
Workspace SMS budget & capslib/sms/budget.tsComplete
Phone number normalizationlib/sms/utils.tsComplete
Opt-out keyword handlingapi/webhooks/twilio/inbound/route.tsComplete
Delivery status webhookapi/webhooks/twilio/status/route.tsComplete
Consent grant/revoke/checkapp/actions/sms-consent.tsComplete
Consent check before every sendlib/notifications/sms-sender.tsComplete
Per-phone monthly cap (20 msgs)lib/sms/twilio.tsComplete