Skip to main content
The Verify API is the simplest way to confirm that a user owns a phone number. You make two calls:
  1. Start a verification with the phone number. OTPBay generates a code and sends it.
  2. Check the code your user enters.
OTPBay handles code generation, expiry, the wrong-code limit, the fallback from Telegram to SMS, and refunds for codes that never arrive.

How a verification works

A verification is pending until it reaches one of three final statuses: Final statuses don’t change. To try again, start a new verification.

Start a verification

The response is 201 with the verification. Store its sid with your user’s session.

Check the code

The response is always 200 while the verification is pending. Read valid:
  • "valid": true — the code matched and status is now approved.
  • "valid": false — the code is wrong. checks_left went down by one. When it reaches 0, the verification is failed.
Checking a verification that is already approved, expired or failed returns 409 VERIFICATION_NOT_PENDING.
Show checks_left to your user after a wrong code, so they know how many tries remain.

Telegram with SMS fallback

By default, Verify sends the code on Telegram, which costs less than SMS in most countries. If Telegram can’t deliver it, OTPBay sends the same code by SMS. Your user can enter the code from either message. OTPBay switches to SMS in two cases, both set in Verify settings:
  • Telegram can’t deliver. The number has no Telegram account, or Telegram rejects or revokes the message. fallback_reason is telegram_failed.
  • The fallback wait passes. Telegram hasn’t delivered the code after this many seconds (default 60). fallback_reason is timeout.
The fallback happens at most once and only before the code expires. When it happens, channel changes to sms and a second entry appears in attempts. The Telegram send is refunded — you pay only for the channel that delivered.

Configure Verify

Open Messaging → Verify in the dashboard. A verification uses the settings in place when it starts; later changes don’t affect verifications already running.
If the channel is SMS, or SMS fallback is on, you need an approved sender ID. Without one, starting a verification fails with 422 SENDER_ID_REQUIRED.
Verify sends its SMS even when the SMS channel is turned off for direct sends, and it doesn’t use the SMS channel’s default callback.

Pricing and refunds

Each verification costs a $0.02 Verify fee plus the price of each channel send. When you start a verification, your balance must cover the fee and the first send, or the request fails with 402 INSUFFICIENT_BALANCE. When the verification finishes, OTPBay refunds what wasn’t delivered:
  • A Telegram send that wasn’t delivered in time is refunded.
  • The Verify fee is refunded if no channel delivered the code.
  • An SMS the carrier accepted is not refunded.
cost on the verification always shows the current total after refunds. See Billing for details.

Follow a verification

You don’t need to poll: check the code when your user submits it. To react to verifications that expire or fail, set a callback. OTPBay sends one webhook when the verification reaches approved, expired or failed, after refunds are settled. You can also get a verification at any time to see its attempts and status.

Best practices

  • Start verifications from your backend. Rate-limit them per user and per phone number to stop people draining your balance.
  • Keep the sid server-side. Tie it to the user’s session rather than trusting a sid sent by the client.
  • Don’t resend by starting new verifications in a loop. Wait for the fallback or for the code to expire first.