Verification API

Verify phone numbers with one-time passcodes. Built-in fraud protection blocks SMS pumping attacks.

Fraud Guard is enabled by default. You'll only be charged for successful verifications.

Create Verification

POST /v1/verify

Send a one-time passcode via SMS.

torequired
string
E.164 phone number to send the OTP to
channelrequired
enum
"sms" (only SMS is currently supported)
template
string
Custom message template. Must include {{code}}.
code_length
integer
OTP length: 4, 6, or 8 digits (default: 6)
// Step 1: Send the OTP to the user
const verification = await client.verify.create({
  to: "+15551234567",
  channel: "sms",
  // Optional: custom template
  template: "Your {{brand}} verification code is: {{code}}",
});

// verification.status → "pending"
// An SMS with a 6-digit code is sent to the user

Check Code

POST /v1/verify/check

Verify the code entered by the user. Codes expire after 10 minutes.

// Step 2: Check the code the user entered
const result = await client.verify.check({
  to: "+15551234567",
  code: userEnteredCode,  // e.g. "847291"
});

if (result.status === "approved") {
  // ✓ User is verified — proceed with signup/login
  await createUserSession(result.to);
} else {
  // ✗ Invalid or expired code
  return { error: "Invalid code. Please try again." };
}

Fraud Guard

Fraud Guard automatically detects and blocks SMS pumping attacks — where bad actors use your API to send mass OTPs and collect carrier payouts. It runs before every verification request, at no extra cost.

Pattern detection
Identifies suspicious traffic patterns in real time.
Geo-blocking
Optionally block specific countries or regions.
Zero cost
Blocked verifications are not charged.
// Fraud Guard is enabled by default on all verifications.
// You can monitor and configure it in the dashboard.

// Example: Check if a number was blocked
const status = await client.fraudGuard.check("+15551234567");
// status.blocked → true | false
// status.reason  → "pumping_suspected" | "rate_limit" | "geo_block"

Rate Limits

Default rate limits protect you from abuse and reduce costs. Customize per your needs.

// Default rate limits per phone number:
// - 5 verification attempts per 10 minutes
// - 1 successful verification per 10 minutes (for the same number)

// Customize for your service (dashboard or API):
const service = await client.verify.services.update("VA_xxxx", {
  codeLength: 6,
  lookupEnabled: true,
  fraudGuardEnabled: true,
  rateLimits: {
    maxAttempts: 3,
    windowMinutes: 10,
  },
});