Use cases

Win back lapsed subscribers with a hosted iMessage AI agent

ZeroSettle lets a subscription app, meal kit or membership start iMessage conversations with its highest-value lapsed customers who opted in to marketing texts, and have the hosted AI agent (Beta) handle their objections and send a come-back checkout link. A nightly job picks the day's customers, and your server calls POST /api/imessage/agent/start for each during their daytime, up to the daily allowance: Pro's 5 new contacts a day is about 150 a month, and Growth allows 50 a day per number. By default the agent sends one follow-up the next morning (9 to 11 AM in its time zone) if they haven't replied.

Key takeaways

  • What it is: 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 hosted AI agent (Beta) runs each win-back conversation, so you need no webhook receiver, only a job that starts the conversations.
  • Who it fits: subscription businesses with lapsed customers whose marketing-text consent is on record, and something new to tell them.
  • Price: Pro is $49/month for one number with 1,000 AI credits a month and unlimited messages with people who message you first; Growth, for several numbers working as one, is from $599/mo with 5,000. Each text the agent sends uses one credit.
  • Main limit: 5 new contacts a day per number on Pro; 50 a day per number on Growth (3 per 15 minutes). On every plan, at most 2 messages to a customer can go unanswered.
  • What it does not do: there is no SMS fallback for customers who moved to Android, and the agent cannot apply a discount or restart a subscription. It sends the link you set.

Who uses iMessage for win-back?

iMessage win-back fits a subscription business with lapsed customers who agreed to marketing texts and a real reason to ask them back. Unlike a win-back email, a conversation lets the hosted AI agent ask why the customer left, answer that objection from your business context, and send the checkout link once they are interested.

  • Meal kits: the reason someone paused (price, portions, packaging) often has a concrete answer, such as a new box size, menu or liner.
  • Subscription apps: Apple's App Store Review Guidelines (3.1.3) say developers "can send communications outside of the app to their user base about purchasing methods other than in-app purchase", so the come-back text can point to a web checkout.
  • Memberships and subscription boxes that changed prices or perks since the customer cancelled.

It is for people who left weeks or months ago, not a failed card, a customer in your cancel flow or a user who just left the paywall.

How iMessage for win-back works, step by step

A nightly job chooses who to ask back, one API call starts each conversation, and ZeroSettle's hosted AI agent runs it from there.

  1. After the 3 AM Eastern reset, the job picks the highest-value lapsed customers with stored marketing-text consent, skipping anyone already asked back, reactivated or opted out anywhere.
  2. For each one, up to the day's allowance (5 on Pro, 50 on Growth), it calls POST /api/imessage/agent/start with their number and first name, during the customer's daytime.
  3. The agent sends your first_message: 1–3 texts, exactly as written, that say who you are, name what changed and end on a question. No link: a cold first text shows it as plain text (why first-message links aren't tappable).
  4. The agent answers each reply in up to three texts and never invents facts your business_context doesn't give. With goal set to purchase, it sends your come-back checkout link, tappable now that the customer has replied.
  5. If the customer goes quiet, the default follow-up trigger sends one follow-up a day after the last message, at a moment between 9 and 11 AM in the agent's time zone; the setup below moves it to the afternoon.
  6. The agent's texts follow the same rules as your own sends: a STOP blocks every number on the account, and on every plan at most two messages to a customer can go unanswered.

Ask what made them take a break, not why they stopped. ZeroSettle treats any text with the word STOP in it, or a clear request like "take me off your list", as an opt-out, so an answer like "had to stop, too pricey" opts them out on the spot, and only their own START opts them back in.

Example conversation: win-back

The opener is the same for every lapsed customer; the agent uses the name from its first answer on.

  1. Thu 11:00 AM
  2. FreshFork: Hi, it's FreshFork. We've missed you!
  3. FreshFork: We just added 15-minute dinners and a 2-person vegetarian box. What made you take a break?
  4. Customer: honestly all the packaging
  5. FreshFork: Fair, Leo. We switched to fully recyclable liners in July.
  6. FreshFork: Want your first box back at 50% off? freshfork.example.com/back
  7. Customer: ok trying it
Illustrative example with a fictional meal kit. Blue bubbles are the hosted AI agent texting from FreshFork's number; gray bubbles are the customer. The liner change and the offer come from the business context.

Setup: a nightly agent/start job

Setup is a business context, the agent settings and a two-part job. No webhook receiver is needed: on a line group Managed by AI Agent, the agent answers inbound texts instead of your webhook. Field names follow the AI agent section of the ZeroSettle docs.

1. Write the business context

The agent's facts come only from this text (up to 40,000 characters): what changed, the offer and its terms, and what it must never promise.

business_context.txt
You are FreshFork's assistant, texting former subscribers who agreed to
marketing texts. Ask what made them take a break (never "why did you
stop"), answer that, offer the come-back box. If they say no, thank
them and stop.

Changed since they left: recyclable liners (July); 15-minute dinners
and a 2-person vegetarian box (August).

Offer: 50% off the first box back, only through the link. Later boxes
renew weekly at the regular price; skip or cancel any week in the account.

Never promise more discounts, refunds or credits for past boxes, an old
price or a delivery date. Account questions: help@freshfork.example.com

2. Turn on the agent

Write the opener (the first two texts of the example above) in the console's Messaging tab, then send the rest with PUT /api/imessage/agent.

bash
jq -n --rawfile ctx business_context.txt '{
  managed_by: "zerosettle", business_context: $ctx,
  goal: "purchase", link: "https://freshfork.example.com/back",
  timezone: "America/New_York",
  triggers: [{id: "followup", repeat: "once", after_days: 1, at: "afternoon",
    instruction: "If they have not replied, send one short, no-pressure follow-up with no link that reads fine even if they already came back, e.g. that the 15-minute dinners are on the menu all month."}]
}' | curl -s -X PUT https://portal.zerosettle.io/api/imessage/agent \
  -H "Authorization: Bearer $ZEROSETTLE_TOKEN" -H "Content-Type: application/json" -d @-
  • A link-free follow-up instruction that reads fine either way: a customer who never replied would see a link as plain text, and one who bought without texting back still gets the follow-up, since the agent doesn't see your checkout.
  • at: "afternoon": the follow-up lands at a random moment between 1 and 3 PM in timezone (Eastern here), which is 10 AM to noon Pacific. triggers is always the whole list, so this replaces the default follow-up.
  • One link for everyone: have the checkout confirm the buyer is a lapsed customer, or a forwarded link gives anyone 50% off.

3. Plan at night, start in the daytime

The planner queues the day's customers for late morning in each one's time zone; a worker calls agent/start as they come due.

python
# winback.py: plan() nightly after 3 AM Eastern; start_due() every 5 minutes
import os
import requests

BASE = "https://portal.zerosettle.io"
TOKEN = os.environ["ZEROSETTLE_TOKEN"]
PER_DAY = 5                                   # Pro; 50 on Growth

def plan() -> None:
    for c in lapsed_customers(marketing_text_consent=True, opted_out=False,
                              asked_back=False, reactivated=False,
                              limit=PER_DAY):   # your DB, highest value first
        queue(c, send_at=local_time(c, hour=11))

def start_due() -> None:
    for c in due_from_queue():
        r = requests.post(f"{BASE}/api/imessage/agent/start",
                          headers={"Authorization": f"Bearer {TOKEN}"},
                          json={"to": c.mobile, "name": c.first_name}, timeout=180)
        if r.ok:
            c.mark_asked_back()               # one win-back per customer
            continue
        err = r.json().get("error") or {}
        if err.get("code") == "new_contact_limit":
            if err["window"] == "day":        # today's allowance is used
                clear_queue()                 # tomorrow's plan() picks them again
            else:                             # "15m": Growth allows 3 per 15 minutes
                c.requeue(seconds=err["retry_after_s"])
            break                             # the rest stay due for the next run
        elif err.get("code") == "recipient_opted_out":
            c.mark_opted_out()                # texted STOP: never retry
        else:
            alert(err.get("message") or r.text)   # e.g. 402 ai_credits_exhausted
            break

Limits and consent for win-back

Each lapsed customer counts once against ZeroSettle's new-contact limit, when the opener reaches them; the rest of the conversation never counts against it. AI credits are the second budget. The limits help keep the number out of Apple's spam filters.

ZeroSettle limits for win-back (API docs, checked October 12, 2026)
LimitProGrowth
Lapsed customers started per day, per number (3 AM to 3 AM Eastern)550
Started per rolling 15 minutes, per number—3
A month at the daily cap, per numberAbout 150About 1,500
Unanswered messages to one customer (texts within 5 minutes count as one)2, then 403 awaiting_reply, the agent included2, then 403 awaiting_reply, the agent included
AI credits included, per account1,000 a month5,000 a month

A failed send never counts as a new contact, and its AI credit comes back.

The limit math for a lapsed list

  • Reach: 3,000 opted-in lapsed customers take about 600 days at Pro's 5 a day, so a list that size belongs on Growth: 60 days at 50 a day on one number. At 3 per 15 minutes, a Growth number needs at least four hours to start its 50, which the worker's retries spread from 11 AM into the afternoon.
  • Credits: a two-text opener uses 2, the follow-up 1, each answer up to 3. Pro's five starts a day are 10 to 15 credits before any answers, or 300 to 450 a month, which leaves room in its 1,000 for answers. Growth's 50 a day on one number is 100 to 150 credits a day, or 3,000 to 4,500 a month before answers: close to its 5,000, so budget a pack or start fewer. With fewer credits left than the opener needs, agent/start sends nothing and returns 402 ai_credits_exhausted; at zero the agent also goes quiet in open threads.

Text only customers with stored consent to marketing texts, between 8 am and 9 pm in their time zone, the window the FCC also sets for telephone solicitations. If consent is old or unclear, recheck it by email or in your app: "If you are unsure whether you have consent, you don't." The iMessage TCPA consent guide has more. This section is general information, not legal advice; have counsel review your consent records and checkout.

  • A delivery number is not marketing consent. ZeroSettle's docs require a number given "for this purpose", and written consent for marketing texts under the TCPA.
  • Other channels' opt-outs are yours to exclude. ZeroSettle knows only the STOPs texted to your numbers, and the FCC lets consumers revoke consent "by using any reasonable method".
  • The checkout is a new sign-up. For an offer that renews automatically, the Restore Online Shoppers' Confidence Act requires the checkout to disclose all material terms, get express informed consent before charging, and offer a simple way to stop. This is not legal advice.

When ZeroSettle is not a fit for win-back

ZeroSettle is the wrong tool for win-back in these cases:

  • Consent is old or unclear. Recheck it first; ZeroSettle suspends lines used for unsolicited messaging.
  • You want to reach thousands of lapsed users a week from one number. One Pro number starts 35 a week, and one Growth number 350; the docs call the limits "a floor, not a licence".
  • Users on Android. There is no SMS fallback, so keep email for them. You can check whether a number is on iMessage before texting it, and the check sends nothing.
  • You need the agent to apply account credits itself. It can't touch your billing or accounts: it works from your business context and sends the link you set, and one link and context serve the whole line group.
  • Your one number already answers support from your server. On a group Managed by AI Agent, inbound texts skip your webhook and your sends get 403 managed_by_zerosettle. The docs add: "Do not send automated marketing into a support thread."

How much does iMessage for win-back cost?

Win-back on ZeroSettle costs the plan price plus any AI credits beyond the monthly allowance.

ZeroSettle plans for win-back (zerosettle.io and API docs, checked October 12, 2026)
OptionPriceAI credits
Pro$49/month, one number to start, 5 new contacts a day, unlimited messages with people who message you first, no setup fee1,000 a month
GrowthFrom $599/mo, several numbers working as one5,000 a month
AI credit pack1,000 for $50 or 5,000 for $200, paid onceNever expire

Monthly credits don't carry over. Both plans have a 30-day money-back guarantee on the subscription. Get a Pro number, book a Growth demo, see ZeroSettle pricing, or browse the iMessage use-case hub.

Frequently asked questions

Does the agent know the customer's history, or that they bought?

No. It works from your business context, its settings, the conversation, the current time and the first name you passed. It learns why they left by asking and doesn't see your checkout, so the nightly job must skip anyone who already reactivated.

Can the agent send more than one follow-up?

Not to someone who hasn't answered. The opener and one follow-up already make two unanswered messages, so on every plan a third is refused until they reply. You can add up to 5 triggers, but each follows that rule. The docs call repeated messages to people who never answer "the fastest way to get a number flagged by Apple".

How do I copy STOPs into my CRM?

Read GET /api/imessage/opt-outs in the nightly job; it lists every handle that texted STOP, with opted_out_at. On an agent-managed line your webhook isn't called, so this list, or the live stream's optout events, is how your systems hear about a STOP.

Sources

  1. ZeroSettle iMessage API docs: "AI agent", "Links in a first message", "Customer support" and "Errors, limits, and compliance". Checked October 8, 2026.
  2. ZeroSettle iMessage API Terms of Service, section 13 (opt-in and prohibited uses). Last modified September 28, 2026.
  3. 47 CFR 64.1200, Delivery restrictions, the FCC's TCPA rules: written consent (a)(2), revocation (a)(10), calling hours (c)(1) and texts to wireless numbers (e) (Legal Information Institute). Checked October 8, 2026.
  4. 15 U.S.C. 8403, Negative option marketing on the Internet, the Restore Online Shoppers' Confidence Act (Legal Information Institute). Checked October 8, 2026.
  5. App Store Review Guidelines, guideline 3.1.3 (Other Purchase Methods), Apple Developer. Checked October 8, 2026.

Written by the ZeroSettle team. 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.

Product facts come from the ZeroSettle iMessage API docs, the zerosettle.io homepage and the iMessage API Terms as of October 12, 2026. FreshFork is a fictional meal kit used for illustration, and nothing here is legal advice.

Text your customers from your own iMessage number

ZeroSettle gives your business its own phone number on real iMessage, running on Apple hardware we operate for you in a server facility. Your code sends with one API call and hears every reply on a signed webhook.

Pro is $49 a month with a 30-day money-back guarantee. Growth, for several numbers working as one, is from $599/mo.