TLDR:
30908 privacy policy can't be verifiedis almost never about your privacy page wording. It's about whether a human vetter can physically reach your opt-in flow and see the policy at the point of consent.
What We Built
I shipped a real-time labor and delivery SMS notification app in one autonomous session — a Next.js app that sends real-time SMS updates to family during labor and delivery.
The SMS layer is standard A2P stuff: Twilio (the cloud messaging platform), webhooks, STOP/START inbound sync. Phase 4 was the full engine. By June 18 it was wired and deployed.
Next step: 10DLC campaign registration — the US carrier requirement that every business sending SMS must complete or your messages get blocked.
The Rejection
Three errors. All at once.
30886— campaign description too thin/generic30893— sample message content invalid30908— privacy policy can't be verified
My immediate read on 30908? The privacy page wording is wrong.
It wasn't.
The /privacy page was live. It was real — what data we collect, that we don't sell it, that it's not used for marketing. The URL was linked in the submission. I rewrote the wording. Resubmitted.
Rejected again.
The Actual Problem
Here's what I didn't understand until I sat with it: 30908 is almost never about your privacy page text.
It's about whether the vetter — an actual human being — can reach your opt-in/consent flow and verify the privacy disclosure at the moment of signup.
Our recipient signup was gated behind a per-event invite token and a password. The vetter couldn't get in. Couldn't see the opt-in. Couldn't verify the policy at the point of consent.
So… rewriting the page? Totally the wrong fix.
The real fix: build a public /messaging program page — always reachable, no login, no token — with the program description, who sends, what they'll receive, and the opt-in language. Something any carrier rep (or any recipient) can read at any time.
The Other Two
30886 — thin description.
"Sends birth updates to family" is not a campaign description, apparently. The fix: name who sends, who receives, why, that it's NOT marketing, and link the public program page. Be explicit enough that a stranger with no context understands the use case.
30893 — sample content.
This one was subtle, and honestly kind of painful.
I had prefixed every outbound SMS with Baby [Last Name]: — warm, personal, exactly right for the moment.
Carriers read that as person-to-person traffic. Not A2P. Rejected under 30893.
The rule: samples must self-identify the registered program name, and they must match your real outbound byte-for-byte. Don't add a Reply STOP footer in the submission if your code never sends one.
Before:
Baby [Last Name]: She's in active labor! Updates coming soon. 💙
After:
Birth Updates [Program Name]: Active labor has started! Updates coming. Reply STOP to opt out.
It's a different feel. But it's what passes.
Why This Matters
Every builder I've seen hit 30908 chases the fix in the wrong place — rewrites the privacy policy, reformats the bullets, swaps "will not" for "never."
That's not the problem.
The question isn't "does my policy say the right things?"
It's: "Can the vetter walk through my opt-in flow, unauthenticated, and see my privacy disclosure at the exact point of consent?"
If that flow is token-gated or password-locked — they can't. And you'll keep getting rejected no matter how good the wording is.
Build the public program page. Make the opt-in path reachable without authentication. Prefix your SMS with the registered program name. Write the campaign description for a stranger.
That's the whole fix.