Prevent OTP API Abuse
If scripts repeatedly hit your OTP send flow, users receive floods of unwanted codes, account balance is consumed quickly, and channel reputation can drop. EngageLab OTP can limit sending frequency and volume, but it cannot stop an unauthenticated "Get verification code" endpoint in your application.
This article explains how to combine platform capabilities with application-side protections to reduce API abuse.
Correct architecture
The EngageLab OTP API must be called only from your server. Do not call it directly from a browser, mobile app, or mini program.
User → Your frontend (sign-in / sign-up / reset password)
→ Your backend (session check, CAPTCHA, business rate limits)
→ EngageLab OTP API (with API Key and end_user_ip)
- Store
dev_keyanddev_secretonly on the server. Do not put them in frontend code, app packages, or public repositories. - The frontend should call only your own "Get verification code" API. Do not call
https://otp.api.engagelab.ccdirectly. - For production API Keys, configure a caller IP whitelist. See API Key.
Do not mix the two types of IP
| Setting / parameter | What to enter | What it blocks |
|---|---|---|
| API Key IP whitelist | Your server egress IP | Unknown IPs calling the OTP API with a leaked Key |
end_user_ip in the send request |
The end user's IP | The same user IP requesting codes repeatedly in a short time |
After you enable "By IP address" limits in Security Center, you must pass end_user_ip in the Send OTP request for the limit to take effect. Pass the user's public IP, not your server IP.
Platform-side protections
Complete the following configuration in the OTP console to limit damage if sending is abused:
| What to do | Where | Purpose |
|---|---|---|
| Set an IP whitelist and expiry for the API Key, and keep it easy to disable | API Key | Restrict who can call the API; disable it immediately if leaked |
| Enable sending frequency limits for the same number and same IP | Security Center | Block repeated sends to one number or from one IP |
Pass end_user_ip in the send request |
Send OTP | Make IP-based rate limiting take effect |
| Set daily / monthly warning and quota values | Security Center | Alert or auto-pause when volume is abnormal |
| Set a country / region whitelist or blacklist | Security Center | Avoid sending to countries outside your business |
| Pause the SMS channel in an emergency | Security Center | Stop loss quickly while abuse is happening |
To receive notifications when a warning or quota is reached, first configure the callback event in Webhook.
Application-side protections
Platform rate limits cannot replace protection on your own "Get verification code" API. Complete these checks before calling EngageLab:
- Run a CAPTCHA (such as an image CAPTCHA, Turnstile, or reCAPTCHA) before sending a code, and verify the result on the server.
- Set a resend interval for the same phone number (for example 60 seconds) and show a countdown on the frontend.
- Limit requests per account, device, and IP by minute, hour, and calendar day. Count failed requests as well.
- "Get verification code" must include a signed-in session, or a valid session in unsigned-in flows. Do not expose a public send endpoint with no context.
- Limit verification attempts for the same code and invalidate it immediately after a successful check. EngageLab OTP does not allow a successfully verified code to be verified again.
Treat error codes as abuse signals
Send OTP may return the following errors during pre-send validation. When you see them, slow down retries and check for concentrated traffic:
| Error code | HTTP status | Meaning |
|---|---|---|
3004 |
400 | Frequency limit exceeded for the same template and same recipient; the window follows the template configuration |
6001 |
429 | Sending frequency for the same phone number exceeded; the window may be minute, hour, or calendar day |
6002 |
429 | Sending frequency for the same end-user IP exceeded; checked only when end_user_ip is passed |
6003 |
429 | The application's global daily or monthly send volume reached the cap |
6007 |
403 | SMS OTP sending is paused, for all countries / regions or the current one |
Do not retry immediately in a tight loop when you receive HTTP 429. If it continues, first check Security Center for a volume quota or Emergency Stop, then contact support.
What to do if a secret is leaked
- In the OTP console, disable or rotate the API Key.
- In Security Center, use Emergency Stop to pause SMS sending.
- Review abnormal sends in History and callbacks.
- Tighten the API Key IP whitelist and check whether daily / monthly quotas are reasonable.
- Resume sending only after the risk is gone.
Launch checklist
- The API is called only from the server.
dev_secretis not in the frontend, app, or a public repository. - The production API Key has a server egress IP whitelist.
- Security Center number frequency limits are on; send requests include
end_user_ipwhen you need IP limits. - Daily / monthly send quotas are set, and volume-related callbacks are configured.
- The "Get verification code" API runs CAPTCHA and business rate limits before calling EngageLab.
- You know the abuse response order: disable the Key → Emergency Stop → review send records.










