How STOP and opt-outs work on a ZeroSettle iMessage line
On ZeroSettle, any text containing the word STOP, or a clear request like "take me off your list", opts the sender out of every number on your account: texts, photos, voice messages, tapbacks, typing indicators and name-and-photo shares to them are refused with 403 recipient_opted_out, and nothing is sent. The person opts back in by texting START (or unstop) as the whole message. You still receive the STOP and anything they send after it, and GET /api/imessage/opt-outs lists everyone who is opted out, with when they texted STOP.
Key takeaways
- What triggers it: any text with the word "stop" in it ("pls stop", even "stop by at 3?"), about 58 opt-out phrases anywhere in a text ("take me off your list", "unsubscribe", "don't text me", "wrong number"), plus keywords such as quit as the whole text or its first sentence. Tapbacks, photos and voice messages never count.
- What it blocks: every kind of send to that person from every number on your account, refused with
403 recipient_opted_out. There is no override. - How it ends: only the person texting START or unstop as the whole message, or ZeroSettle clearing it when they ask another way.
- What it leaves to you: "cancel", "end", "revoke" and other wording outside its lists, opt-outs from your other channels, and STOPs received before enforcement launched.
- Plans: STOP enforcement applies to every line. Pro is $49/month and Growth is from $599/mo.
What counts as an opt-out?
On a ZeroSettle line, any text containing the word "stop" opts the sender out, wherever the word sits and whatever its capitalization or meaning. So does any of about 58 opt-out phrases ZeroSettle recognizes, such as "take me off your list", "remove me", "unsubscribe", "opt me out", "don't text me", "wrong number" or "leave me alone", anywhere in a text (matched as whole words, apostrophes ignored). Keywords such as "quit" also count when one is the whole text or its first sentence. Only a text counts, never a tapback, photo or voice message.
| The contact sends | Opt-out? | Why |
|---|---|---|
| pls stop / Don't stop / stop by at 3? | Yes | Contains the word "stop", whatever it means |
| I'm at the bus stop / non-stop flights | Yes | A space or hyphen leaves "stop" a word of its own |
| Quit / Quit. Who is this? | Yes | A listed keyword as the whole text or its first sentence |
| please take me off your list / I want to unsubscribe / wrong number lol | Yes | One of the listed opt-out phrases, anywhere in the text |
| it stops at 5 / nonstop / unstop | No | "stops" and "nonstop" are other words; "unstop" is an opt-in word |
| cancel / end / revoke | No | Not a listed keyword or phrase, so your code handles them |
| A 👎 tapback | No | Only a text counts |
For the recipient's side, see what to do when a business texts you on iMessage.
What gets blocked after a STOP?
After a STOP, ZeroSettle refuses every kind of send to that handle from every number on your account, and nothing is sent or stored. The refusal is 403 recipient_opted_out, with error.handle and error.opted_out_at saying who opted out and when.
| Action | Where it comes from | After a STOP |
|---|---|---|
| Text, photo or voice message | POST /api/imessage/send | 403 recipient_opted_out |
| Tapback | POST /api/imessage/reactions | 403 recipient_opted_out |
| Typing indicator | POST /api/imessage/typing | 403 recipient_opted_out |
| Name-and-photo share | POST /api/imessage/profile/share | 403 recipient_opted_out |
| Hosted AI agent text | The agent | Not sent; its AI credit comes back |
| Your team's reply | The web console | Conversation disabled, showing when they texted STOP |
Treat recipient_opted_out as final: don't retry or queue the message. Another of your numbers won't help; a STOP to any line blocks them all.
How does someone opt back in?
A person opts back in to a ZeroSettle line by texting START or unstop as the whole message. Any other text, such as "ok you can text me again", "start now" or a new question, arrives as a normal message while sends to them stay blocked.
If the person asks some other way, for example by email, contact ZeroSettle and ZeroSettle can clear the opt-out; neither the API nor the console can lift one. When the person texts START, the live stream sends an optout event with "opted_out_at": null.
How do you see who has opted out?
Your code sees ZeroSettle opt-outs three ways: the STOP text reaches your webhook as an ordinary message.received event, GET /api/imessage/opt-outs lists each opted-out handle with opted_out_at, and the live stream sends an optout event on each STOP and START.
BASE=https://portal.zerosettle.io
curl -s -H "Authorization: Bearer $ZEROSETTLE_TOKEN" $BASE/api/imessage/opt-outs
# {"opt_outs": [{"handle": "+18055559876", "opted_out_at": "2026-09-28T17:04:11Z"}]}
The webhook has no separate opt-out event, so a receiver that must react at once reads the STOP text itself, using ZeroSettle's rule: the word "stop" anywhere, one of the documented opt-out phrases anywhere, or a listed keyword as the whole text or its first sentence. With more than one number, each opt-out and each optout event also carries line and line_id. On a line group the hosted AI agent manages, inbound texts skip your webhook, so the STOP shows in the console, GET /api/imessage/messages and the live stream.
Does STOP cover the AI agent and Sign in with iMessage?
Yes for ZeroSettle's hosted AI agent: after a STOP it sends that person nothing more, follow-ups included. Sign in with iMessage keeps working for someone who texted STOP, because the user texts you and verification needs nothing sent to them.
- Hosted AI agent (Beta). The hosted agent's texts follow the same rules as yours: STOP is honored, and the plan's new-contact limits and the 2-unanswered-messages rule apply. The agent points anyone who wants no more texts to STOP.
- Your own model. Check each inbound text for an opt-out before calling the model, so you don't pay for an answer ZeroSettle will refuse with
403 recipient_opted_out. - Sign in with iMessage. The recipe's 👍 tapback to an opted-out user returns
403 recipient_opted_out, so confirm the sign-in in your app, not in the thread (how Sign in with iMessage works).
What should you still do yourself?
ZeroSettle's block covers your ZeroSettle numbers and the words it recognizes; the rest of opt-out compliance stays with you.
- Act on other wording. As we read the FCC's TCPA rules, replying "stop", "quit", "end", "revoke", "opt out", "cancel" or "unsubscribe" to a text generally revokes consent, and so may other wording a reasonable person would read as a request to stop. ZeroSettle blocks on the word "stop" and its listed phrases ("unsubscribe", "quit texting me", "don't text me" and the rest), but not on "cancel", "end" or "revoke", or on a request it doesn't recognize, such as "I'm done with these texts", so your webhook code must mark those handles and stop sending.
- Sync the list.
GET /api/imessage/opt-outscovers only your ZeroSettle numbers. Copy it into your CRM so email and workflow tools respect it, as the nightly job in the HubSpot and Salesforce guide does, and honor unsubscribes from other channels, which never reach ZeroSettle. - Carry old opt-outs forward. In the docs' words, "Only STOPs received since this enforcement launched are recorded." Anyone who texted STOP before then is not on the list and is not blocked.
An opt-out ends consent you had to have in the first place. ZeroSettle's docs spell out what consent means in practice:
- 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."
The docs give the stakes: "texting a consumer without their prior express consent carries statutory damages of $500 to $1,500 per message, and class actions are routine. Marketing texts need written consent; the National Do Not Call Registry applies." More in the TCPA consent guide for iMessage; you are responsible for consent. This isn't legal advice; have counsel review your program.
How do other iMessage APIs handle STOP?
iMessage API providers differ on what triggers an opt-out, whether later sends are blocked, and what reopens the contact. ZeroSettle wrote this page; each other row comes from that provider's own docs.
| Provider | What triggers an opt-out | Sends after an opt-out | What reopens the contact |
|---|---|---|---|
| ZeroSettle | Any text with the word "stop" or one of about 58 opt-out phrases ("unsubscribe", "take me off your list", "wrong number"); quit and similar keywords as the whole text or its first sentence | Refused on every number (403); no override | START or unstop as the whole message, or ZeroSettle on request |
| Linq | STOP, UNSUBSCRIBE, OPTOUT, CANCEL, END or QUIT as the entire message, matched case-sensitively except opt out | Rejected on every line (403, error 2024); a single request can pass override_optout: true, and Linq records each use | Any later reply that is not itself an opt-out keyword |
| Sendblue | Built-in detection for stop, unsubscribe, cancel, opt out, revoke, end and quit; custom phrases through its support team | Not stated on its security page | start |
| Project Blue | "does not automatically detect or block STOP replies" | "no built-in suppression list on the API today" | Your own system decides |
ZeroSettle's rule catches "pls stop" and "please take me off your list", which whole-message lists miss, but also opts out people who did not mean it, and leaves "cancel" and "end" to you. Apple's policy for its separate Messages for Business channel names "unsubscribe" as the primary term and "spam", "stop" and "end" as alternatives; ZeroSettle is not Messages for Business and is not affiliated with Apple.
Gotchas: when "stop" doesn't mean stop
Because any text with the word "stop" opts the sender out of a ZeroSettle line, a customer who uses the word mid-conversation can't hear from you by text until they text START, though their own texts still reach you. Write prompts so nobody needs the word, and still act on what they asked.
- Learners. "Can we stop here?" mid-lesson opts a learner out; the language-learning voice lessons teach "pause" instead.
- Subscribers. "Stop my subscription" opts the customer out. Process the cancel anyway and confirm by email or in your app, because a confirming text returns
403. The skip, swap and reorder flow asks for SKIP. - Directions. "I'm at the bus stop" opts a pickup or delivery customer out mid-errand. Keep another way to reach them, such as a call or your app, for when a send returns
403. - Your own copy. Write "Reply PAUSE to pause", never "Reply STOP to pause", and tell the hosted agent the same in its business context.
- Testing. Texting "stop" from your own test number opts it out of every line; text START to undo it.
- Mon 9:02 AM
- Business: Hi Jordan, it's Harbor Coffee. Your next bag ships Thursday. Reply SKIP to skip it or SWAP to change roasts.
- Customer: can you stop the next one? traveling til the 20th
- Wed 7:45 PM
- Customer: START
- Business: Thanks, Jordan, you're back on Harbor Coffee texts. Thursday's bag is skipped as you asked, and the next one ships on the 24th.
403 recipient_opted_out, so the business skipped the bag and confirmed by email, adding that texting START turns texts back on.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; more in the reliability and trust hub). The 403 recipient_opted_out error and the opt-outs endpoint are documented in the errors, limits and compliance section of the docs; to try STOP and START on your own number, get a number.
Frequently asked questions
Does a ZeroSettle opt-out ever expire?
No. A STOP keeps blocking that person on every number on your account until they text START or unstop as the whole message, or ZeroSettle clears it at their request. Time alone never lifts it.
Can I send one confirmation text after someone texts STOP?
No. The FCC's rules generally allow one confirmation text with no marketing in it (presumed within consent if sent within five minutes), but ZeroSettle refuses every send to an opted-out person, so a confirmation from your code won't go out. Tell people how to opt back in before they need it, or confirm by email.
Can my team lift an opt-out, for example by deleting the conversation?
No. Neither the console nor the API can lift one, and deleting a conversation removes its stored messages but not the opt-out. Only the person texting START or unstop as the whole message, or ZeroSettle clearing it after the person asks another way, reopens them.
Does an opt-out survive if ZeroSettle replaces my number?
Yes. A STOP blocks every number on your account, and when ZeroSettle replaces the number behind a line, the line keeps its STOPs, conversations, name and photo. Only the number changes, so recipients see a new number.
Sources
- ZeroSettle iMessage API docs: "Errors, limits, and compliance" (STOP is enforced), "Webhooks, step by step", "Live stream (SSE)", "AI agent", "Sign in with iMessage" and "More than one number". Checked October 12, 2026.
- 47 CFR 64.1200, Delivery restrictions, paragraphs (a)(10) and (a)(12), the FCC's TCPA rules, Legal Information Institute. Checked October 8, 2026.
- Apple Messages for Business Policies, Apple. Checked October 8, 2026.
- Linq iMessage documentation, "Chat health: OPTED_OUT" and error 2024, Linq. Checked October 8, 2026.
- Security & Compliance, Sendblue Docs. Checked October 8, 2026.
- Managing Automations & STOP Replies on API-Only Integrations, Project Blue Support Docs. Checked October 8, 2026.
Changelog
- Added the opt-out phrases (such as "take me off your list" and "unsubscribe" anywhere in a text) that ZeroSettle now enforces.
- First published.