· 5 min · TextMeFlow Team

How to Send Bulk WhatsApp Reminders Without Triggering Broadcast Detection

You have 40 appointments tomorrow and want to remind every client tonight. The obvious approach — one loop, one hardcoded string, 40 recipients — is exactly the pattern that gets flagged. Not by us trying to be difficult: by the same signal Meta itself watches for. A single message body fanned out to a pile of numbers in a short window is the textbook definition of a broadcast, and broadcasts are what get WhatsApp numbers banned.

This guide covers the specific trigger, why it exists, and how to restructure a bulk send so it never fires.

The trigger, exactly

TextMeFlow's anti-spam pipeline watches for identical text sent to more than 5 distinct recipients within a 10-minute window. Cross that line and your account's risk score jumps by 25 points immediately. Keep doing it and the account gets throttled to 50% of its normal sending rate — on top of the score increase, not instead of it. Full detail on every trigger lives in the anti-spam guide; this is the one that catches the most well-intentioned bulk senders.

It's not about volume. Sending 40 different messages to 40 recipients in ten minutes is fine — that's what a busy front desk genuinely looks like. It's specifically sameness at scale that reads as bot behavior, because that's what a spam blast looks like from the outside: one body, many targets, tight timing.

Why this exists

WhatsApp doesn't ban accounts for sending a lot of messages. It bans accounts that behave like broadcast tools instead of like a person or business having individual conversations. A human sending 40 reminders would naturally vary the wording per person — different name, different time, different room. A script that concatenates a static template with zero variation is the one thing a real human conversation never produces. Meta's detection knows this, and so does ours — see the risk score breakdown for how points here compound with other triggers into a suspension.

Fix: template on real per-recipient fields

The fix isn't slower sending — it's a message body with real per-recipient content baked in, not just a name inserted for the sake of it.

const bookings = await getTomorrowBookings();

for (const booking of bookings) {
  const body = `Hi ${booking.firstName}, reminder for your appointment ` +
    `tomorrow at ${booking.time} (booking #${booking.reference}). ` +
    `Reply STOP to opt out.`;

  await fetch('https://api.textmeflow.eu/v1/messages', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.TEXTMEFLOW_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({ to: booking.phoneE164, text: body }),
  });
}

Name, time and booking reference are all fields you already have in your booking system — this isn't extra data entry, just wiring what you have into the template instead of hardcoding a flat string. Every message is now unique text, so the identical-content detector never sees a match, no matter how many recipients you loop through.

Good fields to vary on, roughly in order of how much they help:

  • Appointment time or date (almost always different per recipient anyway)
  • A booking/order/reference number
  • First name
  • Location, room number or service detail

Two of these is usually enough. You don't need a paragraph of personalization — Hi Sarah, your 14:30 slot tomorrow (ref #4821) is already unique enough to read as a real message rather than a template stamped out at scale.

Don't fight the pacing on top of it

Even with personalized bodies, consecutive sends from one account are spaced apart automatically — a random 20 to 90 second gap between messages by default (the first message in a batch always goes out immediately; only the ones after it queue). Don't try to route around this with parallel requests or multiple accounts to push 40 messages out in ten seconds; that just trades one detection trigger for another. Let the queue do its job — sent messages aren't lost, they're paced, and your loop above will finish well within the hour on any plan.

Check your risk score before it becomes a problem

You can see exactly where your account stands at any time:

curl -H "Authorization: Bearer $TEXTMEFLOW_API_KEY" \
  https://api.textmeflow.eu/v1/accounts/me

The response's risk_score field reflects the rolling 30-day window in real time — check it after your first bulk run to confirm the templating actually worked before you scale up to your full contact list. Details on every plan's hourly ceiling, which interacts with the same pipeline, are on the rate limits page.

tl;dr

  • More than 5 identical messages in 10 minutes = automatic risk-score hit, then throttling.
  • Fix is per-recipient content (name, time, reference), not slower code — the queue already paces sends for you.
  • Verify with GET /v1/accounts/me before you trust a bulk job at full volume.

Building a reminder flow and want the anti-spam pipeline handling this automatically instead of hand-rolling it? Start free — 50 messages a month, no card required, and the same rate limiting and pacing described here from message one.

Zelf WhatsApp-berichten versturen via API?

Gratis voor altijd tot 50 berichten/maand. QR scannen en binnen 5 minuten verstuur je je eerste bericht.

Gratis voor altijd