How to keep a business iMessage number out of spam filters
Apple filters business iMessage numbers that behave like spam, and the main signal to avoid is repeated messages to people who never answer: once a number is flagged, every send from it fails, to everyone. ZeroSettle's new-contact limits exist to keep each number out of those spam filters (Pro: 5 a day per number; Growth: 50 a day and 3 per 15 minutes; on both, at most two unanswered messages to one contact), and people who text you first are never limited. Consent, a first message that says who you are, no link before a reply, and stopping when people don't answer do the rest.
Key takeaways
- Main risk: repeated messages to people who never answer. When Apple flags a number, every send from it fails, to everyone.
- Enforced limits, per number: Pro allows 5 new contacts a day. Growth allows 50 a day and 3 per rolling 15 minutes. Both allow at most 2 unanswered messages to one contact. People who texted you first are never limited.
- First message: say who you are, ask one question, and leave the link out until they reply.
- If it happens anyway: ZeroSettle replaces a flagged number at no extra charge, and your API token, webhook and code stay the same.
- Not for: texting people who never gave you their number. ZeroSettle's terms prohibit unsolicited messaging, and ZeroSettle suspends lines used for it.
- Price: Pro is $49/month, starting with one number, with unlimited messages with people who message you first; Growth is from $599/mo. ZeroSettle pricing and plan limits has the details.
What gets a business iMessage number flagged?
The fastest way to get a business iMessage number flagged is to keep texting people who never reply. ZeroSettle's API docs put it in one sentence:
Repeated messages to people who never answer are the fastest way to get a number flagged by Apple: when that happens every send fails, to everyone.
ZeroSettle iMessage API docs, "Errors, limits, and compliance"
A flag takes the whole number down, including conversations with customers who wanted your texts. Recipients can also report you: Apple's iPhone guide puts a Report Spam link at the bottom of any message from an unknown sender, and a reported iMessage goes to Apple with the sender's information. Apple's guides give no thresholds; other iMessage API providers publish some:
| Provider | Published guidance |
|---|---|
| Sendblue | Causes of blocked lines include junk reports, too many follow-ups without a response, cold or weak-consent outreach, high volume in a short window, links or media before the recipient engages, and repetitive copy (article updated April 12, 2026). |
| Linq | "Stay meaningfully under 50 first-touch conversations per line per rolling 24 hours." |
| LoopMessage | "Your reply rate should be over ~30%"; "We recommend not initiating a conversation with more than 50 contacts per day." |
The common thread: many first-touch conversations at once, low reply rates, follow-ups to silence, and links before engagement.
What are ZeroSettle's limits, and what counts?
ZeroSettle caps new contacts per number: 5 a day on Pro, 50 a day and 3 per rolling 15 minutes on Growth, and both plans allow at most two unanswered messages per contact. The docs say why: "This is what keeps the number out of Apple's spam filters; it applies to every caller, the console included."
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. A new contact counts against these limits whether your code, the console or the hosted AI agent sends the first text.
| Limit | Pro | Growth |
|---|---|---|
| New contacts per day (3 AM to 3 AM Eastern) | 5 | 50 |
| New contacts per rolling 15 minutes | — | 3 |
| Unanswered messages to one contact | 2, then 403 awaiting_reply | 2, then 403 awaiting_reply |
| People who texted first, ongoing conversations | Never limited | Never limited |
The docs define the unit: "A 'new contact' is a handle the line delivers a text, voice message, or photo to first; reactions, typing, profile shares, and failed sends never count. Anyone who texted the line first is never limited, and neither is an ongoing conversation."
At a cap, the API returns 429 new_contact_limit with retry_after_s. On an account with several numbers, each number has its own day, and the send is refused only when every number is full (or the line it names is).
The limit math for one batch
Take 30 people who signed up at an event and agreed to texts about it:
- On Pro: 5 openers go out on the first day, and the rest wait for the following days, which start at 3 AM Eastern, so the last goes out on day six. For batches like this, Growth is the better fit.
- On Growth with three numbers: at most 9 new conversations per 15 minutes and 150 a day, so all 30 are out in four windows, about 45 minutes.
- Only the first text counts: later texts to the same person, and their replies, never count as new contacts on either plan. The two-unanswered rule still applies.
Handle the 429 in code
GET /api/imessage/line shows today's count in usage.new_contacts. When a send hits a cap, requeue the person for retry_after_s instead of retrying in a loop:
import os
import requests
BASE = "https://portal.zerosettle.io"
HEADERS = {"Authorization": f"Bearer {os.environ['ZEROSETTLE_TOKEN']}"}
def send(to: str, text: str) -> tuple[str, int]:
"""("sent", 0), ("retry", seconds to wait) or ("skip", 0) to leave this person out."""
r = requests.post(f"{BASE}/api/imessage/send", headers=HEADERS,
json={"to": to, "text": text}, timeout=120)
if r.ok:
return "sent", 0
if r.status_code == 503:
return "retry", 30 # line briefly unreachable: back off
if r.status_code in (401, 402):
r.raise_for_status() # bad token or inactive plan: stop the batch
err = r.json()["error"]
if err["code"] == "new_contact_limit":
return "retry", err["retry_after_s"] # 15-minute window or the 3 AM Eastern reset
if err["code"] == "line_busy":
return "retry", 2
return "skip", 0 # STOP, awaiting_reply, not_on_imessage, bad handle
A recipient_opted_out person stays skipped until they text START; an awaiting_reply person can be texted again once they reply. A retry that comes due at the 3 AM Eastern reset is midnight Pacific, so hold anything promotional until after 8 am in the recipient's time zone, as ZeroSettle's consent rules ask.
Why do people who text first never count?
People who text your number first never count against ZeroSettle's limits, because they started the conversation and every reply after that is part of an ongoing one.
Text-first fixes two more problems. ZeroSettle's docs say a prefilled sms: button "makes your number a known sender from the first message, and every link after that works," and that it avoids iOS 26's Screen Unknown Senders list. Apple says that setting, which files unknown senders under a separate filter, is on for anyone who had Filter Unknown Senders turned on in iOS 18.
Put a "Text us" link (sms:+18055550100&body=…, with an order number prefilled) on your site or in your app, and the same link as a QR code on a sign, receipt or package. On Android it opens the SMS app and ZeroSettle has no SMS fallback, so keep email or chat there. More in the guide to getting customers to text you first.
What should the first message look like?
When you text first, say who you are and why you are texting, ask one easy question, and leave the link out. Once they reply, your links become tappable and the unanswered count resets; the guide to first iMessages that get replies has more openers.
- Name the business and the reason. ZeroSettle's consent rules include "Your first message says who you are."
- No link yet. "An iPhone won't open links from an unknown sender. Until the recipient replies to your number or saves it as a contact, a link in your text shows as plain text they can't tap. The recipient's phone does this, so no sender can avoid it." The API still sends it and returns
warning.code: "link_not_tappable"(why first-message links aren't tappable). - Short texts, not a paragraph. "Three texts a few seconds apart read like a person typing; one paragraph reads like a campaign."
- Today 10:14 AM
- Business: Hi Dana, it's Harbor Moving.
- Business: You asked for a moving quote on our site this morning.
- Business: How many bedrooms, and what's your move date?
- Customer: 2 bedrooms, Nov 14
- Business: Thanks! Your quote for Nov 14: harbormoving.example/q/4821👍
How many follow-ups are safe?
One follow-up after silence is a sensible ceiling. ZeroSettle enforces two unanswered messages per contact on every plan, then refuses the next send with 403 awaiting_reply.
| What happens | Unanswered | Result |
|---|---|---|
| Three opener texts within 5 minutes | 1 | Sent |
| One follow-up the next day | 2 | Sent |
| A third message, no reply yet | 2 | Refused; nothing sent or stored |
| They send anything back: text, photo, voice note or tapback | 0 | Next send allowed |
The cap is a limit, not a target: stop after the opener and one follow-up. Sendblue lists "too many follow-ups without a response" among the causes of blocked lines.
The hosted AI agent (Beta) follows the same STOP, new-contact and unanswered rules. Its first_message is 1 to 3 texts, and its triggers default to one follow-up a day after the last message, sent in the morning; every trigger obeys STOP, the two-unanswered rule and the caps. See how the hosted AI agent works.
What do consent, STOP and quiet hours require?
ZeroSettle's limits cap volume, but consent is what makes the texts wanted, and ZeroSettle's docs define it in four rules:
- The person gave you their number for this purpose, and you can show the record.
- Your first message says who you are.
- Honor STOP immediately.
- "Don't message before 8 am or after 9 pm in the recipient's time zone for anything promotional."
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 the person out, and only START opts them back in. Texts, voice messages, photos, reactions, typing and name-and-photo shares to them then return 403 recipient_opted_out, and nothing is sent or stored. Linq's reputation docs list "still messaging recipients who opted out" among the patterns that put a line at risk. See how STOP works on a ZeroSettle line.
ZeroSettle's docs put US TCPA damages at $500 to $1,500 per message sent without prior express consent. As we read the statute, 47 U.S.C. § 227(b)(3) generally sets $500 per violation (or the actual loss, if greater), and a court may triple it when the violation was willful or knowing. More in the iMessage TCPA consent guide. This isn't legal advice; have counsel review your program.
Unsure about consent?
"ZeroSettle suspends lines used for unsolicited messaging. If you are unsure whether you have consent, you don't."
What if a number is flagged anyway?
If a ZeroSettle number is flagged anyway, ZeroSettle replaces it at no extra charge. The homepage FAQ: "It is rare. The API's rate limits are designed to keep every line out of spam filters, and across more than 10,000 messages a week we have seen it happen only twice."
If it does happen, we replace the number right away at no extra charge. Your API token, webhook, and code stay exactly as they are, so your integration keeps running without changes.
zerosettle.io FAQ, "What if a number does get marked as spam?"
On multi-number accounts the line keeps its line_id, conversations, message ids, name and photo, and STOPs; only the number changes, and recipients see the new one. To them it is a number they have never texted, so treat the next message like a first one: say who you are, and no link until they reply. Before sending again, find the batch that went unanswered. Linq's reputation docs warn that moving a list to a new number and going "straight back into the previous daily cadence without waiting for anyone to reply" makes every send land cold. More in what happens when a number is flagged.
Is staying under the limits enough?
No. Staying inside ZeroSettle's limits does not make outreach safe on its own. The docs: "Carrier and Apple rules: unsolicited volume gets a number filtered or deactivated. The new-contact limits above exist for this reason; they are a floor, not a licence."
Five unwanted texts a day are still unwanted: a Pro number that spends its allowance on people who never asked, and hears nothing back, is doing what the docs warn against, only more slowly. ZeroSettle publishes no reply-rate target, so after each batch ask: are people answering? If the plan is to reach people who never gave you their number, ZeroSettle is not the tool; its terms prohibit spam and unsolicited messaging.
The other reliability and trust pages cover uptime, delivery status and security. To start, get a number on Pro, compare plans, or read the limits and compliance docs.
Frequently asked questions
Can I raise my daily new-contact limit?
Not for a single number: the limits are per number, so more room means more numbers or a bigger plan. Growth (50 new contacts a day per number, numbers that work as one under the same API key and webhook) is from $599/mo and set up after a demo (see ZeroSettle pricing). Beyond that, the Enterprise plan, "for high volume and compliance needs", has custom pricing.
When exactly does the daily count reset?
At 3 AM Eastern, EST or EDT, which is midnight Pacific. resets_at under usage.new_contacts in GET /api/imessage/line gives the next reset; the 15-minute windows are rolling, so each slot frees up 15 minutes after it was used.
Does deleting a conversation reset that contact?
Yes, and it works against you: the next message to that person counts as a new contact again and re-shares your name and photo. Nothing already delivered is unsent.
Can I check whether a number is on iMessage before texting it?
ZeroSettle does it for you: every first message to a new contact is checked with Apple, and a phone number or email that isn't on iMessage gets 422 not_on_imessage, with nothing sent and no new-contact slot used. ZeroSettle has no SMS fallback, and a failed send never counts as a new contact.
Sources
- ZeroSettle iMessage API docs: "Errors, limits, and compliance", "Links in a first message", "More than one number", "Customer support", "Retention offers" and "AI agent". Checked October 12, 2026.
- zerosettle.io homepage, FAQ "What if a number does get marked as spam?" and the plans section. Checked October 12, 2026.
- ZeroSettle iMessage API Terms of Service, restrictions on spam and unsolicited messaging. Last modified September 28, 2026.
- Report spam and block senders in Messages on iPhone, Apple Support (iPhone User Guide). Checked October 9, 2026.
- View conversations from unknown senders in Messages on your iPhone, Apple Support. Checked October 8, 2026.
- 47 U.S. Code § 227, Restrictions on use of telephone equipment, Legal Information Institute, Cornell Law School. Checked October 8, 2026.
- Why did my Sendblue line get blocked?, Sendblue Knowledge Base. Last updated April 12, 2026; checked October 8, 2026.
- Phone Reputation, Linq API Docs. Checked October 8, 2026.
- Is it possible to send an outbound text first?, LoopMessage Helpdesk. Checked October 8, 2026.
Changelog
- Updated for current limits: Pro allows 5 new contacts a day, the two-unanswered rule applies on every plan, and every first message is checked for iMessage.
- First published. Reviewed quarterly, and sooner after any incident or new data.