OTP API reference
Complete reference for the Zend OTP endpoints — sending, checking status, verifying, and analytics. All requests use the base URL https://api.tryzend.com and authenticate with your API key in the x-api-key header. For a guided walkthrough, see the OTP overview.
Send OTP
POST/otp/send
Generate a one-time password and deliver it to a phone number.
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
}'
Request fields
phone_numberstringrequired
Phone number in international format, e.g.
+233201234567.appstringrequired
Application identifier used to categorize and track OTPs.
channelstringrequired
Delivery channel. One of
sms or whatsapp.expirynumber
Expiry time in minutes. Defaults to
10.lengthnumber
Number of digits in the code. Defaults to
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"
}
Get OTP status
GET/otp/{id}/status
Check the current status, attempt counts, and lifecycle timestamps of an OTP.
curl https://api.tryzend.com/otp/otp_64f8a1b2c3d4e5f6/status \
-H "x-api-key: YOUR_API_KEY"
Response
{
"id": "otp_64f8a1b2c3d4e5f6",
"phone_number": "+233201234567",
"app": "my_ecommerce_app",
"channel": "sms",
"status": "pending",
"attempts": 0,
"max_attempts": 3,
"created_at": "2024-01-15T10:20:00Z",
"expires_at": "2024-01-15T10:30:00Z",
"verified_at": null
}
Response fields
statusstring
Current lifecycle state. See status values.
attemptsnumber
Number of verification attempts made so far.
max_attemptsnumber
Maximum verification attempts allowed before the OTP fails.
verified_atstring | null
Timestamp of successful verification, or
null if not yet verified.Verify OTP
POST/otp/{id}/verify
Verify a code against the OTP created in 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" }'
Request fields
codestringrequired
The one-time password code the user entered.
Response
{
"success": true,
"message": "OTP verified successfully",
"verified_at": "2024-01-15T10:25:00Z",
"attempts_remaining": 2
}
Response fields
successboolean
true if the code was correct, false otherwise.messagestring
Human-readable result message.
verified_atstring
Timestamp of successful verification. Present on success.
attempts_remainingnumber
Verification attempts left before the OTP fails.
Get analytics
GET/otp/analytics
Retrieve OTP analytics and statistics, optionally scoped to an application and time window.
curl "https://api.tryzend.com/otp/analytics?app=my_ecommerce_app&days=30" \
-H "x-api-key: YOUR_API_KEY"
Query parameters
appstring
Filter analytics to a single application.
daysnumber
Number of days to analyze. Defaults to
30.Status values
| Status | Description |
|---|---|
sent | OTP sent successfully |
pending | Waiting for verification |
verified | Successfully verified |
expired | OTP expired |
failed | Verification failed |
Error responses
A failed verification returns success: false along with the number of attempts left:
{
"success": false,
"message": "Invalid OTP code",
"attempts_remaining": 2
}
Note
When
attempts_remaining reaches 0, the OTP moves to a failed state and can no longer be verified. Send a new OTP to retry.