OTP
Zend OTP is a secure one-time password service for verifying phone numbers over SMS and WhatsApp. Send a code, let Zend handle generation, delivery, expiry, and attempt limits, then verify the code your user entered — no need to store or manage codes yourself.
What Zend OTP does
Zend OTP generates a random code, delivers it to a phone number over your chosen channel, and tracks its lifecycle. You send a request to create the OTP, then verify the code the user submits. Zend enforces expiry, caps verification attempts, and cleans up expired codes automatically.
- SMS & WhatsApp — deliver codes over either channel.
- Configurable — set the expiry window and code length per request.
- Secured by default — rate limiting, attempt limits, and automatic expiry.
- Trackable — check status and remaining attempts at any time.
Authentication
All requests authenticate with your API key in the x-api-key header:
-H "x-api-key: YOUR_API_KEY"
Quickstart
1. Send an OTP
Create and deliver a code to a phone number. channel selects the delivery method, and expiry and length are optional.
curl -X POST https://api.tryzend.com/otp/send \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone_number": "+233201234567",
"app": "my_ecommerce_app",
"channel": "sms",
"expiry": 10,
"length": 6
}'
Response
{
"id": "otp_64f8a1b2c3d4e5f6",
"phone_number": "+233201234567",
"app": "my_ecommerce_app",
"channel": "sms",
"expiry_minutes": 10,
"length": 6,
"status": "sent",
"created_at": "2024-01-15T10:20:00Z",
"expires_at": "2024-01-15T10:30:00Z"
}
Store the returned id — you'll use it to verify the code the user enters.
2. Verify the OTP
Submit the code your user typed against the id from the send step.
curl -X POST https://api.tryzend.com/otp/otp_64f8a1b2c3d4e5f6/verify \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "code": "123456" }'
Response
{
"success": true,
"message": "OTP verified successfully",
"verified_at": "2024-01-15T10:25:00Z",
"attempts_remaining": 2
}
A success of true confirms the code was correct. See the full request/response schema and error shapes in the OTP API reference.
End-to-end example
// Send OTP
const response = await fetch('https://api.tryzend.com/otp/send', {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
phone_number: '+233201234567',
app: 'my_ecommerce_app',
channel: 'sms',
expiry: 10,
length: 6
})
});
const { id } = await response.json();
// Verify OTP
const verifyResponse = await fetch(`https://api.tryzend.com/otp/${id}/verify`, {
method: 'POST',
headers: {
'x-api-key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({ code: '123456' })
});
const result = await verifyResponse.json();
console.log(result.success); // true if verified
Features
- SMS & WhatsApp support — send OTPs via SMS or WhatsApp.
- Flexible configuration — customizable expiry time and OTP length.
- App categorization — track OTPs by application with the
appfield. - Security features — rate limiting, attempt limits, and automatic expiry.
- Analytics & reporting — detailed analytics and cost tracking.
- Real-time status — check OTP status and verification attempts.
- Auto cleanup — automatic cleanup of expired OTPs.
Note
expiry window and are capped at a maximum number of verification attempts. Once an OTP is verified, expired, or out of attempts, it can no longer be verified — send a new one.Best practices
- Set appropriate expiry. Use shorter expiry times for security — 5 to 15 minutes is a good range.
- Monitor analytics. Track verification rates and optimize your flow with the analytics endpoint.
- Handle errors. Implement proper error handling for failed verifications and surface
attempts_remainingto the user. - Respect rate limits. Stay within rate limits to avoid service disruption.
- Never store codes client-side. Don't keep OTP codes in client-side storage.
Next steps
- OTP API reference — every endpoint, request/response field, status value, and error response.