One-Time Passwords (OTPs)
One-Time Passwords (OTPs) enable secure verification flows where you need to confirm user identity or authorize sensitive actions. Generate time-limited tokens, deliver them to recipients, and verify submissions with built-in protection against brute-force attacks and token reuse.
The OTP transaction object
An OTP transaction represents a complete verification session from token generation through delivery and verification. Each transaction tracks delivery status, expiration time, and verification attempts.
Properties
Initiate OTP transaction
Generate a one-time password, deliver it to the recipient, and return a transaction ID for verification. The token is securely generated and never stored in plain text. Supports custom message templates and idempotency to prevent duplicate sends.
Required attributes
- Name
idempotency_key- Type
- string
- Description
Unique key to prevent duplicate OTP sends during retries. If a transaction with this key already exists, that transaction is returned instead of creating a new one. Length: 16-128 characters. Use UUIDs, timestamps with random suffixes, or request IDs from your system.
- Name
recipient- Type
- string
- Description
Recipient identifier where the OTP will be delivered. For phone numbers, use international format (e.g.,
+233241234567,+12065551234). For email addresses, use standard email format (e.g.,user@example.com). Delivery method is automatically determined by recipient type—phone numbers receive SMS or WhatsApp, email addresses receive email. Invalid formats are rejected with clear error messages.
Optional attributes
- Name
message_template- Type
- string
- Description
Custom message template for the OTP. Must include
{token}placeholder for token substitution and optionally{service}for service name. Example:Your {service} verification code is {token}. Valid for 10 minutes.If not provided, uses system default template. Max length after substitution: 160 characters (SMS limit).
Request
curl https://api.zebo.dev/otp/initiate \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{
"idempotency_key": "txn_67890_otp_20231215",
"recipient": "+233241234567",
"sender": "Acme",
"service_name": "Acme Bank",
"message_template": "Your {service} code is {token}. Valid for 10 minutes.",
"token_alphabet_type": "numeric",
"token_size": 6,
"validity_duration_in_minutes": 10,
"purpose": "transaction_confirm"
}'
Response
{
"transaction": {
"id": "3f8a9c7e2d1b4a6f",
"status": "pending",
"full_message": "Your Acme Bank code is {token}. Valid for 10 minutes.",
"initiated_at": 1702656000,
"expires_at": 1702656600,
"canceled_at": null,
"cancel_reason": null,
"transmission": {
"recipient": "+233241234567",
"sender_id": "Acme",
"sent_via": "sms",
"status": "submitted",
"sent_at": 1702656001
}
}
}
Verify OTP
Verify a one-time password by comparing the user-submitted token against the transaction. Enforces attempt limits to prevent brute-force attacks. Expired or canceled transactions are rejected immediately.
Required attributes
Request
curl https://api.zebo.dev/otp/verify \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{
"transaction_id": "3f8a9c7e2d1b4a6f",
"recipient": "+233241234567",
"token": "847293"
}'
Response (Success)
{
"transaction": {
"id": "3f8a9c7e2d1b4a6f",
"status": "verified",
"full_message": "Your Acme Bank code is {token}. Valid for 10 minutes.",
"initiated_at": 1702656000,
"expires_at": 1702656600,
"canceled_at": null,
"cancel_reason": null,
"transmission": {
"recipient": "+233241234567",
"sender_id": "Acme",
"sent_via": "sms",
"status": "delivered",
"sent_at": 1702656001
}
}
}
Lookup OTP transaction
Retrieve details of an existing OTP transaction by its ID. Check transaction status, delivery state, and verification status.
Required attributes
Request
curl https://api.zebo.dev/otp/lookup \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{
"transaction_id": "3f8a9c7e2d1b4a6f"
}'
Response
{
"transaction": {
"id": "3f8a9c7e2d1b4a6f",
"status": "pending",
"full_message": "Your Acme Bank code is {token}. Valid for 10 minutes.",
"initiated_at": 1702656000,
"expires_at": 1702656600,
"canceled_at": null,
"cancel_reason": null,
"transmission": {
"recipient": "+233241234567",
"sender_id": "Acme",
"sent_via": "sms",
"status": "delivered",
"sent_at": 1702656001
}
}
}
Cancel OTP transaction
Cancel an active OTP transaction to prevent further verification attempts. Cancel when a user requests a new OTP, when suspicious activity is detected, or when the authentication flow is abandoned. Canceled transactions cannot be verified even if the token hasn't expired.
Required attributes
Request
curl https://api.zebo.dev/otp/cancel \
-H "Authorization: Bearer {api_key}" \
-H "Content-Type: application/json" \
-d '{
"transaction_id": "3f8a9c7e2d1b4a6f",
"reason": "user_requested_new_code"
}'
Response
{
"transaction": {
"id": "3f8a9c7e2d1b4a6f",
"status": "canceled",
"full_message": "Your Acme Bank code is {token}. Valid for 10 minutes.",
"initiated_at": 1702656000,
"expires_at": 1702656600,
"canceled_at": 1702656120,
"cancel_reason": "user_requested_new_code",
"transmission": {
"recipient": "+233241234567",
"sender_id": "Acme",
"sent_via": "sms",
"status": "delivered",
"sent_at": 1702656001
}
}
}