The simple way to turn visitors into verified customers

Secure Your Users with our multi-channel Verify API

Grow signups and keep accounts safe with one-time passcodes (OTPs) sent to your customers.

Channels: SMS · WhatsApp · Viber · Telegram

If the first channel is slow, we try the next one automatically so fewer people drop off.

Free trialTalk to an expert

*No credit card required. Get free Call & SMS credits on sign‑up.

TrustRadius
TrustRadius Five Star Rating
G2 Rating
G2 4.5 Rating
Capterra Rating
Capterra Five Star Rating
TrustPilot Rating
TrustPilot Four Star Rating
verify api hero image

+1,000 BUSINESSES USE SMS.to FOR THEIR NEEDS

Control Everything in One Place

Set your verification rules once and stay in control. Your team sees what happened in real time with webhooks and logs.

Privacy & Regulatory Compliance

Choose channels and fallback

Pick SMS, WhatsApp, Viber or Telegram and set the order we try.

ShortLink Tracking

Set expiry and code format

Choose how long the code is valid and the length or format that fits your flow.

Global Delivery

Use clear templates and language

Write a short message and select the language your customers expect.

Security & Transparency

Adjust per request when needed

Override any default for a test, a new region or a special flow.

We execute your rules in real time and stream events to your webhooks and logs so your team can trace each step.

Who Benefits and How​

Why teams trust Verify API for the entire customer journey, from signups to account changes

Privacy & Regulatory Compliance

One place to set your rules

Create a single Verify App to set your defaults. Pick your channel order, expiry time, code length or format, templates and language. Change any of these per request when you need to.

ShortLink Tracking

Smart fallback that saves time and money

If WhatsApp is not installed or fails to deliver, we try SMS. If Viber is blocked, we can try WhatsApp or Telegram.
You only pay for the channel that delivered and a Verify fee when the user verifies.
Many teams start with WhatsApp in high-penetration regions and use SMS as a universal safety net.

Global Delivery

Clear data for your team

See webhooks, logs and charts for every verification. Support can check what happened. Product can see where users drop off. Engineering can tune timeouts and templates.

Security & Transparency

Built for both business and dev

Business owners get simple pricing rules and better completion. Developers get clean APIs, SDKs and examples. Everyone gets a faster path to a working 2FA flow.

Suitable for both greenfield projects and established platforms. Whether you’re adding 2FA to a new app or replacing in-house scripts, the verification api provides consistent responses, webhooks, and a dashboard your team can use without a manual.

How SMS.to Verify API works

Initiate a verification

Choose the channel order (for example, WhatsApp → SMS), OTP expiry, code length/format, message template, and locale. Set smart defaults in your Verify App. Change them on any single request for A/B tests, roll out by region, or handle a unique case.

Deliver & observe

We attempt the first channel and track delivery in real time. If delivery doesn’t happen within your timeout, we fall back automatically to the next channel. Your logs show the exact path taken - useful when support asks, “What happened to this user’s code?”

Verify the code

Your user enters the code. You call the verification API to check it. You’ll also receive delivery and verification webhooks, plus searchable logs and charts. The result includes the channel that ultimately delivered, timestamps, and a verification status you can trust in downstream systems.

Best-practice fraud controls

recommended
  • Add rate limits for user, IP and device.
  • Use shorter expiry for risky actions.
  • Use Home Location Register (HLR) or Mobile Number Portability (MNP) lookup to keep numbers clean.
  • Add a simple human check (like CAPTCHA) on repeat attempts.

Get Started

verify API

Key Features​

Multi-channel delivery

(SMS, WhatsApp, Viber, Telegram)

Reach users on the app they open.

Single source of truth

One Verify App powering all verification flows
SMS API Tabs Notifications

Smart fallback orchestration

Auto-switch channels when delivery stalls to lift completion.
SMS API Tabs Reminders

Per-request overrides

Change channel order, expiry (TTL), code length/format, template, and locale on any request
SMS API Tabs Marketing

Client-generated OTP (optional)

Bring your own code; we’ll handle delivery, limits, and verification

SMS API Tabs Surveys and Feedback Requests

Telemetry that matters

Delivery + verification webhooks, searchable logs, dashboards, and exportable reports
SMS API Tabs Surveys and Feedback Requests

Localization & templates

Friendly message templates with variables and local language support
SMS API Tabs Surveys and Feedback Requests

Statistics & charts

Track completion, drop-off, and trends.
SMS API Tabs Surveys and Feedback Requests

Pricing:
What You Pay and When

How billing works

OTT channels (WhatsApp, Viber, Telegram)
You pay the channel fee only if it delivers, and the Verify fee only when the OTP is verified.

SMS
You pay the SMS send fee when we send it, even if it is not delivered.
You pay the Verify fee only when the OTP is verified.

Skipped channels
If a channel is not attempted, you do not pay for it.

Failed delivery
For OTT: no channel fee if it does not deliver.
For SMS: the send fee still applies even if delivery fails.

Experimenting with new channel orders won’t surprise you with extra costs if they don’t deliver.

Examples

  • India (WhatsApp delivered) → Pay WhatsApp send + Verify success fee
  • Egypt (WhatsApp timed out → SMS delivered) → Pay SMS send + Verify success fee
  • Poland (no delivery) → No Verify success fee; skipped/failed channels not charged (except SMS)
  • Germany (SMS delivered, user never entered code) → channel fee charged; no success fee

Compare WhatsApp→SMS versus SMS-only for your regions.
Our graphs show your potential savings and completion gains.
If you already use multiple channels, we also show how much you saved
versus SMS-only.

Get Started

verify API
easy SETUP!

Verify API For Developers

Ship your first OTP in minutes. Use our sms verification api with clear responses and webhook events.
Prefer SDKs? Use Node, Python, PHP, Java, or Go. A Postman collection and a copy‑paste quickstart help you verify the flow quickly.
Note on code samples: The live page shows SMS API examples by default. For exact Verify API endpoints and parameters, follow the Read Docs link.

				
					curl --location 'https://verifyapi.sms.to/api/v1/verifications/create' \
--header 'Authorization: Bearer <api_key>' \
--header 'Content-Type: application/json' \
--data '{
    "guid": "3-1748345-bcef-0342-6bef5c26-04f64e7",
    "recipient": "+35799999999999",
    "reference": "d36f6c45-2bd3-4eee-b7c1-d9f81e65efb0",
    "code": "123456",
    "callback_url": "https://abc.sms/message/callback",
    "channels": [
        {
            "channel": "viber",
            "sender_id": "SMSTO",
            "priority": 1,
            "expiry_time": 30
        },
        {
            "channel": "whatsapp",
            "priority": 2,
            "expiry_time": 30
        },
        {
            "channel": "sms",
            "priority": 3,
            "expiry_time": 30
        }
    ]
}'
				
			
				
					<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://verifyapi.sms.to/api/v1/verifications/create',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
    "guid": "3-1748345-bcef-0342-6bef5c26-04f64e7",
    "recipient": "+35799999999999",
    "reference": "d36f6c45-2bd3-4eee-b7c1-d9f81e65efb0",
    "code": "123456",
    "callback_url": "https://abc.sms/message/callback",
    "channels": [
        {
            "channel": "viber",
            "sender_id": "SMSTO",
            "priority": 1,
            "expiry_time": 30
        },
        {
            "channel": "whatsapp",
            "priority": 2,
            "expiry_time": 30
        },
        {
            "channel": "sms",
            "priority": 3,
            "expiry_time": 30
        }
    ]
}',
  CURLOPT_HTTPHEADER => array(
    'Authorization: Bearer <api_key>',
    'Content-Type: application/json'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
				
			
				
					var https = require('follow-redirects').https;
var fs = require('fs');

var options = {
  'method': 'POST',
  'hostname': 'verifyapi.sms.to',
  'path': '/api/v1/verifications/create',
  'headers': {
    'Authorization': 'Bearer <api_key>',
    'Content-Type': 'application/json'
  },
  'maxRedirects': 20
};

var req = https.request(options, function (res) {
  var chunks = [];

  res.on("data", function (chunk) {
    chunks.push(chunk);
  });

  res.on("end", function (chunk) {
    var body = Buffer.concat(chunks);
    console.log(body.toString());
  });

  res.on("error", function (error) {
    console.error(error);
  });
});

var postData = JSON.stringify({
  "guid": "3-1748345-bcef-0342-6bef5c26-04f64e7",
  "recipient": "+35799999999999",
  "reference": "d36f6c45-2bd3-4eee-b7c1-d9f81e65efb0",
  "code": "123456",
  "callback_url": "https://abc.sms/message/callback",
  "channels": [
    {
      "channel": "viber",
      "sender_id": "SMSTO",
      "priority": 1,
      "expiry_time": 30
    },
    {
      "channel": "whatsapp",
      "priority": 2,
      "expiry_time": 30
    },
    {
      "channel": "sms",
      "priority": 3,
      "expiry_time": 30
    }
  ]
});

req.write(postData);

req.end();
				
			
				
					require "uri"
require "json"
require "net/http"

url = URI("https://verifyapi.sms.to/api/v1/verifications/create")

https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = "Bearer <api_key>"
request["Content-Type"] = "application/json"
request.body = JSON.dump({
  "guid": "3-1748345-bcef-0342-6bef5c26-04f64e7",
  "recipient": "+35799999999999",
  "reference": "d36f6c45-2bd3-4eee-b7c1-d9f81e65efb0",
  "code": "123456",
  "callback_url": "https://abc.sms/message/callback",
  "channels": [
    {
      "channel": "viber",
      "sender_id": "SMSTO",
      "priority": 1,
      "expiry_time": 30
    },
    {
      "channel": "whatsapp",
      "priority": 2,
      "expiry_time": 30
    },
    {
      "channel": "sms",
      "priority": 3,
      "expiry_time": 30
    }
  ]
})

response = https.request(request)
puts response.read_body

				
			
				
					import http.client
import json

conn = http.client.HTTPSConnection("verifyapi.sms.to")
payload = json.dumps({
  "guid": "3-1748345-bcef-0342-6bef5c26-04f64e7",
  "recipient": "+35799999999999",
  "reference": "d36f6c45-2bd3-4eee-b7c1-d9f81e65efb0",
  "code": "123456",
  "callback_url": "https://abc.sms/message/callback",
  "channels": [
    {
      "channel": "viber",
      "sender_id": "SMSTO",
      "priority": 1,
      "expiry_time": 30
    },
    {
      "channel": "whatsapp",
      "priority": 2,
      "expiry_time": 30
    },
    {
      "channel": "sms",
      "priority": 3,
      "expiry_time": 30
    }
  ]
})
headers = {
  'Authorization': 'Bearer <api_key>',
  'Content-Type': 'application/json'
}
conn.request("POST", "/api/v1/verifications/create", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
				
			
				
					OkHttpClient client = new OkHttpClient().newBuilder()
  .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n    \"guid\": \"3-1748345-bcef-0342-6bef5c26-04f64e7\",\n    \"recipient\": \"+35799999999999\",\n    \"reference\": \"d36f6c45-2bd3-4eee-b7c1-d9f81e65efb0\",\n    \"code\": \"123456\",\n    \"callback_url\": \"https://abc.sms/message/callback\",\n    \"channels\": [\n        {\n            \"channel\": \"viber\",\n            \"sender_id\": \"SMSTO\",\n            \"priority\": 1,\n            \"expiry_time\": 30\n        },\n        {\n            \"channel\": \"whatsapp\",\n            \"priority\": 2,\n            \"expiry_time\": 30\n        },\n        {\n            \"channel\": \"sms\",\n            \"priority\": 3,\n            \"expiry_time\": 30\n        }\n    ]\n}");
Request request = new Request.Builder()
  .url("https://verifyapi.sms.to/api/v1/verifications/create")
  .method("POST", body)
  .addHeader("Authorization", "Bearer <api_key>")
  .addHeader("Content-Type", "application/json")
  .build();
Response response = client.newCall(request).execute();
				
			
				
					package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://verifyapi.sms.to/api/v1/verifications/create"
  method := "POST"

  payload := strings.NewReader(`{
    "guid": "3-1748345-bcef-0342-6bef5c26-04f64e7",
    "recipient": "+35799999999999",
    "reference": "d36f6c45-2bd3-4eee-b7c1-d9f81e65efb0",
    "code": "123456",
    "callback_url": "https://abc.sms/message/callback",
    "channels": [
        {
            "channel": "viber",
            "sender_id": "SMSTO",
            "priority": 1,
            "expiry_time": 30
        },
        {
            "channel": "whatsapp",
            "priority": 2,
            "expiry_time": 30
        },
        {
            "channel": "sms",
            "priority": 3,
            "expiry_time": 30
        }
    ]
}`)

  client := &http.Client {
  }
  req, err := http.NewRequest(method, url, payload)

  if err != nil {
    fmt.Println(err)
    return
  }
  req.Header.Add("Authorization", "Bearer <api_key>")
  req.Header.Add("Content-Type", "application/json")

  res, err := client.Do(req)
  if err != nil {
    fmt.Println(err)
    return
  }
  defer res.Body.Close()

  body, err := ioutil.ReadAll(res.Body)
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(string(body))
}
				
			

What to do with Verify API today

Privacy & Regulatory Compliance

Complete account sign-ups with fewer drop offs

Reduce abandonment with short, localized templates and the channel your audience prefers. A common setup is WhatsApp → SMS for high-penetration markets.

ShortLink Tracking

Protect logins with 2FA

Use short lived codes and stricter limits. Pick the fastest channel first for your users, while keeping them safe.

Global Delivery

Secure high-risk actions

For password resets, payouts, or policy changes, use stricter limits and secure templates. Confirm in a second channel if needed.

Security & Transparency

Confirm phone number changes

When users update their number, run a quick verify OTP before you overwrite the primary contact.

Why multi-channel helps: Coverage, cost, and completion.

If the first channel is slow or blocked for a user, we fall back to the next one.
This keeps the journey moving without manual retries.

Seamless Integrations
With Your Favorite Tools​

SMS integrations for your preferred platform

seamless integration mobile

Compliance & security

We provide privacy and uptime resources and can share detailed security practices on request. See our: Privacy Notice & Status Page Typical controls (on request): encryption at rest/in transit, webhook signing (HMAC), configurable retention for OTP logs. If you need a deeper review for procurement, we’ll walk you through data flows and operational processes.

Get Started

verify API

What Our Users Say

Start sending OTPs in minutes

Ready to try the sms verification api?


Start free or book a quick call to map out your channel order and rollout plan.
We can share quick start guidance and sample requests and responses so your team can test end-to-end in your own environment.

Learn how we collect and use your information by visiting our Privacy Notice

SMS.to SignUp

FAQ
(Verification API essentials)

It is a simple way to add phone verification to your app. You send a request. We send a one-time code by SMS. You confirm the code with one quick check.

Initiate with your channel order, then call the verify endpoint with the verification_id and the user’s code. Webhooks confirm delivery and success.

Yes. You can supply your own code; we’ll deliver it and handle the verification step.

  • OTT channels (WhatsApp, Viber, Telegram): you pay the channel fee only if it delivers, and the Verify fee only when the OTP is verified.
  • SMS: you pay the SMS send fee when we send it, even if it is not delivered. You pay the Verify fee only when the OTP is verified.
  • Skipped channels: if a channel is not attempted, you do not pay for it.

You only pay for the channel that delivered and a Verify fee when the OTP is successfully verified. Skipped or failed channels are not charged.

We focus on phone verification. For ID documents and KYC, you can use your own provider on your platform.

We make this easy by sending delivery and verification events to your webhooks, so you can trigger KYC checks in the same flow. OTP confirms phone possession. For identity verification or KYC, we can integrate with your existing provider or recommend a partner.

No. If nothing delivers or the code isn’t verified, you don’t pay the Verify success fee.

Absolutely. Many teams verify phone numbers during profile edits, two-step approvals, high-risk transactions, and device pairing.

Yes for SMS and Viber. You can use your own templates and languages. For WhatsApp and Telegram, the channel requires a standard OTP text. We follow those rules and cannot change them. Keep messages short so users spot the code quickly.