Send OTP via SMS/WhatsApp

Send secure One-Time Passwords to verify phone numbers through SMS or WhatsApp messaging. Our OTP API provides reliable delivery with customizable templates and comprehensive tracking.

🚀 Quick Start

Basic OTP Request

curl -X POST "https://api.airtexts.com/otp/send" \
  -H "X-API-Key: your_api_key" \
  -H "X-API-Secret: your_api_secret" \
  -H "Content-Type: application/json" \
  -d '{
    "appid": "your_app_id",
    "recipient": "+5511999888777",
    "channel": "sms",
    "from": "YourApp"
  }'

WhatsApp OTP Request

curl -X POST "https://api.airtexts.com/otp/send" \
  -H "Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=" \
  -H "Content-Type: application/json" \
  -d '{
    "appid": "your_app_id",
    "recipient": "+5511999888777",
    "channel": "whatsapp",
    "from": "YourCompany"
  }'

📋 Request Parameters

Required Parameters

ParameterTypeDescriptionExample
appidstringApplication ID for API identification"myapp_123"
recipientstringPhone number in international format"+258845888195"

Optional Parameters

ParameterTypeDescriptionDefaultExample
channelstringDelivery channel: sms or whatsapp"sms""whatsapp"
fromstringSender ID (also accepts sender)"OTP""YourApp"
otp_lengthintegerOTP code length (4-8 digits)64
templateIdintegerCustom template IDnull123
langstringLanguage code for template"en""pt"

Alternative Parameter Names

  • recipient can also be sent as phone or to
  • from can also be sent as sender
  • otp_code can also be sent as code

📱 Channel Options

SMS Channel

  • Fast delivery - Usually delivered within seconds
  • Universal support - Works on all mobile devices
  • Cost effective - Lower cost per message
  • High reliability - 99%+ delivery rate

WhatsApp Channel

  • Rich messaging - Support for formatting and emojis
  • Higher engagement - Better user interaction
  • Free for recipients - No SMS charges for users
  • Business presence - Builds brand recognition

Template Variables

Template messages support these variables:

  • {{otp}} or {{code}} - The OTP code
  • {{app_name}} or {{appname}} - Application name
  • {{expires_at}} or {{expires_time}} - Expiration time (HH:MM)
  • {{expires_full}} - Full expiration datetime
  • {{expiry_minutes}} - Minutes until expiration
  • {{recipient}} or {{phone}} - Recipient phone number
  • {{channel}} - Delivery channel
  • {{lang}} - Language code
  • Custom variables from custom_vars object

✅ Success Response

{
  "status": "success",
  "message": "OTP sent successfully",
  "verification_id": "otp_67890abcdef12345",
  "recipient": "+5511999888777",
  "channel": "sms",
  "expires_at": "2025-08-19T20:15:00Z"
}

Response Fields

  • verification_id - Unique ID for this OTP (use for verification)
  • recipient - Phone number that received the OTP
  • channel - Delivery channel used (sms/whatsapp)
  • expires_at - When the OTP expires (ISO 8601 format)

❌ Error Responses

Missing App ID

{
  "error": "appid is required"
}

Invalid Phone Number

{
  "error": "Invalid phone number format"
}

Rate Limited

{
  "error": "Rate limit exceeded. Try again in 60 seconds",
  "retry_after": 60
}

Insufficient Balance

{
  "error": "Insufficient balance to send OTP",
  "balance": 2.50,
  "cost": 0.05
}

🔒 Authentication Examples

API Key Headers

curl -X POST "https://api.airtexts.com/otp/send" \
  -H "X-API-Key: your_api_key" \
  -H "X-API-Secret: your_api_secret" \
  -H "Content-Type: application/json" \
  -d '{"appid": "your_app_id", "recipient": "+5511999888777"}'

Basic Authentication

curl -X POST "https://api.airtexts.com/otp/send" \
  -H "Authorization: Basic $(echo -n 'username:password' | base64)" \
  -H "Content-Type: application/json" \
  -d '{"appid": "your_app_id", "recipient": "+258845888195"}'

Bearer Token

curl -X POST "https://api.airtexts.com/otp/send" \
  -H "Authorization: Bearer your_jwt_token" \
  -H "Content-Type: application/json" \
  -d '{"appid": "your_app_id", "recipient": "+5511999888777"}'

Per Company Limits

  • 20 OTPs per minute - Company-wide rate limit
  • Burst protection - Automatic throttling during high usage

Failed Attempts

  • 3 failed verification attempts in 30 minutes - Temporary block

🎯 Implementation Examples

PHP Example

<?php
$data = [
    'appid' => 'your_app_id',
    'recipient' => '+5511999888777',
    'channel' => 'sms',
    'from' => 'YourApp'
];

$ch = curl_init('https://api.airtexts.com/otp/send');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'X-API-Key: your_api_key',
    'X-API-Secret: your_api_secret',
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
$result = json_decode($response, true);
curl_close($ch);

if ($result['status'] === 'success') {
    echo "OTP sent! Verification ID: " . $result['verification_id'];
} else {
    echo "Error: " . $result['error'];
}
?>

💡 Best Practices

Security

  • Never log OTP codes - Keep verification codes out of logs
  • Use HTTPS only - Always use secure connections
  • Validate phone numbers - Check format before sending
  • Set appropriate expiration - 5-15 minutes recommended

User Experience

  • Clear instructions - Tell users what to expect
  • Retry mechanism - Allow users to request new codes
  • Multiple channels - Offer SMS and WhatsApp options
  • Error handling - Provide helpful error messages

Performance

  • Cache verification IDs - Store for verification process
  • Handle rate limits - Implement exponential backoff
  • Monitor delivery - Track success rates
  • Use webhooks - Get real-time delivery updates

🔄 Next Steps

After sending an OTP, you'll typically want to:

  1. Store the verification_id - Save it for the verification step
  2. Show user interface - Display code input form
  3. Implement verification - Use /otp/verify endpoint
  4. Handle expiration - Allow resending via /otp/resend
  5. Track analytics - Monitor success rates and delivery
Body Params
string
required

Application ID for API identification

string

Phone number in international format

string
required

Phone number in international format (can also use 'phone' or 'to')

string
enum
Defaults to sms

Delivery channel for OTP

Allowed:
string

Sender ID (can also use 'sender')

integer
4 to 8
Defaults to 6

OTP code length (4-8 digits)

integer

Template ID for custom message template

string
Defaults to en

Language code for template

Responses

Language
Credentials
LoadingLoading…
Response
Click Try It! to start a request and see the response here! Or choose an example:
application/json