Apps · OTP Hub
OTP Hub
Send one-time verification codes to your customers on WhatsApp from Inboxi's verified number, with one API call to send and one to check.
OTP Hub verifies your users' phone numbers on WhatsApp for sign-up, login, password reset, checkout or any sensitive action. You don't need a WhatsApp number, a Meta Business verification or an approved template. Inboxi sends the code from its own dedicated and verified number. It generates the code, stores only a hash of it, handles expiry and limits retries. Your backend makes two calls.
Get started
- 1Install OTP HubGo to Settings › Apps and click Install on OTP Hub.
- 2Create an API keyOn the OTP Hub page, open API keys and click Create. Copy the key right away, because it is shown only once. These keys can only use OTP Hub.
- 3Try itIn Try it, send a code to your own WhatsApp and verify it, or turn on test mode to get the code back without sending anything.
- 4Call the API from your server
X-API-Key header from your backend only. If you put it in a mobile app or website code, anyone can use it to send codes on your account.A complete sign-in flow
Send the code and keep the returned id with the user's session:
curl -X POST "https://inboxi.app/api/v1/otp/send" \
-H "X-API-Key: inx_live_your_otp_hub_key" \
-H "Content-Type: application/json" \
-d '{
"phone": "201012345678",
"language": "ar"
}'When the user submits the code, check it with the same id:
curl -X POST "https://inboxi.app/api/v1/otp/verify" \
-H "X-API-Key: inx_live_your_otp_hub_key" \
-H "Content-Type: application/json" \
-d '{
"id": "otp_5f0c2a9e41b7d3c8a6e2f019",
"code": "482913"
}'{
"success": true,
"data": {
"valid": true,
"reason": null,
"id": "otp_5f0c2a9e41b7d3c8a6e2f019",
"status": "verified",
"attempts": 1,
"attemptsLeft": 4,
...
}
}Allow the action only when valid is true. When valid is false, the reason field tells you what to show the user. The full list is in the API reference.
Which number sends the codes
When you install OTP Hub you choose the number your users receive codes from. You can change it any time in OTP Hub › Settings › Sending number.
| OTP Hub's verified number | Your WhatsApp number | |
|---|---|---|
| Setup | None | Your number must be connected to the workspace. We create the verification template inboxi_otp_code on it, and Meta must approve it before codes go out |
| Who pays | Your Inboxi wallet, one price per code | Meta bills your WhatsApp account directly. OTP Hub charges nothing |
| Sender name | OTP Hub | Your business |
| Your number's limits | Not used | Each code counts toward your number's daily messaging limit |
| Other codes from your workspace | Salla login codes and code events (events marked sensitive) are sent from the OTP Hub number too, and billed the same way | Keep going from your number, as before |
Every response and log row says where a code went: from is otp_hub or own_number, and billing is own_number for codes sent from your number.
The message your users receive
Codes go out as a WhatsApp authentication message from the number you chose. Meta fixes this message format: the code, a short security note and a Copy code button. The text cannot be changed and cannot include your company name (from your own number, WhatsApp shows your business as the sender). Tell your users on your verification screen where to look, for example: "We sent a 6-digit code on WhatsApp from OTP Hub."
| Setting | Value |
|---|---|
| Code | 6 digits, random |
| Expires | 10 minutes after it is sent |
| Verify attempts | 5 per code. After that, request a new code |
| New code | Cancels the previous code for the same number, so only the latest code works |
| Language | Arabic or English template. Pass language: ar or en |
Protection and limits
- At most 5 codes per phone number per hour and one code every 30 seconds to the same number. Above that you get
429with aRetry-Afterheader. - A daily limit for your whole workspace (1,000 codes by default; change it in Settings). This stops someone from using your sign-up page to send thousands of codes and drain your wallet. Above it you get
429 DAILY_LIMIT_REACHED. - Allowed countries (optional): if you only serve some countries, list their calling codes in Settings. Numbers anywhere else are refused with
403 COUNTRY_NOT_ALLOWEDand are not charged. - OTP Hub API keys allow 120 requests per minute each.
- Only a hash of each code is stored. Nobody can read the codes, not even Inboxi.
- Paid codes need enough wallet balance, so nobody can run up charges beyond what you have added.
Test mode
Pass "test": true to /send. No message is sent and nothing is charged. The code comes back in the response (data.code) so automated tests can verify it. Test requests appear in the log marked Test and do not count toward the per-phone limits.
The OTP Hub page
| Tab | What it shows |
|---|---|
| Overview | Your wallet balance, the price per message and roughly how many messages the balance covers, with a Top up button. Below that: this month's codes sent, delivered, verified, verification rate and spend, and today's count against your daily limit. |
| API keys | Create and revoke OTP Hub keys. |
| Try it | Send a real or test code and verify it, with the raw API response. |
| Logs | Every code: masked number, status, delivery, billing and price. |
| Settings | The sending number (OTP Hub's or yours), daily limit, allowed countries, the low-balance alert, and a link to set up webhooks. |
Webhooks
To have Inboxi tell your server what happens to each code, subscribe a URL to these events inSettings › Developer Hub › Webhooks. Deliveries are signed like every Inboxi webhook (see Webhooks). The payload is the request object plus the full phone. It never includes the code.
| Event | When |
|---|---|
otp.sent | WhatsApp accepted the message |
otp.delivered | The message reached the phone |
otp.failed | WhatsApp could not deliver it. A paid message is refunded. Includes reason |
otp.verified | The user entered the right code |
Safe retries
If your server might retry a send (for example after a timeout), add an Idempotency-Key header with a value that is unique for that attempt, such as your sign-up id. A repeat with the same key within 24 hours does not send another code. Instead, it returns the first request with "replayed": true, status 200 and the header Idempotent-Replayed: true.
Terms of use
When you install OTP Hub, you agree to these terms. Inboxi can suspend the app for any workspace that breaks them.
- OTP Hub is for one-time verification codes only. No marketing, promotions or other content.
- Send a code only to a person who asked for it on your site or app, for their own number.
- Protect the page that requests codes against automated abuse (for example with a CAPTCHA), and keep a daily limit that fits your traffic.
- Codes come from the shared OTP Hub number in Meta's fixed authentication wording, without your company name. Tell your users where to look.
- Misuse that harms the number's quality or other customers (spam, bulk sends to numbers that did not ask) leads to suspension without a refund of the affected usage.
Best practices
- Verify with the
idfrom/send, not the phone. That way a user can never confirm a different request. - Show a 30-second countdown before you enable "Resend code".
- If you get
NOT_ON_WHATSAPP, offer the user email or SMS instead. - Never log or store the code in your own system. You don't need it, because OTP Hub checks it for you.
- Use test mode in development and CI. Use a real send only for a final check.