OTP & Verify API
Send one-time passwords across any channel. Canary handles code generation, delivery, verification, and automatic retries - all with built-in fraud protection.
99.9% Success Rate
Automatic retries and channel fallbacks ensure delivery.
Multi-Channel
SMS, Email, Voice, and WhatsApp from a single API.
Built-in Expiry
Configurable code expiration and attempt limits.
Supported Channels
SMS
Global delivery
Email
Branded templates
Voice
Text-to-speech
WhatsApp
2B+ users
Quick Start
Send an OTP in seconds. Canary generates a secure code, delivers it via your chosen channel, and handles verification automatically.
Step 1: Send OTP
POST/v1/verify/send
curl -X POST https://api.canarymsg.dev/v1/verify/send \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '
{
"to": "+15551234567",
"channel": "sms",
"brand_name": "Acme Inc"
}
'Response
{
"verification_id": "ver_abc123xyz",
"to": "+15551234567",
"channel": "sms",
"status": "pending",
"expires_at": "2024-01-01T12:10:00Z"
}Step 2: Verify Code
POST/v1/verify/check
{
"verification_id": "ver_abc123xyz",
"code": "123456"
}Verification Response
{
"verification_id": "ver_abc123xyz",
"status": "approved",
"channel": "sms",
"verified_at": "2024-01-01T12:02:30Z"
}Send Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
to | string | Phone number (E.164) or email address | |
channel | string | sms, email, voice, or whatsapp | |
brand_name | string | Optional | Your brand name shown in the message |
code_length | number | Optional | Length of the code (4-10, default 6) |
expires_in | number | Optional | Expiration in seconds (60-3600, default 600) |
locale | string | Optional | Message locale (e.g., en, es, fr) |
Verification Status
| Status | Description |
|---|---|
| pending | Code sent, awaiting verification |
| approved | Code verified successfully |
| failed | Too many incorrect attempts |
| expired | Code expired before verification |
| canceled | Verification was canceled |
Channel Fallbacks
Automatic Retries
Configure fallback channels to maximize delivery rates. If the primary channel fails, Canary automatically retries via your specified fallback channels.
POST/v1/verify/send
{
"to": "+15551234567",
"channel": "sms",
"fallback_channels": ["whatsapp", "voice"],
"fallback_delay": 30,
"brand_name": "Acme Inc"
}SDK Examples
Node.js
import Canary from '@canary/node';
const canary = new Canary('YOUR_API_KEY');
// Send OTP
const verification = await canary.verify.send({
to: '+15551234567',
channel: 'sms',
brand_name: 'Acme Inc',
});
// Verify code
const result = await canary.verify.check({
verification_id: verification.id,
code: '123456',
});
if (result.status === 'approved') {
console.log('Phone verified!');
}Python
from canary import Canary
canary = Canary("YOUR_API_KEY")
# Send OTP
verification = canary.verify.send(
to="+15551234567",
channel="sms",
brand_name="Acme Inc"
)
# Verify code
result = canary.verify.check(
verification_id=verification.id,
code="123456"
)
if result.status == "approved":
print("Phone verified!")