How reliable is ZeroSettle? Uptime, delivery, spam flags and failures
ZeroSettle's published reliability record for its iMessage API is a "99.9% uptime" figure on its homepage (a stat, not an SLA), sends that normally reach Apple in 2–5 seconds, inbound texts at your webhook about 1–2 seconds after they reach the line, and a spam flag ZeroSettle says it has seen "only twice" across more than 10,000 messages a week, with a flagged number replaced at no extra charge. ZeroSettle's terms state that delivery of any particular message is not guaranteed, and a failed send returns an error code or a message.failed event instead of failing silently. This page lists what is measured, what is published and what is not promised.
Key takeaways
- Published figures: "99.9% uptime" and "10,000+ messages/week" are homepage stats. Sends normally take 2–5 seconds; inbound reaches your webhook in about 1–2 seconds.
- No SLA: ZeroSettle publishes no service-level agreement, and its terms say delivery of any particular message is not guaranteed.
- Failures are reported: busy, capped, unreachable and opted-out sends each return their own error code; a send recorded but not delivered arrives as
message.failed; webhook deliveries are retried after 1, 5 and 20 seconds. - Spam flags: across more than 10,000 messages a week, ZeroSettle says it has "seen it happen only twice," and it replaces a flagged number at no extra charge with the token, webhook and code unchanged.
- Price: Pro is $49/month for one number, with 5 new contacts a day per number and unlimited messages with people who message you first; Growth is from $599/mo. See ZeroSettle plans and pricing.
What reliability figures does ZeroSettle publish?
ZeroSettle publishes two homepage stats, latency figures in its API docs, and a spam-flag count in its homepage FAQ; none of them is an SLA. 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 (what ZeroSettle is, explained).
| Figure | Exact published wording | Source | Status |
|---|---|---|---|
| Uptime | "99.9% uptime" | zerosettle.io homepage | Homepage stat; not an SLA |
| Volume | "10,000+ messages/week" | zerosettle.io homepage | Homepage stat |
| Send time | "normally 2–5 seconds and at most about 75 for a text (about 105 for a voice message or photo, which ZeroSettle converts first)" | API docs, "Send a message" | Documented behavior |
| Inbound latency | "about 1–2 s from the line receiving a text to your webhook" | API docs, "Errors, limits, and compliance" | Documented behavior |
| Typing call | Returns once the line has raised the bubble, "normally under 2 seconds" | API docs, "Typing indicators" | Documented behavior |
| Spam flags | "across more than 10,000 messages a week we have seen it happen only twice" | Homepage FAQ | ZeroSettle's own report |
| Webhook retries | "retries 3 more times, after 1 s, 5 s, and 20 s" | API docs, "Webhooks, step by step" | Documented behavior |
The send time is measured to the moment the line hands the message to Apple, not to the recipient's screen. Inbound is pushed, so "inbound never delays a send."
Why a homepage stat is not a contract is covered in what 99.9% uptime means for an iMessage API; the ZeroSettle reliability and trust hub links the rest of this series.
What happens when something fails?
When a ZeroSettle send fails, the API returns a specific error code or a message.failed webhook event with a documented next step; a failed webhook delivery is retried, then recorded. Every send the line attempts is stored with record.status set to sent or failed (a send blocked by STOP is neither sent nor stored). What happens after Apple accepts a message is not visible to the API.
| Situation | What ZeroSettle returns | What your code does |
|---|---|---|
| The line stays busy with another request for ~12 s | 429 line_busy, Retry-After: 2 | Retry after 2 s. Sends are serialized per line. |
| New-contact cap reached | 429 new_contact_limit with retry_after_s | Wait retry_after_s. |
| Line temporarily unreachable, or slow to answer | 503 with an error code (see the code below) | Retry with backoff; check GET /api/imessage/line. |
| Your webhook is down or slow | Retries after 1 s, 5 s and 20 s, then the failure is recorded in last_delivery | Answer 2xx within 10 s; dedupe on message.id + event. |
| A send was recorded but not delivered | message.failed webhook event | Alert; use another channel. |
| Number flagged by Apple | Every send fails, to everyone | No code change; ZeroSettle replaces the number at no extra charge. |
| First message to a handle not on iMessage | 422 not_on_imessage; nothing sent, no new-contact slot used | Use another channel. |
| Recipient texted STOP | 403 recipient_opted_out; nothing sent or stored | Don't retry. |
A send wrapper that follows the docs retries only the two transient cases and surfaces everything else:
import os, time, requests
BASE = os.environ.get("ZEROSETTLE_BASE_URL", "https://portal.zerosettle.io")
TOKEN = os.environ["ZEROSETTLE_TOKEN"]
def send(to: str, text: str, attempts: int = 5) -> dict:
backoff = 2
for _ in range(attempts):
r = requests.post(f"{BASE}/api/imessage/send",
headers={"Authorization": f"Bearer {TOKEN}"},
json={"to": to, "text": text}, timeout=90) # a text can take up to ~75 s
if r.ok:
return r.json() # "message_sent": handed to Apple
try:
err = r.json().get("error", {})
except ValueError:
err = {}
code = err.get("code")
if code == "line_busy":
time.sleep(int(r.headers.get("Retry-After", "2"))) # 429; the docs say 2 s
elif r.status_code == 503: # phone_offline / phone_timeout
time.sleep(backoff) # retry with backoff
backoff = min(backoff * 2, 60)
else: # new_contact_limit, recipient_opted_out, ...
raise RuntimeError(f"{r.status_code} {code}: {err.get('message')}")
raise RuntimeError("line still unavailable; queue the message and alert")
More on message.sent, message.failed and the retry schedule is in iMessage delivery status, webhook retries and latency; the ZeroSettle error table lists every code.
How likely is a spam flag, and what happens then?
A spam flag on a ZeroSettle number is rare by ZeroSettle's own account. Its 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." A flag matters more than any single failed send, because it stops the number for everyone at once.
The docs name the fastest way to get flagged: "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." A sudden run of message.failed events across many recipients is the pattern to alert on.
ZeroSettle's homepage states what happens next: "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." For accounts with several numbers, the docs add that the line "keeps its line_id, conversations, message ids, name and photo, and STOPs, and only its number (line) changes. Store line_id; show line."
The number itself is new, so recipients see messages from a different number. More in what happens if your iMessage number is flagged as spam.
How do the limits protect reliability?
ZeroSettle caps new contacts per number because unsolicited volume is what gets a number filtered. The docs: "This is what keeps the number out of Apple's spam filters; it applies to every caller, the console included."
| 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 |
| Total messages sent and received | Unlimited | Unlimited |
On both plans, messages sent within 5 minutes of the first count as one, and anything the contact sends back (a text, photo, voice note or tapback) resets the count.
The docs define the term: "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." On one Pro number, the 6th new contact in a day returns 429 new_contact_limit; on one Growth number, the 4th new contact inside 15 minutes does. With several numbers, a send is refused only when every number is full (or the line the send names is).
The docs call the limits "a floor, not a licence"; the habits that keep a number clean are in how to keep a business iMessage number out of spam filters.
How secure is the API?
ZeroSettle authenticates every API call with a bearer token and signs every webhook with HMAC-SHA256, so your server can reject forged or replayed events. ZeroSettle makes no end-to-end encryption claim.
- Tokens: every call sends
Authorization: Bearer <token>. Tokens are minted in the console; "minting again revokes nothing, revoking revokes all." - Webhook signing: each POST carries
X-ZeroSettle-Signature: t=<unix>,v1=<hex>, an HMAC-SHA256 of"<t>." + raw bodywith your secret. Verify the raw bytes before parsing, compare in constant time, and reject atmore than 300 seconds from now. Ready-made Python and Node verifiers are in the ZeroSettle webhook docs. - The secret: shown once; registering the webhook again rotates it.
- Privacy: ZeroSettle's terms say content "may not be encrypted and … ZeroSettle cannot guarantee communication privacy."
Data handling and the rest of the security model are in is ZeroSettle's iMessage API secure.
How is compliance enforced?
ZeroSettle enforces STOP itself and suspends lines used for unsolicited messaging; consent and quiet hours are the sender's responsibility. A suspension stops the line, so consent matters for reliability as well as for the law.
- 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. Texts, voice messages, photos, reactions, typing and name-and-photo shares to them return
403 recipient_opted_out; nothing is sent or stored. Only START (or unstop) opts them back in. See how STOP and opt-outs work on a ZeroSettle line. - Consent: "ZeroSettle suspends lines used for unsolicited messaging. If you are unsure whether you have consent, you don't."
- Quiet hours: the docs say not to send anything promotional before 8 am or after 9 pm in the recipient's time zone.
Consent rules vary by country and by message, so check yours with counsel. This isn't legal advice.
What does ZeroSettle not promise?
ZeroSettle does not promise uptime, delivery of any particular message, or read status, and its terms say so. The quotes below are from the ZeroSettle iMessage API Terms (last modified September 28, 2026) and the docs.
- No SLA. "ZeroSettle does not warrant that the services will meet your requirements or that their operation will be uninterrupted or error-free." The terms include no service credits.
- No delivery promise. The terms say "delivery of any particular message or feature is not guaranteed."
- No read or delivered receipts in the API.
message.sentmeans "A message left the line"; no API event reports delivery to the recipient or a read. The terms add that "message status, delivery and read receipts, typing indicators … may be delayed, incomplete, or inaccurate." - No Apple affiliation. "ZeroSettle is not affiliated with, endorsed by, or sponsored by Apple Inc." The terms note that the service depends on "third-party platforms, including Apple's iMessage service, that may change without notice," so iMessage availability and Apple's spam filtering sit outside ZeroSettle's control.
ZeroSettle is not a fit if procurement requires a contractual SLA with credits, or if a message must reach someone without iMessage: there is no SMS fallback. For anything critical, keep a second channel.
How are these numbers measured?
Every ZeroSettle figure on this page is ZeroSettle's own published statement, quoted as published; none comes from an independent audit. The homepage stats state no period or method, and the docs' latency figures describe normal behavior ("normally", "about"), not percentiles.
ZeroSettle does not yet publish a monthly send-success rate, median or p95 send latency, or an incident history. When it does, this page will state the period, the number of sends and the method. Until then, measure your own line:
- Time every
POST /api/imessage/sendcall and log its result:message_sentor theerror.code. - Count
message.sentandmessage.failedevents on your webhook per day; sent ÷ (sent + failed) is your send success rate. - Record
last_deliveryfromGET /api/imessage/line(ok,status_code,attempts), or watch the live stream'sdeliveryevents. - Count 503 responses and
line_busyretries as your view of availability.
How does ZeroSettle compare on published reliability evidence?
Messaging providers publish anything from a contractual SLA with service credits (Twilio) to status pages, uptime targets and "as is" terms; ZeroSettle publishes a homepage stat and no SLA.
| Provider | What it publishes | Kind |
|---|---|---|
| ZeroSettle | "99.9% uptime" on the homepage; send and inbound latency in the docs; terms disclaim uninterrupted operation | Stat, no SLA |
| Twilio APIs | 99.95% monthly API availability (99.99% on Twilio Enterprise Edition); covers API availability, not message delivery; excludes telecommunications-provider problems outside Twilio's reasonable control; service credits, not refunds | Contractual SLA |
| Linq | Markets "99.95% uptime backed by the only contractual SLA in the industry"; its status page showed "Linq V3 API" at 99.93% for Jul–Oct 2026 | Claim plus status page |
| Blooio | "99.9% uptime target (a contractual SLA is available only in a signed Enterprise Order Form)" | Target |
| Sendblue | A "99.9%" "Uptime SLA" stat on its API page; no SLA terms linked there | Claim |
| LoopMessage | No uptime figure; incident history lists a May 31–Jun 1, 2026 "Messaging performance issue" and a Jun 4, 2026 CDN incident (about 2 hours) | Status page |
| Project Blue | Status page shows Messaging Gateway at "100% uptime" on a 90-day timeline | Status page |
| Apple Messages for Business | "Apple makes no guarantees in relation to the availability or uptime of Apple Messages for Business." | Terms |
| WhatsApp Business Platform | Terms say the platform "IS PROVIDED 'AS IS' AND WITHOUT ANY WARRANTY OF ANY KIND" | Terms |
Status-page percentages are measured by each vendor; a marketing figure may not be backed by contract terms.
To test ZeroSettle against your own traffic, read the ZeroSettle iMessage API docs or get a number.
Frequently asked questions
Does ZeroSettle pay service credits or refunds for downtime?
No. ZeroSettle publishes no SLA, and its terms include no service credits for downtime. Separately from downtime, the subscription has a 30-day money-back guarantee: ask within 30 days and you are refunded in full and the subscription is cancelled.
How do I recover messages my webhook missed after the last retry?
Page forward with GET /api/imessage/messages?after_id=…, which returns every message in both directions in id order; pass each response's next_after_id as the next after_id. ZeroSettle keeps messages "indefinitely for now," so a receiver that was down catches up from the last id it handled.
Can two of my servers send from the same number at once?
Yes, but ZeroSettle sends one message at a time per line: concurrent sends queue behind each other and return 429 line_busy after about 12 seconds of waiting. Retry after 2 seconds, or send from a single queue.
Sources
- ZeroSettle iMessage API docs: "Your iMessage number", "Send a message", "Read messages", "Typing indicators", "Webhooks, step by step" and "Errors, limits, and compliance". Checked October 8, 2026.
- zerosettle.io homepage, stats and FAQ "What if a number does get marked as spam?". Checked October 8, 2026.
- ZeroSettle iMessage API Terms of Service, sections 2, 5, 7, 13 and 14. Last modified September 28, 2026.
- Twilio APIs Service Level Agreement, Twilio. Updated April 9, 2026; checked October 8, 2026.
- Service Terms for Messages for Business, Apple, section 4.2. Last updated December 17, 2024; checked October 8, 2026.
- Meta Terms for WhatsApp Business Platform, Meta, section 7.8. Last modified September 23, 2026; checked October 8, 2026.
- Linq iMessage API and Linq status page, Linq. Checked October 8, 2026.
- Blooio pricing, Blooio. Checked October 8, 2026.
- Sendblue API, Sendblue. Checked October 8, 2026.
- LoopMessage incident history, LoopMessage. Checked October 8, 2026.
- Project Blue status page, Project Blue. Checked October 8, 2026.
Changelog
- Updated to ZeroSettle's current limits: Pro is 5 new contacts a day per number, and the 2-unanswered-message rule applies on every plan. Added the not-on-iMessage refusal and the full STOP wording.
- First published. Next review: quarterly, or sooner after any incident or new data.