Skip to main content

Send OTP

Send one-time passwords (OTPs) via Email, SMS, or WhatsApp for user verification, 2FA, and authentication workflows.

Endpointโ€‹

POST /api/v1/otp/send

Headersโ€‹

X-API-Key: sk_live_your_api_key
Content-Type: application/json

Why Use This Endpoint?โ€‹

  • ๐Ÿ” Multi-Channel - Send OTP via Email, SMS, WhatsApp, or all three simultaneously
  • โšก Instant Delivery - Fast OTP generation and delivery across all channels
  • ๐ŸŽฏ Flexible Configuration - Customize OTP length, expiry time, and attempt limits
  • ๐Ÿงช Sandbox Testing - Test without sending real messages or charges
  • ๐Ÿ“Š Session Management - Built-in tracking, rate limiting, and security
  • ๐Ÿ”„ Auto-Contact Sync - Optionally create contacts when they verify

Core Conceptโ€‹

An OTP session is created when you send an OTP. The session manages:

  • OTP codes for each channel (hashed for security)
  • Verification status for each channel
  • Security settings (expiry, max attempts, rate limiting)
  • Custom metadata for your application logic

After sending, you receive a session token that you'll use to verify the OTP later.

Request Structureโ€‹

Required Fieldsโ€‹

FieldTypeDescription
channelsarrayArray of channels: "email", "sms", "whatsapp"
recipientsobjectRecipient contact for each channel

Recipients Objectโ€‹

FieldTypeRequired WhenDescription
recipients.emailstringchannels includes "email"Valid email address
recipients.smsstringchannels includes "sms"Phone number in E.164 format (+1234567890)
recipients.whatsappstringchannels includes "whatsapp"WhatsApp number in E.164 format

Optional Fieldsโ€‹

FieldTypeDefaultDescription
configobjectSee belowOTP configuration settings
metadataobject{}Custom data to store with session
add_contactbooleanfalseCreate contact after successful verification
sandbox_modebooleanfalseTest mode - returns OTPs, doesn't send messages

Configuration Object (config)โ€‹

FieldTypeDefaultDescription
otp_lengthnumber6OTP code length (4-8 digits)
expiry_minutesnumber10Session expiry time
max_attemptsnumber3Maximum verification attempts

Use Case Examplesโ€‹

Example 1: Email Verificationโ€‹

Send OTP to verify a user's email address during registration.

curl -X POST https://api.sendmator.com/api/v1/otp/send \
-H "X-API-Key: sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"channels": ["email"],
"recipients": {
"email": "newuser@example.com"
},
"config": {
"otp_length": 6,
"expiry_minutes": 10
},
"metadata": {
"purpose": "email_verification",
"user_id": "user_12345"
},
"add_contact": true
}'

Response:

{
"session_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"channels_sent": {
"email": {
"success": true,
"message_id": "msg_550e8400e29b41d4a716446655440000"
}
},
"expires_at": "2024-01-15T10:45:00.000Z",
"verification_mode": "any"
}

Example 2: Phone Verification (SMS + WhatsApp)โ€‹

Send OTP to both SMS and WhatsApp, allowing the user to verify via either channel.

curl -X POST https://api.sendmator.com/api/v1/otp/send \
-H "X-API-Key: sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"channels": ["sms", "whatsapp"],
"recipients": {
"sms": "+1234567890",
"whatsapp": "+1234567890"
},
"config": {
"otp_length": 6,
"expiry_minutes": 5
},
"metadata": {
"purpose": "phone_verification",
"user_id": "user_67890"
}
}'

Response:

{
"session_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"channels_sent": {
"sms": {
"success": true,
"message_id": "msg_660f9511f30c52e5b827557766551111"
},
"whatsapp": {
"success": true,
"message_id": "msg_660f9511f30c52e5b827557766552222"
}
},
"expires_at": "2024-01-15T10:40:00.000Z",
"verification_mode": "any"
}

Example 3: Two-Factor Authentication (2FA)โ€‹

Send a short-lived OTP for 2FA during login.

curl -X POST https://api.sendmator.com/api/v1/otp/send \
-H "X-API-Key: sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"channels": ["sms"],
"recipients": {
"sms": "+1234567890"
},
"config": {
"otp_length": 6,
"expiry_minutes": 5,
"max_attempts": 3
},
"metadata": {
"purpose": "2fa_login",
"user_id": "user_12345",
"ip_address": "192.168.1.1"
}
}'

Response:

{
"session_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"channels_sent": {
"sms": {
"success": true,
"message_id": "msg_770g0622g41d63f6c938668877662222"
}
},
"expires_at": "2024-01-15T10:40:00.000Z",
"verification_mode": "any"
}

Example 4: Multi-Channel Verificationโ€‹

Send OTP to all three channels for maximum delivery success.

curl -X POST https://api.sendmator.com/api/v1/otp/send \
-H "X-API-Key: sk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"channels": ["email", "sms", "whatsapp"],
"recipients": {
"email": "user@example.com",
"sms": "+1234567890",
"whatsapp": "+1234567890"
},
"config": {
"otp_length": 6,
"expiry_minutes": 10
},
"metadata": {
"purpose": "account_verification"
}
}'

Response:

{
"session_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"channels_sent": {
"email": {
"success": true,
"message_id": "msg_880h1733h52e74g7d049779988773333"
},
"sms": {
"success": true,
"message_id": "msg_880h1733h52e74g7d049779988774444"
},
"whatsapp": {
"success": true,
"message_id": "msg_880h1733h52e74g7d049779988775555"
}
},
"expires_at": "2024-01-15T10:45:00.000Z",
"verification_mode": "any"
}

Example 5: Sandbox Mode (Testing)โ€‹

Test OTP flow without sending real messages or incurring charges.

curl -X POST https://api.sendmator.com/api/v1/otp/send \
-H "X-API-Key: sk_test_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"channels": ["email", "sms"],
"recipients": {
"email": "test@example.com",
"sms": "+1234567890"
},
"sandbox_mode": true
}'

Response (Sandbox Mode):

{
"session_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"channels_sent": {
"email": {
"success": true,
"message_id": "msg_sandbox_990i2844i63f85h8e150880099884444"
},
"sms": {
"success": true,
"message_id": "msg_sandbox_990i2844i63f85h8e150880099885555"
}
},
"sandbox_otps": {
"email": "123456",
"sms": "123456"
},
"expires_at": "2024-01-15T10:45:00.000Z",
"verification_mode": "any"
}

Response Fieldsโ€‹

Success Responseโ€‹

FieldTypeDescription
session_tokenstringJWT token for verifying OTP later
channels_sentobjectStatus of each channel send attempt
expires_atstringISO 8601 timestamp when session expires
verification_modestringVerification mode: "any" or "all"
sandbox_otpsobjectOTP codes (only in sandbox mode)

Channels Sent Objectโ€‹

Each channel in channels_sent contains:

FieldTypeDescription
successbooleanWhether the OTP was sent successfully
message_idstringUnique message identifier for tracking

Error Responseโ€‹

{
"statusCode": 400,
"message": "Invalid recipient email address",
"error": "Bad Request"
}

Common Error Responsesโ€‹

Status CodeErrorCause
400Invalid recipientEmail/phone format is incorrect
400Invalid channelChannel not supported
400Missing recipientsRecipients object missing required fields
401Invalid API keyAPI key is missing or incorrect
402Insufficient balanceNot enough wallet credits
429Rate limit exceededToo many OTP requests

Recipient Format Validationโ€‹

Emailโ€‹

  • Must be a valid email address
  • Example: user@example.com

Phone Number (SMS/WhatsApp)โ€‹

  • Must be in E.164 format
  • Include country code with + prefix
  • No spaces, dashes, or parentheses
  • Examples:
    • โœ… +1234567890 (US)
    • โœ… +919876543210 (India)
    • โœ… +442071234567 (UK)
    • โŒ 1234567890 (missing + and country code)
    • โŒ +1 (234) 567-8900 (contains formatting)

Best Practicesโ€‹

1. Securityโ€‹

  • Store the token securely on the client side
  • Never log or expose OTP codes in production
  • Use short expiry times (5-10 minutes) for sensitive operations
  • Implement rate limiting on your application side
  • Monitor failed attempts and block suspicious activity

2. User Experienceโ€‹

  • Clear instructions - Tell users where to find the OTP
  • Multiple channels - Offer SMS + WhatsApp for better deliverability
  • Resend option - Allow users to request a new OTP
  • Show expiry time - Display countdown timer
  • Error handling - Provide helpful error messages

3. Configurationโ€‹

  • OTP length: Use 6 digits for balance of security and usability
  • Expiry time:
    • 5 minutes for 2FA/login
    • 10 minutes for verification workflows
    • 15 minutes for password resets
  • Max attempts: 3 attempts is recommended

4. Metadata Usageโ€‹

Store context for later retrieval:

{
"metadata": {
"user_id": "user_12345",
"purpose": "email_verification",
"ip_address": "192.168.1.1",
"user_agent": "Mozilla/5.0...",
"app_version": "2.1.0"
}
}

5. Auto-Contact Creationโ€‹

Enable add_contact: true to automatically add verified users to your contacts:

{
"add_contact": true
}

This creates a contact record when the user successfully verifies any channel.

Rate Limitsโ€‹

To prevent abuse:

  • 5 OTP sends per 5 minutes per user
  • 20 OTP sends per hour per IP address
  • 100 active sessions per user

Sandbox vs Productionโ€‹

FeatureSandbox ModeProduction Mode
Messages SentโŒ Noโœ… Yes
OTPs Returnedโœ… YesโŒ No
Wallet ChargedโŒ Noโœ… Yes
Use CaseTestingLive users

Next Stepsโ€‹