Compliance
The rules you cannot design around.
Messaging is a permission channel. The requirements are not onerous, but they are load-bearing — and every one of them also happens to be good practice that improves your results.
Not legal advice. This is the operational shape of the problem so you know what to ask a lawyer about. Rules vary by jurisdiction and change over time.
The checklist
Ten things to have in place before your first customer send
If you can tick all ten, you are in better shape than most businesses many times your size.
- 01
Capture consent explicitly
Its own unticked checkbox, clear language beside it, never a condition of purchase, never buried in a terms link.
- 02
Separate marketing from transactional
Two scopes, stored separately. Someone who wants delivery updates has not agreed to a coupon blast.
- 03
Store proof, not just a boolean
Timestamp, exact disclosure wording, source form, IP or staff member, and every subsequent status change.
- 04
Automate STOP before your first send
STOP, UNSUBSCRIBE, CANCEL, END, QUIT — all of them, instantly, with no human in the loop.
- 05
Answer HELP
Business name, a way to reach a human, and opt-out instructions. It is required and it is cheap to build.
- 06
Identify yourself
Name the business in the first message of any conversation. An unidentified text is a deleted text.
- 07
Respect local quiet hours
8am to 9pm in the recipient's time zone, not your server's. Queue messages outside the window; never drop them.
- 08
Cap frequency at the send layer
Enforced centrally, not per campaign — otherwise three well-behaved campaigns become one bad week.
- 09
Register your traffic
US business SMS on 10-digit numbers needs carrier registration. Unregistered traffic gets filtered or blocked outright.
- 10
Own the opt-out list
In your database, not only in a vendor dashboard. Switching providers must not resurrect people who unsubscribed.
Consent
Two levels, and the gap between them is where trouble lives
Most compliance failures at small businesses are not deliberate. They are a marketing message sent to a list that only ever consented to transactional ones.
Transactional
Express consent
The customer is expecting this message because of something they did — booked, ordered, or asked. Appointment reminders, order confirmations, delivery notices, invoice due dates.
Generally sufficient: they gave you the number for this purpose.
Marketing
Express written consent
Offers, promotions, win-backs, announcements. In the US this requires an explicit, provable, written agreement to receive marketing texts at that number.
An existing business relationship is not consent. A number on an invoice is not consent.
The buried-checkbox trap
Consent to marketing texts cannot be a condition of buying something, cannot be pre-ticked, and cannot be hidden inside a terms link. It needs its own unticked checkbox with clear language next to it. This is the single most common way small businesses end up out of compliance without ever intending to.
In your codebase
Two things to build first
Opt-out handling and a consent record you own. Everything else can wait; these cannot.
const STOP_WORDS = new Set([ "stop", "stopall", "unsubscribe", "cancel", "end", "quit", "revoke", "optout",]); export async function handleInbound(from: string, text: string) { const first = text.trim().toLowerCase().split(/\s+/)[0]; if (STOP_WORDS.has(first)) { await optOut(from); // persist BEFORE replying await send(from, "You're unsubscribed. No more messages from Acme."); return; } if (first === "help") { await send(from, "Acme support: (555) 010-0000. Reply STOP to unsubscribe."); return; } await routeToInbox(from, text);}// This outlives every vendor you will ever use. Keep it yours.type ConsentRecord = { phone: string; // E.164, always status: "opted_in" | "opted_out" | "unknown"; scope: "marketing" | "transactional" | "both"; capturedAt: string; // ISO 8601 source: string; // which form, which page, which staff member disclosureText: string; // the exact words they agreed to ip?: string; history: { at: string; event: "opt_in" | "opt_out" | "scope_change"; channel: "web" | "sms" | "in_person"; }[];};The compliance dividend
Clean lists engage better, get fewer spam reports, and keep healthier sender reputation with carriers. Businesses that do this properly get better numbers, not just safer ones — a filtered message is worth exactly zero.
Carrier filtering
The rules nobody tells you about, enforced silently
SMS filtering happens at the carrier, before delivery, with no bounce and no appeal. Your API call returns success and the message simply never arrives.
Register your traffic
US business SMS on standard 10-digit numbers requires registration tying your traffic to a verified business. Unregistered traffic is heavily filtered. Start it early — approval is not instant.
Never use a public shortener
Shared shortener domains carry every spammer's reputation alongside yours. Use a branded short domain on a domain you own. This is the highest-impact single change available.
Write like a person
No ALL CAPS, no rows of exclamation marks, no $$$. One link per message. Identify your business. Vary at least the name across a bulk send.
Go deeper
Two guides cover the operational detail
Consent capture and opt-out handling in one; timing, frequency caps and the opt-out rate you should be watching in the other.