← All guides

Operations deep-dive

Cannabis customer SMS — what carriers actually filter, what gets you blocked

Cannabis customer SMS is harder than regular retail SMS for three reasons stacked: (1) carrier filters (T-Mobile, Verizon, AT&T) block cannabis-keyword content aggressively under their A2P 10DLC enforcement; (2) WAC 314-55-155 caps the message content even before carriers see it; (3) operators routinely tank their sender reputation by leading with ‘$10 off!’ spam-bait copy. Most operators don’t notice until 40% of their messages stop landing. Here’s the discipline that keeps the channel open + the patterns that don’t trip filters.

By CannAgent6 min read

Why cannabis SMS is structurally hard

  • **A2P 10DLC carrier filters.** Every business SMS in the US since 2023 must register a 10-digit-long-code (10DLC) campaign with the carriers. Cannabis is on the ‘restricted’ list; carriers approve campaigns at lower rates + sample messages aggressively. Send the wrong content + your registered campaign gets paused, not just the message blocked.
  • **Cannabis-keyword filtering.** ‘THC,’ ‘flower,’ ‘edible,’ ‘ounce,’ ‘eighth’ — all soft-flagged. The combination of cannabis-keyword + discount-language + urgency-language is what carrier ML models score as spam. ANY ONE of those is fine; ALL THREE in one message and the deliverability rate drops to ~30%.
  • **WAC 314-55-155(2)(c) advertising scope.** Customer-facing SMS that promotes cannabis products IS advertising. The age-disclaimer + audience-restriction rules apply. We can’t SMS to a number we haven’t verified is a 21+ customer (loyalty enrollment establishes that; cold prospect lists don’t).
  • **Sender reputation compounding.** Once a number / shortcode hits a complaint threshold, ALL future messages from that sender get filtered harder. Recovery is months, not weeks. The discipline is preventing reputation damage, not recovering from it.

The 4 SMS types — and what works for each

TypeCarrier filter riskRecommended pattern
Transactional (order ready, account update)LowLead with action: ‘Order ready for pickup at the front desk.’ No order-ID in body (PII discipline per memory). No discount tail.
Loyalty milestone (anniversary, birthday)Low-midLead relational: ‘Hey Alex, been a year since your first visit. Stop by when you’re around.’ No price-bait. No urgency.
Promotional (new product, weekly deal)HighLead with the product, not the discount. &lsquo;New flower from <vendor> just landed; favorites of yours.&rsquo; No &lsquo;LIMITED TIME&rsquo; / no exclamation marks / no $-bait.
Re-engagement (haven&rsquo;t shopped in 60+ days)MidSoft check-in: &lsquo;Been a few weeks; everything good?&rsquo; Don&rsquo;t lead with points-balance reminder (per memory: that pushes redemption + converts soft liability to hard discount).

Pattern-level rules we run

  • **One short, one URL, one CTA.** Carrier ML models score multi-link / multi-CTA SMS as spam. Single link → /menu OR /pickup, NEVER both.
  • **Name the customer.** Per the named-customer-beat operator pattern: &lsquo;Hey Alex&rsquo; > &lsquo;Hey there.&rsquo; First names only; we never use last names in SMS body. Ungendered.
  • **No exclamation marks.** Carrier filters score them as spam-bait. The voice-rule from /docs/brand-voice.md applies to SMS verbatim.
  • **No price in the body.** &lsquo;Save $10&rsquo; / &lsquo;30% off&rsquo; / &lsquo;BOGO&rsquo; all trip filters. Mention the offer if relevant; don&rsquo;t structure the message around the price.
  • **Phone normalization at the lib boundary, not the call site.** Per the operator pattern: lib/sms.ts sendSms() calls normalizeToE164() internally. Don&rsquo;t pre-normalize at call sites; centralized + idempotent.
  • **Quiet hours.** No SMS before 9 AM or after 8 PM in the customer&rsquo;s tz. Carrier complaint rates spike outside that window.
  • **Hard-stop on STOP.** Customer replies STOP → no more SMS to that number, period. Carrier rule + ethical floor + the unsubscribe page lives at /unsubscribe.
  • **Cap frequency.** No more than 1 SMS per customer per 7-day window. Repeat sends compound carrier-filter risk + customer-irritation risk.

What we don&rsquo;t do

  • **No SMS to non-loyalty walk-ins.** Single-visit cash customers haven&rsquo;t opted in beyond the WAC 314-55 retail interaction. Their phone is on file (if at all) for ID-scan purposes only.
  • **No third-party SMS list rentals.** Doesn&rsquo;t prove 21+ verification; carrier-side complaint rate destroys sender reputation; WSLCB cite-able if they audit.
  • **No URLs to non-CannAgent / non-shop domains.** Off-domain links score as suspicious in carrier ML; brand confusion compounds.
  • **No emojis in cannabis SMS body.** Carrier ML treats heavy-emoji content as spam-marker. Plain text only.
  • **No order-ID in the customer SMS body.** Per the POS customer-display payload schema memory + the pickup-flow guide: order-IDs are operator-side; customer SMS just confirms readiness.

Takeaways

Ready to talk through your migration?

30-minute demo. We end by quoting the cutover from your current setup — fixed scope, no hourly games.