This is not optional timing trivia
WhatsApp treats rapid, repeated OTP traffic from one linked number as spam risk. If your backend fires many POST /api/v1/send calls in parallel (retries, load tests, double-clicks, or a loop without a queue), you are asking for a ban on the business line you linked in the dashboard.
Zindua’s anti-ban layer paces WhatsApp delivery for you. After a successful WhatsApp send, wait at least 3 seconds before the next WhatsApp send for the same project. If you ignore that gap, you will see errors like: Wait Xs before sending another WhatsApp OTP.
- Minimum 3 seconds between WhatsApp sends (same project)
- Do not burst concurrent /send calls for WhatsApp
- Prefer a queue or debounce in your app for resend / load tests
- Zindua workers also pace; your app must still respect the gap
What Zindua does vs what you must do
On our side, the anti-ban robot applies a minimum interval and per-minute caps so one noisy client cannot melt a linked session. That protects every project on the platform, including yours.
Official SDKs (Node, PHP, Python, .NET) mirror that robot client-side: by default they wait ≥3s between WhatsApp sends on the same client instance and print a warning so developers learn to space traffic. On your side, still treat WhatsApp OTP like a rate-limited API: serialize bursts, use a queue or debounce, and map wait messages to clear UX.
Node.js / TypeScript
Use a short sleep between scripted sends, or a Redis/memory lock on your OTP resend endpoint so users cannot hammer WhatsApp.
import { Zindua } from "@zindua/sdk";
const zindua = new Zindua({ apiKey: process.env.ZINDUA_API_KEY! });
await zindua.send({
to: "+243812345678",
channel: "whatsapp",
template: "otp-verification",
lang: "fr",
variables: { code: "482910" },
});
// Required before the next WhatsApp send (same project)
await new Promise((r) => setTimeout(r, 3000));
await zindua.send({
to: "+243812345678",
channel: "whatsapp",
template: "otp-verification",
variables: { code: "991002" },
});PHP / Laravel
sleep(3) works for CLI smoke tests. In Laravel, prefer a cache lock that returns 429, or dispatch a delayed job. Do not block the user request for three seconds on every resend.
use Zindua\Client;
$zindua = new Client(['apiKey' => getenv('ZINDUA_API_KEY')]);
$zindua->send([
'to' => '+243812345678',
'channel' => 'whatsapp',
'template' => 'otp-verification',
'variables' => ['code' => '482910'],
]);
sleep(3); // scripts / CLI only
$zindua->send([
'to' => '+243812345678',
'channel' => 'whatsapp',
'template' => 'otp-verification',
'variables' => ['code' => '991002'],
]);
// Laravel (recommended): Cache::add('zindua:wa:'.$phone, 1, now()->addSeconds(3))
// or dispatch(new SendWhatsappOtp(...))->delay(now()->addSeconds(3));Python
Same rule: one WhatsApp send, then wait (or enqueue) before the next. FastAPI endpoints should reject rapid resends with HTTP 429 instead of sleeping inside the request when traffic is interactive.
import os, time
from zindua import Zindua
zindua = Zindua(api_key=os.environ["ZINDUA_API_KEY"])
zindua.send(
to="+243812345678",
channel="whatsapp",
template="otp-verification",
variables={"code": "482910"},
)
time.sleep(3) # scripts / batch only
zindua.send(
to="+243812345678",
channel="whatsapp",
template="otp-verification",
variables={"code": "991002"},
)C# / ASP.NET Core
Use Task.Delay in tools and tests. In production, gate resend with a distributed lock or a background queue so concurrent requests cannot stampede the linked WhatsApp line.
await zindua.SendAsync(new ZinduaSendOptions
{
To = "+243812345678",
Channel = "whatsapp",
Template = "otp-verification",
Variables = new Dictionary<string, string> { ["code"] = "482910" },
});
await Task.Delay(TimeSpan.FromSeconds(3));
await zindua.SendAsync(new ZinduaSendOptions
{
To = "+243812345678",
Channel = "whatsapp",
Template = "otp-verification",
Variables = new Dictionary<string, string> { ["code"] = "991002" },
});Integration checklist
If your load test or “resend OTP” button ignores the gap, Zindua will pace or reject, and aggressive bypass attempts put the linked number at ban risk. Build the 3-second rule into your product UX from day one.
- Resend button disabled or countdown ≥ 3s
- No parallel WhatsApp send loops in CI without delays
- Handle Wait Xs before sending another WhatsApp OTP in the client
- Queue bulk WhatsApp jobs with spacing; never fire-and-forget bursts