Use cases

How to ask for Google reviews over iMessage, without review gating

With ZeroSettle, a local business asks for Google reviews over iMessage in two steps: a question with no link in the customer's existing thread ("How did Maria and the team do today?"), then the Google review link once the customer replies, when their iPhone shows it as a link they can tap. The link goes to everyone who replies, happy or not, because Google's review policy forbids asking only happy customers and the FTC has said this "review gating" can violate the FTC Act. Customers who already have a thread with you from booking or reminders don't count toward the Pro plan's 5 new contacts a day.

Key takeaways

  • What it is: a review request in two steps, a question with no link and then your Google review link, sent from your business's own iMessage number through ZeroSettle's REST API. Replies arrive on a signed webhook.
  • The rule: everyone who answers gets the same link. Your code sends it without looking at what the customer said.
  • Price: Pro is $49/month and starts with one number, with unlimited messages with people who message you first. Growth, for several numbers working as one, is from $599/mo. There are no per-message fees.
  • Main limit: asking a customer your number has never texted uses one of Pro's 5 new contacts for the day. Customers already in a thread don't count.
  • What it does not do: there is no SMS fallback for Android customers, and the API doesn't schedule sends. Your CRM or POS decides when to ask.

Who uses iMessage for review requests?

iMessage review requests fit local service businesses that depend on Google reviews and already text their customers: cleaning companies, contractors, salons, and restaurants that take bookings by text. 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.

The problem: an emailed request competes with the whole inbox, and a review link texted from an unknown number can look like phishing and, on an iPhone, can't be tapped. A question in a thread the customer already knows avoids both. ZeroSettle is a poor fit if most of your customers use Android (see when ZeroSettle is not a fit). This is one of the 50 ways businesses use iMessage.

How iMessage review requests work, step by step

A ZeroSettle review request is one question with no link when the job closes, then one link after the customer answers. Every answer gets the same link.

  1. A job closes in your CRM or POS. Between 8 am and 9 pm in the customer's time zone, your code sends a plain question people answer through POST /api/imessage/send: "How did Maria and the team do today?" Outside those hours, the question waits until 8 am.
  2. The question has no link, because an iPhone shows a link as plain text until the customer has replied to your number or saved it. A link sent to someone who has never texted your number still goes out, and the API adds warning.code: "link_not_tappable" to the response (why links in a first iMessage aren't tappable).
  3. The customer answers. ZeroSettle posts a signed message.received event to your webhook about 1–2 seconds after the line receives the text. A tapback on the question arrives as reaction.received.
  4. Your code sends the Google review link to everyone who answered, with the same text. A 👎 gets exactly what a ❤️ gets.
  5. Every answer also goes to the owner, who handles complaints from the ZeroSettle console. A complaint never holds the link back.
  6. A ❤️ on the link itself arrives as reaction.received. Count it as engagement, not as proof of a review.

Customers who opted in when they booked usually already have a thread from appointment reminders or on-the-way texts, so the question uses none of your new-contact allowance.

Why asking first is not review gating

Asking first is fine; filtering who gets the link by their answer is not. The FTC describes gating like this:

Review gating occurs when a business asks past purchasers to provide feedback on a product and then invites only those who provide positive feedback to post online reviews on one or more websites.

Federal Trade Commission, final rule on consumer reviews (2024), quoting its 2023 proposal

The 2024 rule doesn't ban gating by name, but the Commission wrote that it "can nonetheless violate Section 5 of the FTC Act", and its guide for marketers says "Don't ask for reviews only from customers you think will leave positive ones." Google's policy says merchants may not "selectively solicit positive reviews from customers". So the code that sends the link never reads the answer.

Example conversation: review requests

The same flow with a happy customer and an unhappy one. Both get the same link.

  1. Thu 4:12 PM
  2. Business: Hi Rosa, it's Sparkle Home Cleaning. Thanks for having us today! How did Maria and the team do?
  3. Customer: honestly the house looks amazing
  4. Business: Thank you for telling us, Rosa. If you have 30 seconds, an honest Google review helps a small team like ours: reviews.example.com/sparkle❤️
  5. Customer: done!
Illustrative example with a fictional cleaning company. Blue bubbles come from the company's number; gray bubbles are the customer's.
  1. Thu 5:40 PM
  2. Business: Hi Dan, it's Sparkle Home Cleaning. Thanks for having us today! How did Maria and the team do?
  3. Customer: kitchen looks great but the upstairs bathroom got skipped
  4. Business: Thank you for telling us, Dan. If you have 30 seconds, an honest Google review helps a small team like ours: reviews.example.com/sparkle
  5. Business: This is Jen, the owner. Sorry about the bathroom. Can we come back tomorrow morning to finish it?
  6. Customer: tomorrow at 9 works
Illustrative example. Dan gets the same link as Rosa. The owner typed her follow-up in the ZeroSettle console.

Setup: a job-close trigger and a reply router

A ZeroSettle review flow needs two pieces of code: a function your CRM or POS calls when a job closes, and a webhook receiver that sends the link after any answer, text or tapback. Copy your review link from your Google Business Profile: Read Reviews, then Get more reviews, then the copy icon (Google's steps).

python
# reviews.py: run with  uvicorn reviews:app --port 8100
import hashlib, hmac, json, os, time
from datetime import datetime
from zoneinfo import ZoneInfo
import requests
from fastapi import BackgroundTasks, FastAPI, Request, Response

BASE = "https://portal.zerosettle.io"
TOKEN, SECRET = os.environ["ZEROSETTLE_TOKEN"], os.environ["ZEROSETTLE_WEBHOOK_SECRET"]
LINK = os.environ["GOOGLE_REVIEW_LINK"]
app, asked, seen = FastAPI(), {}, set()   # asked: E.164 phone -> visit (use your database)

def send(to, text):
    return requests.post(f"{BASE}/api/imessage/send", json={"to": to, "text": text},
                         headers={"Authorization": f"Bearer {TOKEN}"}, timeout=90).json()

def on_job_closed(visit):                 # call this from your CRM or POS
    if not 8 <= datetime.now(ZoneInfo(visit["tz"])).hour < 21:
        return queue_for_8am(visit)       # 8 am to 9 pm, the customer's time zone
    asked[visit["phone"]] = visit
    r = send(visit["phone"], f"Hi {visit['name']}, it's Sparkle Home Cleaning. Thanks for having us "
                             f"today! How did {visit['lead']} and the team do?")
    if not r.get("ok"):                   # e.g. 429 new_contact_limit: nothing was sent,
        asked.pop(visit["phone"], None)   # so a later text from them gets no link

def on_answer(m):                         # a text or a tapback, whatever it says
    visit = asked.pop(m["handle"], None)  # one link per visit
    if visit:
        notify_owner(visit, m)
        send(m["handle"], f"Thank you for telling us, {visit['name']}. If you have 30 seconds, "
                          f"an honest Google review helps a small team like ours: {LINK}")

def verify(header, raw):                  # from the ZeroSettle docs
    try:
        parts = dict(p.split("=", 1) for p in header.split(","))
        t, v1 = int(parts["t"]), parts["v1"]
    except Exception:
        return False
    if abs(time.time() - t) > 300:
        return False
    expected = hmac.new(SECRET.encode(), f"{t}.".encode() + raw, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, v1)

@app.post("/webhook")
async def webhook(request: Request, tasks: BackgroundTasks):
    raw = await request.body()
    if not verify(request.headers.get("X-ZeroSettle-Signature", ""), raw):
        return Response(status_code=401)
    ev = json.loads(raw)
    if ev["event"] in ("message.received", "reaction.received"):
        key = (ev["message"]["id"], ev["event"])   # retries repeat the id and event
        if key not in seen:
            seen.add(key)
            tasks.add_task(on_answer, ev["message"])
    return Response(status_code=200)

def notify_owner(visit, m): print("answer:", m["handle"], m.get("text") or m.get("reaction"))
def queue_for_8am(visit): print("hold until 8 am:", visit["phone"])   # your job queue

Register the receiver with PUT /api/imessage/webhook and store the signing secret it returns, because ZeroSettle shows it only once. The webhook steps in the ZeroSettle docs cover retries and testing.

Limits and consent for review requests

A review request uses ZeroSettle's new-contact allowance only when the question goes to a customer your number has never texted, and then only once. The link and every tapback never count.

What a review request uses of the Pro plan's new-contact allowance (ZeroSettle API docs, checked October 12, 2026)
MessageCounts as a new contact?
Question to a customer who texted your number firstNo, never limited
Question to a customer you already text (reminders, on-the-way texts)No, an ongoing conversation
Question to a customer your number has never textedYes, once: 5 a day per number
Review link after they answerNo
Tapbacks, either wayNever

The day runs from 3 AM to 3 AM Eastern. Growth allows 50 new contacts a day and 3 per 15 minutes, per number.

For example, a cleaning company closes 14 jobs on a Thursday. Twelve customers got yesterday's reminder from the same number. Two booked with a phone call, agreed to texts, and haven't been texted yet. The twelve don't count, and the two use 2 of Pro's 5 for the day.

Ask once per visit, with no nudges. Both plans refuse a third unanswered message to a contact with 403 awaiting_reply, and the sample goes further: it sends the question once per closed job, never follows up, and asked.pop allows one link per visit.

Consent comes first

Text only existing customers who gave you their number for texts about their visit, keep the record, and say who you are. A review request may be treated as promotional, so send it between 8 am and 9 pm in the customer's time zone. ZeroSettle enforces STOP across every number on your account; see iMessage and TCPA consent. This isn't legal advice; rules vary by place and purpose.

When ZeroSettle is not a fit for review requests

ZeroSettle is the wrong tool for review requests when:

  • You want to send review links only to happy customers. That is review gating. Google's policy prohibits it, and the FTC has said it can violate the FTC Act (this isn't legal advice).
  • You want to offer a discount for a review. Google prohibits incentives for reviews, and the FTC's 2024 rule bans incentives conditioned on a review's sentiment.
  • You want one text to every customer from the past year. They didn't opt in to this, unsolicited volume gets a number filtered, and on Pro each customer your number has never texted uses one of 5 new contacts a day.
  • Most of your customers use Android. There is no SMS fallback, so ask those customers by email.
  • Your review platform's own requests already bring in the reviews you need. A second ask over iMessage would mean two requests for one visit.

To score service rather than collect reviews, see customer feedback over iMessage.

How much does iMessage for review requests cost?

Review requests cost only the plan price. ZeroSettle has no per-message fees, and messages are unlimited (but counted).

ZeroSettle plans (zerosettle.io, checked October 12, 2026)
PlanPriceFits
Pro$49/monthOne number to start, first messages to 5 new contacts a day, unlimited messages with people who message you first, self-serve, no setup fee
GrowthFrom $599/moSeveral numbers working as one, set up after a demo

Both plans have a 30-day money-back guarantee on the subscription. See the plans on zerosettle.io for full details.

Frequently asked questions

Does a ❤️ tapback make the review link tappable?

That isn't documented. ZeroSettle reports the tapback as reaction.received, but nothing documents whether iOS counts a tapback alone as a reply when it decides if a link is tappable. When the link matters, ask a question that invites a short text reply.

Can the review request name the technician?

Yes, in the question ("How did Maria do?"). Don't ask the customer to mention Maria in the review, though. Google's policy says merchants shouldn't request specific review content, such as naming a staff member.

What happens if a customer answers with STOP?

A text with the word STOP, or a clear request like "take me off your list", opts the customer out of every number on your account. ZeroSettle then refuses the review link with 403 recipient_opted_out and sends nothing. Only texting START opts them back in.

Sources

  1. ZeroSettle iMessage API docs: "Send a message", "Links in a first message", "Reactions (tapbacks)", "Webhooks, step by step" and "Errors, limits, and compliance". Checked October 12, 2026.
  2. Prohibited and restricted content, Maps User Generated Content Policy Help, Google ("Rating manipulation"). Checked October 8, 2026.
  3. Create a Google link or QR code to request reviews, Google Business Profile Help. Checked October 8, 2026.
  4. Trade Regulation Rule on the Use of Consumer Reviews and Testimonials (16 CFR Part 465), final rule and Statement of Basis and Purpose, Federal Trade Commission. Checked October 8, 2026.
  5. Federal Trade Commission Announces Final Rule Banning Fake Reviews and Testimonials, FTC press release, August 14, 2024. Checked October 8, 2026.
  6. Soliciting and Paying for Online Reviews: A Guide for Marketers, Federal Trade Commission, January 2022. 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 on this page come from the ZeroSettle iMessage API docs and zerosettle.io as of October 12, 2026. Google's and the FTC's rules come from their own pages, checked October 8, 2026. Sparkle Home Cleaning is a fictional business and reviews.example.com a placeholder link, 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.