Sub-three-second OTP delivery across every Kenyan carrier — the fastest verification rail in the country. Login, password reset, transaction approval, KYC. One API, transactional sender, audit log of every code.
OTP rides on the same transactional SMS rail as your other alerts — same endpoint, same sender ID, same delivery webhook.
Generate a 4–6 digit code in your backend. Hash it, store it with the user ID and an expiry (recommend 5 minutes). Never log the raw code.
POST to /v1/messaging with type: "transactional" and your bank/app sender ID. Median delivery on Safaricom is under 3 seconds.
Customer enters the code, you compare the hash, mark single-use, increment fail counter. Webhook confirms delivery for audit.
Safaricom routes are tuned for transactional SMS. Most OTPs arrive faster than the customer can switch apps.
Use your bank, fintech or app name as the visible sender. Customers recognise it instantly — reduces phishing-fatigue dismissals.
Carrier hiccups get retried automatically. Permanent failures (invalid number, DND) surface immediately on the webhook so you can fall back to email or voice.
Every OTP send is logged with timestamp, sender, recipient, message ID and delivery state. Exportable for ISO 27001 / PCI / NCA audits.
Separate dev, staging, production projects — each with its own Bearer key, callback URL and balance. Rotate any key instantly.
Webhook fires the moment the carrier confirms delivery. Use to decide when to allow OTP entry or escalate to a fallback channel.
The shape is identical to any other transactional send — type: "transactional", your sender ID, the code in the message body. We handle priority routing on the backend.
project in body authenticates the request# Send a verification code
curl -X POST "https://api.sozuri.net/v1/messaging" \
-H "Authorization: Bearer $SOZURI_API_KEY" \
-d '{
"project": "Bidii Bank",
"from": "BIDII BANK",
"to": "+254712345678",
"channel": "sms",
"type": "transactional",
"message": "Your Bidii Bank verification code is 4821. Expires in 5 minutes. Never share this code.",
"campaign": "login-otp"
}'
404 "Project not found." — check the project name (case-sensitive). 400 "Unknown project." — API key doesn't match. 401 "Unauthenticated." — no token at all. Rotating a key invalidates the old one immediately with no overlap window.
Two-factor authentication, reset codes, suspicious-login challenges. The minimum bar for any app handling money.
Step-up auth for transfers over a threshold, beneficiary additions, card disputes. Audit-logged for regulator inspection.
Confirm phone ownership at signup. Same flow whether the customer is on Safaricom, Airtel or Telkom.
No — OTP rides on the standard /v1/messaging endpoint with type: "transactional". Sozuri prioritises transactional routes on the backend, so OTPs hit the front of the carrier queue.
By design, no. Generate, hash and store the code on your side — that way the cleartext code never crosses Sozuri's storage. We send what you compose; you control entropy, format, expiry and rotation.
From the project dashboard, click Regenerate. The new key is immediately active and the old one is revoked. Plan a brief deploy window; there is no overlap period.
The webhook fires with a non-success status and a descriptive code. Best practice: on permanent failure (invalid number, DND, blacklist), fall back to a voice OTP or email immediately rather than retrying SMS.
SMS reaches every Kenyan phone, online or offline, smartphone or feature. For authentication, that's the only reach metric that matters.