Docs/OTP & Verify

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

ParameterTypeRequiredDescription
tostringPhone number (E.164) or email address
channelstringsms, email, voice, or whatsapp
brand_namestringOptionalYour brand name shown in the message
code_lengthnumberOptionalLength of the code (4-10, default 6)
expires_innumberOptionalExpiration in seconds (60-3600, default 600)
localestringOptionalMessage locale (e.g., en, es, fr)

Verification Status

StatusDescription
pendingCode sent, awaiting verification
approvedCode verified successfully
failedToo many incorrect attempts
expiredCode expired before verification
canceledVerification 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!")

Next Steps