Moving business texting from SMS to iMessage: a migration plan
Moving business texting from SMS to iMessage usually means adding iMessage next to SMS, not replacing it: a ZeroSettle number reaches only people on iMessage, can't be ported from your SMS number, and has no SMS fallback yet. The practical migration plan is to keep your SMS provider for Android and other contacts who aren't on iMessage, introduce the new iMessage number so customers text it first, carry your opt-out list across, and rewrite your messages for a conversational, one-to-one channel.
Key takeaways
- What changes: you add a second number. The ZeroSettle iMessage number is new (it can't be ported from your SMS number), and SMS stays for Android and anyone not on iMessage.
- What moves: one-to-one conversations that expect a reply, such as support, follow-ups and reminders. Sign-in codes and promotions to a whole list stay on SMS.
- Opt-outs: ZeroSettle blocks only people who opt out by texting your ZeroSettle number (a text with the word STOP, or a clear request like “take me off your list”), so remove your SMS opt-outs yourself before the first send.
- Main limit: a Pro number can start conversations with 5 new contacts a day. Anyone who texts the number first is never limited, and messages with them are unlimited.
- Price: Pro is $49/month for one number, with no per-message charge. Growth, for several numbers working as one, is from $599/mo.
Will you replace SMS or run both?
Plan to run both, because a ZeroSettle number reaches only people on iMessage. ZeroSettle is an iMessage API: a real phone number on real iMessage, running on Apple hardware we operate for you, that your code texts customers from and hears back on through a bearer token and signed webhooks. Its docs say: "The address must be on someone's iMessage; there is no SMS or email fallback." SMS fallback for non-Apple phones is on ZeroSettle's roadmap, not in the product.
Owning an iPhone isn't the same as being on iMessage: Apple lists iMessage being turned off as one reason a message goes green (blue vs green bubbles explains the colors).
| Your situation | Plan |
|---|---|
| Customers on a mix of iPhone and Android | Run both: iMessage for contacts on iMessage, SMS for the rest. |
| Customers start conversations from your iOS app or website | Start them on iMessage with a prefilled sms: link (Step 3); keep email or chat for Android visitors. |
| Messages must reach every phone, or a large list at once | Keep them on SMS. ZeroSettle caps new contacts per number per day, and its terms rule out "high-volume or abusive outreach of any kind". |
If you want one vendor for both, Sendblue's FAQ (as of October 2026) says it will "automatically fall back to sending the message through SMS" when a recipient doesn't have iMessage enabled. iMessage vs SMS vs RCS vs WhatsApp compares the channels.
Step 1: which messages should move to iMessage?
Move the conversations that are one-to-one and expect a reply, and keep on SMS anything that must reach every phone. ZeroSettle caps how many new people a number texts first, never people who text it first, so the mix you move sets the pace.
| Message | Move? | Why |
|---|---|---|
| Support questions | Move | Inbound is never limited. |
| Follow-ups and reminders that ask for a reply | Move, for contacts on iMessage | Only the first message to each person counts as a new contact. On every plan, a contact who hasn't replied gets at most 2 messages. |
| One-time sign-in codes | Keep on SMS | They must reach every phone. Sign in with iMessage can replace them for users on iMessage. |
| Promotions to your list | Keep on SMS | New contacts are capped per day. |
| Contacts on Android or without iMessage | Keep on SMS | ZeroSettle can't reach them. |
How long does the move take?
Texting 300 existing SMS customers first from the new number takes 60 days on one Pro number (5 new contacts a day) and 6 days on one Growth number (50 a day, 3 per 15 minutes). If those 300 customers text the new number first, none count against the limit. That is why Step 3 asks customers to start the thread.
Step 2: get the number and set the name and photo
A ZeroSettle number is a new number assigned at signup. It can't be ported in, and the docs offer no way to bring your own number, choose the area code or get a non-US number.
- Press Get started and sign in with your phone number (a one-time SMS code). A number is set aside while you finish.
- Say what the number is for (sign in with iMessage, branded messages, or an AI agent). That claims it.
- Set your brand name and photo, and text yourself a test message. You can skip the test and change the name and photo later.
- Subscribe. The console and API open once the subscription is active, and a number not paid for within 30 minutes is released.
"If all numbers are taken, you can join the waitlist," so set your announcement date after the number is live. The terms add: "Phone numbers assigned to your lines remain the property of ZeroSettle. Once a subscription is no longer active, the number is reclaimed and may be reassigned or returned to its provider." Keep your SMS number active through the migration and after it.
Use the brand name customers already see in your SMS texts, so they connect the two numbers. The name (up to 64 characters) becomes the contact's first name, and the photo is a JPEG or PNG under 3 MB. ZeroSettle shares the card with the first message of every conversation and again after you change it, as "<name> shared a name and photo with you"; a share never counts as a new contact.
Step 3: introduce the new number so customers text first
Announce the iMessage number through channels customers already trust and ask them to text it, so the iMessage conversation starts with them. A customer who texts first is never limited, and links you send them are tappable. Texting first also gets around iOS 26's Screen Unknown Senders, which moves texts from unknown senders into a separate list without a notification.
Put the ask in three places (Fernwood Plant Co. is a fictional shop):
- One SMS to your opted-in list from your existing number: "Fernwood Plant Co: on an iPhone? We now answer on iMessage at (805) 555-0100. Text us there anytime. Reply STOP to opt out."
- A prefilled
sms:link on your website, order pages and emails, which opens Messages on iPhone with your number and the text filled in. - A QR code of that link on receipts and packaging.
<a href="sms:+18055550100&body=Hi%20Fernwood%2C%20order%204821">Text us on iMessage</a>
The same link opens the SMS app on Android, so show those visitors your SMS number, email or chat. Prefill a short reference such as an order number, never an email address or a secret, to match the new thread to the customer. If you do text someone first, ZeroSettle checks the number with Apple before the first message: if it isn't on iMessage, the API answers 422 not_on_imessage, nothing is sent and no new-contact slot is used. More in how to get customers to text you first.
- Tue 9:14 AM
- Customer: Hi Fernwood, order 4821
- Customer: got your text about the new number. is my monstera shipping this week?
- Business: Hi Dana, Fernwood Plant Co here. Thanks for switching over!
- Business: Yes, it ships tomorrow. Your order page: fernwood.example.com/t/4821 👍
sms: link, so the link in the reply is tappable. Blue bubbles come from the shop's new iMessage number; gray bubbles are Dana's.Step 4: do SMS consent and opt-outs carry over?
SMS opt-outs don't carry over: ZeroSettle only knows about opt-outs texted to your ZeroSettle number, so remove everyone who opted out on SMS before the new number sends anything. ZeroSettle's docs tie consent to a purpose ("The person gave you their number for this purpose"), so ask counsel whether consent you collected for SMS covers texts from a new number. iMessage and TCPA consent covers the rules. Consent rules vary by place and purpose; this isn't legal advice.
From then on, ZeroSettle enforces STOP: "When a contact texts STOP, the server records it and blocks your number (every number on your account) from reaching them." A text with the word STOP, or a clear request like “take me off your list”, opts them out across every number on your account, and only START opts them back in. Texts, voice messages, photos, reactions, typing and name-and-photo shares to them return 403 recipient_opted_out, with nothing sent or stored. See how STOP and opt-outs work on ZeroSettle.
Keep one suppression list for both numbers. GET /api/imessage/opt-outs lists every handle that opted out on your ZeroSettle numbers, with opted_out_at. It covers only opt-outs received since ZeroSettle began enforcing STOP, so keep your own list too. Run this before each batch of texts you send first:
# ok_to_text.py: drop everyone who opted out on SMS or on the iMessage number
# usage: ZEROSETTLE_TOKEN=... python ok_to_text.py contacts.csv sms_opt_outs.csv > ok.csv
import csv, os, sys
import requests
BASE = "https://portal.zerosettle.io"
TOKEN = os.environ["ZEROSETTLE_TOKEN"]
def numbers(path):
# one E.164 number per row, in a column named "phone" (e.g. +18055559876)
with open(path, newline="") as f:
return [row["phone"].strip() for row in csv.DictReader(f)]
r = requests.get(f"{BASE}/api/imessage/opt-outs",
headers={"Authorization": f"Bearer {TOKEN}"}, timeout=30)
r.raise_for_status()
blocked = {o["handle"] for o in r.json()["opt_outs"]} | set(numbers(sys.argv[2]))
print("phone")
for phone in numbers(sys.argv[1]):
if phone not in blocked:
print(phone)
The script removes opt-outs; it doesn't prove consent. After launch, copy each new ZeroSettle STOP into your SMS suppression list too (the same list call, or the live stream's optout event), so a STOP on either number counts on both. ZeroSettle's other consent rules still apply: keep the record of consent, say who you are in the first message, and send nothing promotional before 8 am or after 9 pm in the recipient's time zone.
Step 5: rewrite messages for iMessage
Rewrite SMS templates as short, conversational texts: iMessage has no 160-character segments, and ZeroSettle's docs note that "Three texts a few seconds apart read like a person typing; one paragraph reads like a campaign."
| SMS habit | On a ZeroSettle number |
|---|---|
| One 160-character segment | A text can be 1–4,000 characters. |
| A link in the first text | Shown as plain text until they reply or save your number: "The recipient's phone does this, so no sender can avoid it." The API still sends and returns warning.code: "link_not_tappable". Ask for a reply first. |
| MMS for pictures | Photos up to 5 MB, with a caption in the same bubble, sent only to contacts who have replied. HEIC, WebP, TIFF, BMP and anything over 2048 px on the long edge are re-encoded to JPEG, which strips EXIF and GPS. |
| A long explanation in text | A voice message up to 6 MB (m4a, mp3, wav and other common formats, converted by ZeroSettle), shown as Messages' audio bubble with a waveform and the transcript the recipient's iPhone generates, but no caption. Like photos, only to contacts who have replied. |
| "Reply Y to confirm" | A 👍 tapback can stand in for "Y"; it reaches your webhook as reaction.received. |
For example, the SMS "FERNWOOD: Order 4821 shipped! Track: fernwood.example.com/t/4821" becomes three texts to a customer who hasn't texted the new number yet: "Hi Sam, it's Fernwood Plant Co.", "Your fiddle-leaf fig shipped and should arrive Thursday.", "Want the tracking link?" The link goes out after Sam answers (more in writing a first iMessage customers reply to).
Step 6: route replies and measure
Send iMessage replies into the same inbox or CRM as SMS replies, tagged by channel, so whoever answers sees one history per customer. ZeroSettle POSTs every message event to one HTTPS webhook, and an inbound text arrives about 1–2 seconds after the line receives it.
- Verify first:
X-ZeroSettle-Signature: t=<unix>,v1=<hex>is an HMAC-SHA256 of"<t>." + raw body, keyed with your webhook secret. Compare it in constant time and reject atmore than 300 seconds off. Auto-reply only tomessage.received, because your own sends come back asmessage.sent. - Match the customer on
message.handle, which can be an iMessage email address rather than a phone number. - Dedupe retries (after 1, 5 and 20 seconds) on
message.idplusevent.
Measure on your own traffic, such as the share of reminders answered within a day on each channel: ZeroSettle publishes no reply rates, and its API reports message.sent and message.failed, not read status. How to receive iMessages with a webhook has a full receiver.
What does running iMessage next to SMS cost?
ZeroSettle Pro is a flat $49 a month for one number with no per-message charge, while US SMS on Twilio is billed per segment plus carrier and registration fees. Running both means paying for both: moving conversations cuts SMS segments but doesn't end the SMS bill.
| Item | ZeroSettle Pro | Twilio US SMS |
|---|---|---|
| Number | Included in $49/month | $1.15/month |
| Per message | None: messages are unlimited (counted), new contacts are capped | $0.0083 per 160-character segment, plus carrier fees (for example $0.005 per outbound SMS to Verizon) |
| Registration | No setup fee | A2P 10DLC brand and campaign, including $4.50 brand registration and $41.50 Standard brand vetting |
| Reaches | iMessage users only | Any SMS-capable phone, Android included |
Twilio figures from its US SMS pricing page, A2P 10DLC overview and brand registration docs.
Pro is self-serve, can be cancelled anytime and includes unlimited messages with people who message you first, 5 new contacts a day, and 1,000 AI credits a month for the hosted AI agent; Growth is from $599/mo. Both have a 30-day money-back guarantee on the subscription, and there is no free trial. See ZeroSettle pricing, the ZeroSettle vs Twilio comparison and the other guides, or get a Pro number and read the ZeroSettle API docs.
Frequently asked questions
Do I need to build anything before customers text the new number?
No. ZeroSettle's web console shows every conversation live and lets your team send texts and photos, so you can answer the new number there and add the webhook routing from Step 6 later.
What if the new iMessage number gets flagged as spam?
ZeroSettle says it is rare ("across more than 10,000 messages a week we have seen it happen only twice") and that "we replace the number right away at no extra charge", with your API token, webhook and code unchanged. The number customers text does change, so you would announce the replacement; your SMS number is unaffected. See what happens if your number is flagged.
Can the hosted AI agent answer the new number instead of my team?
Yes, in Beta. Set the number to Managed by AI Agent and ZeroSettle's hosted agent answers every inbound text from the business context you write, using one AI credit per text it sends (Pro includes 1,000 a month). Inbound texts on that number then skip your webhook, and your own sends are refused with 403 managed_by_zerosettle.
Sources
- ZeroSettle iMessage API docs: "Your iMessage number", "Send a message", "Attachments", "Retention offers", "Customer support", "AI agent", "Webhooks, step by step", "Live stream" and "Errors, limits, and compliance". Checked October 12, 2026.
- ZeroSettle homepage: Plans and FAQ. Checked October 12, 2026.
- ZeroSettle iMessage API Terms of Service, sections 6 and 13. Last modified September 28, 2026.
- Why are my iPhone messages green?, Apple Support. Checked October 8, 2026.
- SMS pricing for the United States, Twilio. Checked October 8, 2026.
- Programmable Messaging and A2P 10DLC, Twilio docs (updated July 7, 2026). Checked October 8, 2026.
- A2P 10DLC Brand Registration, Twilio docs (updated September 25, 2026). Checked October 8, 2026.
- FAQ, Sendblue docs. Checked October 8, 2026.