Workflow AutomationOperationsn8nSmall Business

Automated Texts Not Delivering? Count Segments, Not Sends

Automated text messages usually fail on carrier limits that are counted in message segments per registered business, shared across every phone number, campaign, and platform under the same EIN. Buying more numbers adds no capacity, and a single non-ASCII character in an AI-written message body cuts the segment size from 160 characters to 70, tripling what one reminder consumes.

Alexey YushkinFounder, GENERAL INFORMATICS3 min read

Automated text messages in the US stop reaching people because of limits counted in units nobody on the build side is tracking. The carrier cap is measured in message segments, not messages, and it is applied to your registered business entity rather than to a phone number, so it is shared across every number, every campaign, and every platform registered under the same EIN. Adding a second phone number buys no capacity at all. A single curly apostrophe in an AI-written reminder cuts the segment size from 160 characters to 70 and turns one message into three.

Most advice on this topic reads like email deliverability advice with the nouns swapped: register, get consent, avoid spam words, warm up the number. Registration is genuinely mandatory and worth doing first. It is also not what strands the appointment-reminder workflow that ran fine for four months and then started dropping a third of its sends on Tuesday afternoons.

Your send step reports success either way

An SMS send node returns what the messaging API said when it accepted the request. That is a queued or sent status. It means the provider took the message, not that a handset received it.

Everything that kills automated SMS happens after that point: registration checks, carrier spam filtering, per-brand daily caps, and opt-out blocks. Those results arrive on a status callback, a separate HTTP request the provider makes back to a URL you configure, carrying a final status of delivered, undelivered, or failed plus an error code. If your workflow never set that URL, and most workflows built in a hurry never do, the final status exists in the provider console and nowhere in your system. This is the same failure shape as automations that break without telling you, and it is why the first report is a customer saying they never got the reminder.

Wire the callback into a workflow that writes the error code against the record. Two fields, sms_status and sms_error_code, turn every diagnosis below into a filtered view instead of a support ticket.

The unit carriers count is the segment, not the message

This is the part that surprises people, and it matters more now that message bodies are being generated rather than typed.

A single SMS holds 160 characters when the text fits the GSM-7 alphabet. Go past that and the message is split, and each part carries a header, so the limit drops to 153 characters per segment. Include one character outside GSM-7 and the whole message switches to UCS-2 encoding, where a single segment is 70 characters and concatenated segments are 67 each.

One character. Not one word, not one emoji-heavy sentence. Twilio's own documentation calls out the specific trap: text editors silently convert straight quotes to curly quotes, and a curly quote is a UCS-2 character.

Message bodyEncodingCharactersSegments billed
Plain ASCII appointment reminderGSM-71391
Same text, it's written with a curly apostropheUCS-21393
Same text plus a check mark emojiUCS-21413
Plain reminder with a 24-character tracking link appendedGSM-71632

Three times the consumption of a daily cap, three times the per-message cost, from a character the operator cannot see in the workflow editor. There is a second version of the same trap inside GSM-7 itself: the characters [ ] { } \ ~ ^ | and the euro sign are encoded as two characters each, so a message body that formats a list with square brackets is longer than it looks.

Now add a model to the pipeline. If an LLM writes the reminder text, the body length and the character set change on every run, and models reach for typographic apostrophes, ellipsis characters, and en dashes because that is what good prose looks like in training data. You are handing a variable-length, variable-encoding string to a system that bills in fixed 70 or 160 character blocks. That is the same class of problem as any other non-deterministic model output feeding a downstream system, and it needs the same treatment: a deterministic gate after the model, not a better prompt.

Three rules that fix it:

Normalize the body in code before the send step. Replace curly quotes, en dashes, ellipsis characters, and non-breaking spaces with ASCII equivalents. It is a ten-line function and it is the only reliable version of this fix, because a prompt instruction to use plain ASCII holds most of the time, and most of the time is not a spec.

Count the segments and gate on the number. Compute the encoding and segment count before sending. If the result is more than two segments, truncate to a template or fall back to a fixed string. Never let a generated body reach the carrier without a length check.

Turn on your provider's encoding normalization if it has one. Twilio's Smart Encoding converts curly quotes back to straight ones on the way out. Treat it as a backstop, since it covers a fixed substitution list and a model can produce characters that are not on it.

The daily cap is per business, not per number

Here is the point that changes what you build.

Twilio's documentation for error 30023 states that the T-Mobile daily message cap applies per brand, meaning per EIN, and that it counts total outbound SMS segments and MMS messages sent to T-Mobile, including Sprint and MetroPCS, across any messaging platform where you have registered that brand. The day resets at 00:00 Pacific.

Read that carefully, because four separate assumptions die in one sentence.

The cap is not per phone number, so rotating across five numbers changes nothing. It is not per campaign, so splitting reminders and marketing into separate registered campaigns does not split the quota. It is not per platform, so moving half your volume to a second vendor and keeping the same EIN moves the traffic and not the ceiling. And because it counts segments rather than messages, the encoding problem above is a direct multiplier on the only number that matters.

Where you land in the cap tiers depends on your brand's trust score from the registration and vetting process. The published ceiling is 200,000 segments a day to T-Mobile, and going above it requires T-Mobile's Special Business Review. At the other end, as of August 2026 Twilio's sole proprietor path is limited to one message per second, a daily cap in the low thousands of segments across all carriers with a smaller sub-limit toward T-Mobile, and, per Twilio's registration documentation, exactly one 10DLC phone number attached to the campaign. Attach a second number to a sole proprietor campaign and sends from it fail with error 30034.

So the honest capacity math for a reminder workflow is: expected messages per day, times average segments per message, times the share of your customers on T-Mobile, checked against your brand's cap. Most operators have never computed the middle term.

Five delivery failures and what each one actually means

Once the status callback is writing error codes, the diagnosis stops being guesswork. These are the five that account for nearly everything in workflow-built messaging.

ErrorWhat it meansReal causeFix
30034Unregistered 10DLC trafficThe sending number is not attached to an approved A2P 10DLC campaign, or a second number was added to a sole proprietor campaignComplete registration, or attach the number to an approved campaign
30032Toll-free number not verifiedToll-free traffic to US and Canada is blocked while verification is pending or restrictedSubmit toll-free verification and wait for approval before launching the flow
30007Message filteredA carrier or the provider's policy layer blocked the content or the sender's reputationCheck the content against the registered use case, drop public URL shorteners, verify the opt-in matches what was registered
30023Daily message cap reachedYour brand's T-Mobile segment cap for the day is exhausted, across all numbers and platformsReduce segments per message, spread sends, or pursue a higher trust score
21610Unsubscribed recipientThat person opted out of your sender poolRemove them from the list. Only they can reverse it

Two of these, 30034 and 30032, are configuration problems that fail 100 percent of sends and get found on day one. The dangerous ones are 30007 and 30023, because they fail some sends and not others, which is exactly the pattern that looks like a flaky integration.

STOP is handled before your workflow ever sees it

The last failure is the one that damages customer relationships rather than metrics.

Opt-out keyword handling runs inside the messaging platform, ahead of your application. Twilio's default opt-out list is STOP, UNSUBSCRIBE, END, QUIT, STOPALL, REVOKE, OPTOUT, and CANCEL. When one arrives, Twilio blocks the sender, sends the confirmation reply itself, and passes your webhook an OptOutType property rather than a normal inbound message for your flow to route.

Look at that keyword list next to a two-way appointment reminder. A customer who wants to cancel an appointment replies "CANCEL," which is the natural English answer to "reply to change your appointment." They have just unsubscribed from every message your business sends them, the platform confirmed it on your behalf, and the reschedule branch in your workflow never ran. From then on, sends to that number return 21610, and per Twilio's documentation the only way back is for that person to text START.

The scope makes it worse. Once Advanced Opt-Out is configured on a Messaging Service, the blocked list applies to every sender in that pool. If your promotional blasts and your service reminders go out through the same Messaging Service, one STOP aimed at the marketing takes the reminders with it. Split them into separate Messaging Services for the same reason you split email streams by subdomain: so that the stream people want to unsubscribe from is not carrying the stream they need.

Two build rules follow. Never use a reserved keyword as an interactive reply option, so use "R to reschedule" rather than "reply CANCEL." And handle OptOutType explicitly in the inbound webhook: write the opt-out to your CRM, flag the record, and notify a human, because for a service business an opt-out on a reminder line usually means a real customer just went dark on you.

Where to start: a 30-minute messaging audit

List every automated message your business sends, and for each one write down five things: the sending number, the Messaging Service it belongs to, the registered campaign use case, the average character count of the body, and whether that body is generated by a model or comes from a fixed template.

Then do three checks. Send one message of each type to a phone you control and read the final status and error code from the provider console, not from your workflow log. Paste a real generated body into a segment calculator and confirm it comes back GSM-7 at the count you expected. Total your expected daily segments across every flow under one EIN and compare it to your brand's cap, remembering that the T-Mobile share of that traffic is the number being measured.

Most stacks we look at fail the second check and have never looked at the third. If your reminder or follow-up messaging runs through an n8n or Zapier flow with no status callback wired up, that is a half-day of workflow automation work and it converts a silent failure into a reportable one. If you want a second read on the segment math before you scale a campaign, send us the message templates and we will tell you what they actually cost.

Frequently Asked Questions

SOURCES & CITATIONS

  1. 30023: US A2P 10DLC - Daily Message Cap Reached Twilio Docshttps://www.twilio.com/docs/api/errors/30023
  2. What is the SMS character limit? Twilio Docshttps://www.twilio.com/docs/glossary/what-sms-character-limit
  3. 30034: Unregistered 10DLC Traffic Twilio Docshttps://www.twilio.com/docs/api/errors/30034
  4. Customizing Users' Opt-in and Opt-out Experience with Advanced Opt-Out Twilio Docshttps://www.twilio.com/docs/messaging/tutorials/advanced-opt-out

About Alexey Yushkin

Alexey is the founder of GENERAL INFORMATICS LLC. He designs and ships AI and automation systems for businesses and operators across the US.

Connect on LinkedIn

Related reading

Want this kind of system in your business?

We build practical AI and automation systems for operators. Send us your current workflow and we will show you what to automate first.

Request a Workflow Review