Deliverability

Why your texts aren't delivering

If your reply rate fell off a cliff and your list and script didn't change, you're being filtered — and the evidence is in your delivery report, not your gut. Filtering is a reputation decision made about your number, your content and your registration. Here's how to read the evidence, what actually triggers it, and what to change.

Keith PeikerKeith PeikerPublished August 20, 2026 · 18 min read

Key takeaways

  • Diagnose first: error 30007 means a carrier blocked you as spam. Codes 30003, 30005 and 30006 mean the phone was off, disconnected, or a landline — that's a list problem, not a reputation problem.
  • The nastiest case reports as "delivered." A "delivered" status means the carrier accepted the message, not that a phone lit up. Delivery rate holding while reply rate collapses is the signature of silent filtering.
  • Six triggers do most of the damage: unregistered or mismatched traffic, identical blasts, public link shorteners, a climbing opt-out rate, spam-shaped content, and a list full of numbers that can't receive texts.
  • Don't grade yourself against a threshold you read online — nobody publishes one. Compare this send to your last three from the same number. The step change is the finding.
  • Buying a new number to escape a filter is the trap. Fresh history isn't good history, and spreading the same message across extra numbers is snowshoeing — explicitly against messaging policy and specifically watched for.

Is it carrier filtering, or is it just a bad number?

These are two completely different failures and they get confused constantly, because from the outside both look like "my text didn't arrive." One is a reputation judgment about you. The other is a phone that can't receive texts. Open the delivery report on your last send and read the error code on the undelivered rows — a short list of codes separates them.

US SMS delivery error codes as your platform reports them. Full definitions are in the messaging-platform docs linked at the bottom of this post.
What the delivery report saysWhat actually happenedWhat to do
Undelivered · 30007 — message filteredA carrier or your messaging platform blocked it as spam before it reached the handset.This is filtering. Work the trigger list below.
Undelivered · 30034 — unregistered numberThe number isn't registered for US A2P 10DLC. Carriers block unregistered long-code traffic outright.Finish brand and campaign registration. Nothing else you change matters until this clears.
Undelivered · 30032 — toll-free not verifiedYou're sending from a toll-free number that hasn't cleared toll-free verification.Submit verification, or move the traffic to a registered 10DLC number.
Undelivered · 30003 / 30005 / 30006Handset off or out of coverage, number disconnected, or it's a landline.List problem, not a reputation problem. Scrub those rows and stop re-texting them.
Failed · 21610That person sent a standard opt-out keyword, and your messaging provider is now refusing sends from that number to theirs.Never text them again. That's consent revoked, not a deliverability issue — and note the block only fires on the standard keywords, so a stop worded any other way never appears here at all.
Undelivered · 30022 / 30023You hit the throughput or daily cap your 10DLC registration allows.Pace the send. Not filtering — a capacity ceiling.

The worst case shows up as "delivered"

A "delivered" status means the downstream carrier accepted the message — not that a phone lit up. Some filtering happens after that acknowledgement, so a send can report near-perfect delivery and still reach almost nobody. The tell is the shape of the drop: delivery rate holds, reply rate collapses, and it happened between one send and the next without you touching the list or the script. Treat that as filtering until something else explains it.

Nobody sends you a letter about this. There is no notification, no strike count, no dashboard at the carrier where you can see your standing. That's the frustrating part and it's also why the diagnosis has to come from your own send data.

What actually triggers carrier filtering?

Six things do most of the damage. They're listed roughly in the order they turn out to be the real cause — start at the top, because the first one makes everything below it irrelevant.

1. Unregistered traffic — or traffic that doesn't match what you registered

US application-to-person traffic over 10-digit long codes runs through The Campaign Registry. You register a Brand — your business identity, checked against tax and business records — and a Campaign, which is your use case, your sample messages, and a description of how people end up on your list. Most registrants identify the brand with an EIN, but that isn't the only door: the registry runs a separate sole-proprietor brand type for individuals who genuinely have no tax ID, verified by a one-time code sent to a mobile number and capped at much lower sending limits. It is a narrower path, not a shortcut — if your business has an EIN, choosing sole proprietor is a rejection on its own. Since 2023 messages sent from unregistered US 10DLC numbers are blocked outright rather than merely throttled, and they come back as "message from an unregistered number." Toll-free numbers have their own gate: unverified toll-free traffic gets filtered the same way.

The subtler failure is a mismatch. Your campaign registration is a written description of what you send. If it was approved for one thing and your live traffic is something else — a customer-care registration carrying cold acquisition offers to a skip-traced file — the gap between the two is a signal. Register the use case you actually run, and put your real message wording in the samples. The whole submission, field by field, is in 10DLC registration, start to finish.

The signal: 30034 or 30032 on the undelivered rows, or a number that has never had one good send since you bought it.
The fix: finish registration before the first send, not after the first bad one.

2. The identical blast

The same message body, to thousands of numbers, from one number, inside a short window, to people who never asked — that is the most spam-shaped thing it is possible to do, and content-similarity detection has been good at catching it for a long time. It gets worse when the number is new: a line that has sent nothing all year and then sends four thousand identical messages on a Tuesday has told the filter everything it needs.

Two honest caveats. First, merge tokens are not a disguise — swapping a first name changes very little about a message's fingerprint. What actually changes the pattern is fewer recipients per identical body, genuinely different wording between batches, and a slower ramp on a new number. Second, do not solve it by spreading the blast across a pile of numbers. That's snowshoeing, it is explicitly forbidden by messaging policy, and it is exactly the pattern these systems were built to find.

The signal: the first big send from a number lands, the second one doesn't.
The fix: break the send into smaller batches with real wording differences, and ramp a new number over days rather than opening with your whole list.

Shared shortener domains — bit.ly, tinyurl and the rest — sit near the top of every filtering list, for two obvious reasons. Hiding a destination is what phishing does, and thousands of unrelated senders share that one domain's reputation, so you inherit whatever the worst of them did this morning. Twilio's own guidance on filtered messages calls out public shorteners specifically.

There's a second argument against the link that has nothing to do with filters: a cold first touch earns a reply by asking a question, not by sending someone traffic. If you do need a link later in the thread, put it on a domain you own so the reputation you're borrowing is your own.

The signal: messages with a link get 30007 while the same message without one goes through.
The fix: no link in the first message. Ever.

4. Your opt-out rate

Every STOP is a recorded negative signal, and opt-out rate is one of the earliest indicators that traffic isn't compliant. This is the structural problem with cold outreach: a skip-traced list generates a higher STOP rate than a list of past clients, which is precisely why cold senders get filtered first and hardest. It isn't unfair — it's the system working as designed.

The other half of this is complaints, which are worse than opt-outs. Any recipient can forward a message to 7726 — it spells SPAM on a keypad — and the content goes to an industry spam-reporting service and to their own carrier, feeding the filters directly. All major US carriers support it. A message that reads like a scam earns complaints; a message with an obvious, honored opt-out mostly earns opt-outs.

One thing to be clear about before you start counting STOPs: STOP is the keyword, not the boundary. The FCC's rules let a consumer revoke consent by any reasonable means, treat words like stop, quit, end, revoke, opt out, cancel and unsubscribe as reasonable per se, and bar a sender from designating one exclusive method of revoking (47 C.F.R. § 64.1200(a)(10)). So "take me off your list," "wrong number, don't text this again," and a one-line reply telling you to get lost can all be revocations — and none of them trip keyword blocking or show up in a STOP count. Somebody has to read the replies. For what it's worth about our own build: reitexter's inbound webhook auto-suppresses on a single-word reply of STOP or UNSUBSCRIBE, and that is the entire keyword list; anything longer or worded differently lands in the thread as an ordinary inbound message for a human to mark.

The signal: opt-out rate climbing send over send, with filtering arriving a campaign or two later. Deliverability-wise, the count that matters is opt-outs of every kind, not just the ones that tripped a keyword.
The fix: make the opt-out obvious in the first message, honor it immediately, and honor it permanently — across every number and every campaign, not just the one they replied to, and for the replies that mean stop without saying it. Hiding the exit doesn't keep people on your list, it converts opt-outs into complaints. What a stop has to do on your side is in what happens when someone replies STOP.

5. Content that reads like the corpus

Filters are trained on what spam has historically looked like, and cash-offer texting is unlucky here — the vocabulary of fast money overlaps hard with the loan, debt-relief and crypto spam these systems were built to stop. Stack the rest of the profile on top of it and you've written a training example: capital letters, an exclamation mark, a dollar figure, an emoji, a link, no sender name, and no stated reason for contacting this particular person.

Rewrite it so it reads like a person with a reason. Say who you are and what company you're with, say specifically why you're texting this number, ask one question, and give an out. That message also happens to be the one that gets replies, which is the entire point of sending it — the long version is in the first text to a motivated seller.

The signal: one message template gets filtered while a plainer one from the same number doesn't.
The fix: read your template out loud. If it sounds like a billboard, it will be treated like one.

6. A list that's mostly not textable

Skip-traced files carry landlines, disconnected numbers and plain wrong matches. Those come back as 30006, 30005 and 30003 — not filtering, but not harmless either. They cost you a credit each, they drag your delivery rate down so you can't see the real signal, and a stream of sends to numbers that can't receive texts is not what an established sender's traffic looks like.

The signal: a big block of 30005 and 30006 on every campaign, the same rows every month.
The fix: scrub before you send, then remove the dead rows after each campaign instead of paying to text them again next month.

How do you read your own delivery numbers?

Four numbers per send, all from the same sending number: delivery rate (delivered ÷ sent), filtered share (30007 rows ÷ sent), opt-out rate (STOPs ÷ delivered), and reply rate. That's the whole instrument panel.

Carriers do not publish filtering thresholds, so any specific percentage you find online was invented by whoever wrote the page. Don't grade yourself against a number — grade yourself against yourself. Line up your last three sends from the same number, same kind of list, same time of day. A step change between two of them is the finding; a single ugly campaign in isolation tells you almost nothing.

  • Delivery falls and 30007 climbs. Straightforward filtering on content or reputation. Change the message, cut the batch size, slow the ramp.
  • Delivery holds, reply rate collapses. Silent filtering, or your message genuinely got worse. Change one variable at a time — a plainer template to a small batch is the cheapest test there is.
  • Delivery holds, opt-out rate climbs. The list is wrong for the message, or the message is wrong for the list. Filtering is the next thing that happens; fix it while it's still just a bad reply rate.
  • Delivery falls but 30007 is near zero. Not filtering at all. Look at 30005 and 30006 — you're texting disconnected numbers and landlines, and that's list hygiene, not reputation.

You cannot do any of this if all your platform tells you is "sent." Full disclosure, reitexter is mine: every campaign breaks its send down into delivered, spam-blocked, opted-out and failed, so the diagnosis above takes about ten seconds instead of an export and a spreadsheet — and 10DLC brand and campaign registration is handled in the app rather than being a form you're told to go find somewhere else.

What to change this week

In order. The first item is not optional and nothing below it will save you if it isn't done. The second is the odd one out — it will not move your delivery rate by a single point, and it is on this list because a message that lands is not the same thing as a message you were allowed to send.

  1. Finish registration. Brand and campaign with The Campaign Registry for a 10DLC number, or toll-free verification for a toll-free one. If you're seeing 30034 or 30032, stop reading and go do this.
  2. Scrub against the do-not-call registries. Not a deliverability control — carriers do not consult the registry and a number with a spotless delivery record can still generate a claim. Access to the national registry is a subscription for sellers and telemarketers through the FTC's telemarketer portal, and the FCC's safe harbor for an inadvertent call is conditional on, among other things, using a version of the registry pulled no more than 31 days before the message goes out, which makes it a recurring job rather than a file you download once. A number of states run their own do-not-call lists and their own telemarketing statutes on top of the federal floor. This one is not something reitexter or any other texting platform does as a side effect of sending — it is a separate subscription and a separate step, and the detail is in what TCPA actually says about texting a skip-traced list.
  3. Make your traffic match the registration. The sample messages you submitted should look like the messages you actually send. If your use case changed, update the registration instead of hoping nobody compares.
  4. Take the link out of the first message. Especially a shortened one. Add links later in a thread, on a domain you own.
  5. Cut the batch size and ramp slowly. A new number opening with your entire list is the single most reliable way to burn it. Build up over days.
  6. Keep every message to one segment. Around 160 characters of plain text — no emoji, no smart quotes. Shorter reads better cold, and on a prepaid wallet a two-segment message costs exactly twice as much across the whole list.
  7. Enforce opt-outs everywhere, automatically. One STOP should suppress that person on every number, every campaign, every auto-reply, permanently — and because a revocation does not have to use the keyword, you also need a one-action way to mark the replies that mean stop without saying it. There are rules underneath this: an internal do-not-call list, requests honored within a reasonable time not to exceed ten business days, and the record kept for five years (47 C.F.R. § 64.1200(d)). A manual do-not-text list you remember to check is not a control.
  8. Scrub the list before and after. Drop the landlines and disconnects rather than paying to fail on them again next month.

First touch — one segment, no link, opt-out on the front page ({First name} is a merge field; the brackets are yours to fill in)

Hi {First name}, [your name] with [your company]. Are you open to an offer on [street]? Reply STOP to opt out.
Following up on [street] — still open to an offer, or should I close the file? [your name], [your company]. Reply STOP to opt out.

Change one thing at a time

If you rewrite the template, halve the batch, switch numbers and drop the link all in the same week, you'll get your delivery rate back and learn nothing about why you lost it. Move one variable per send and write down what happened. Three sends of patience buys you a diagnosis you can reuse for years.

Can a filtered number recover, or do you need a new one?

It can recover, you almost certainly don't need a new one, and buying one is usually the move that makes it worse.

Reputation is built out of recent behaviour, so recent behaviour is what changes it. Fix the content, cut the batch size, honor opt-outs, drop the dead rows, and the number's recent history stops looking like the thing that got it flagged. There's no reset button and no appeal you file with a carrier yourself — the escalation path runs through your messaging provider, which is why the documented advice for a persistent 30007 is to collect several message IDs from the undelivered sends and hand them to support for a compliance review.

Buying a new number to dodge a filter is the trap

A fresh number has no history, which is not the same thing as good history — the same content gets filtered again, and faster, because a brand-new line sending a large identical batch is itself the pattern. Spreading similar messages across extra numbers to dilute the damage has a name, snowshoeing, and it's explicitly against messaging policy and specifically targeted for filtering. If you're being filtered, the number is the symptom. The content, the registration and the list are the disease.

One more thing worth saying plainly, because it's the part most deliverability advice skips: carrier filtering and the law are two separate systems with two separate enforcers, and clearing one has never cleared the other. Filtering is a private business decision made by carriers and your provider, with no notice and no appeal. The TCPA and the FCC's rules are enforced by regulators and by private plaintiffs, and they do not care what your delivery rate looks like. A number that delivers at 98% can still be generating claims, and a message that gets filtered was not thereby illegal.

For a skip-traced list, the rules people actually get caught by are worth knowing in outline. The national Do Not Call rule at 47 U.S.C. § 227(c) has no equipment element at all, so it reaches a message you typed with your thumbs, and the FCC's rules apply both the registry restriction and the internal do-not-call requirements to text messages sent to wireless numbers. Separately, 47 C.F.R. § 64.1200(d) requires anyone making telephone solicitations to run their own do-not-call list — written procedures, trained people, a request honored within a reasonable time not to exceed ten business days, the record kept five years, and the caller's name, the company's name and a way to reach the company in the message. Whether an unsolicited offer to buy somebody's house is a "telephone solicitation" in the first place is genuinely contested and depends on how your funnel makes money, and a number of states run their own statutes and their own lists on top of the federal floor. The citations, case by case, are in what TCPA actually says about texting a skip-traced list.

I am not a lawyer, and this is not legal advice

This post is about deliverability — how carriers decide, and how to read your own send data. Where it touches the rules it is describing them, not applying them to your list, and every source is linked at the bottom. Cold outreach to a skip-traced file is exactly the fact pattern where the answers turn on your state, where the list came from, and how your business makes money on a "no." Have a lawyer who does this work read your specific campaign before you scale it, not after.

I grew my own company past $500k in its first twelve months on about $3,600 a year of text messages, and none of that worked because I found a clever way around a filter. It worked because the messages read like a person who had a reason to be texting, and because I stopped texting anyone who told me to stop. Deliverability is mostly that, written down.

Frequently asked questions

Why do my texts say delivered but nobody replies?

A "delivered" status means the downstream carrier accepted the message, not that it appeared on a phone. Some filtering happens after that acknowledgement, so a campaign can report high delivery and still reach almost nobody. The signature is a delivery rate that holds while reply rate collapses between two sends you didn't change. Test it by sending a plainer, link-free version of the same message to a small batch and comparing replies.

What does error 30007 mean on a text message?

30007 is "message filtered" — the message was accepted and submitted downstream, then blocked before reaching the handset, either by a wireless carrier's spam filtering or by your messaging platform's own policy enforcement. It is a reputation and content verdict, not a bad phone number. Twilio's guidance for messages you believe are compliant is to gather three or more message IDs from undelivered 30007 sends and take them to support for review.

Do link shorteners get text messages blocked?

Public, shared shorteners like bit.ly and tinyurl are among the most heavily filtered elements you can put in a message, because obscuring a destination is a phishing pattern and because thousands of unrelated senders share that domain's reputation. Guidance on preventing filtered messages calls them out specifically. Leave links out of a cold first touch entirely, and when you do need one later in the conversation, host it on a domain you own.

Will buying a new phone number fix carrier filtering?

Usually not, and it often makes things worse. A new number has no history rather than good history, so the same content gets filtered again — and a brand-new line sending a large identical batch is itself a suspicious pattern. Spreading similar messages across multiple numbers to dilute filtering is called snowshoeing and is explicitly forbidden by messaging policy and targeted for filtering. Fix the content, the registration and the list instead.

How high can my opt-out rate be before carriers filter me?

Carriers do not publish a threshold, and any exact percentage you see quoted was invented by the person quoting it. Opt-out rate is a known early indicator of non-compliant traffic, so what matters is your own trend: compare your last three sends from the same number against the same kind of list. A step change is the warning. Cold lists naturally run a higher opt-out rate than warm ones, which is exactly why cold senders get filtered first.

Is 10DLC registration actually required, or can I just send?

It's required in practice. Messages sent to US numbers from unregistered 10-digit long codes are blocked rather than throttled, returning an unregistered-number error, and unverified toll-free traffic is filtered the same way. Registration goes through The Campaign Registry: a brand record checked against tax and business records — usually identified by an EIN, though the registry also has a sole-proprietor brand type for individuals who have no tax ID, verified by a one-time code to a mobile number and capped at much lower sending limits — and a campaign record describing your use case, sample messages and how people join your list.

Keith Peiker

Keith Peiker

Founder, reitexter

Founder of reitexter. Grew his own company from zero to $500k+ in 12 months on about $3,600 a year of text messages — then built the software for everyone else working a list of phone numbers.

More about Keith

Keep reading

Texts that actually land

reitexter is texting and calling for real-estate wholesalers and agents. 10DLC and toll-free registration handled in the app, one suppression list checked automatically by every campaign, bulk send and automated text, and a delivered / spam-blocked / opted-out breakdown on every campaign. Plans from $99.99/mo.

See pricing