Skip to content

OTP & verification

Codes by text, or by a call

The Verify API sends a one-time code by SMS or reads it aloud on a call, checks what the user types, and bills only the message or call. No per-verification fee on codes.

  • SMS and voice OTP
  • Pumping limits built in
  • No verification fee on codes

In short

The Verify API makes the code, sends it and checks it: two requests, SMS or voice, with only a hash of the code ever stored.

Codes go out on the best-quality route for each destination, premium-rate and pumping ranges are refused, and every number has a resend cooldown and an hourly cap. You pay the route rate for the SMS or call plus a fee capped at $0.001, with no per-verification charge on codes. Call-in verification skips the SMS entirely: the user calls your own phone number, for $0.01 per approved verification plus the number's monthly price.

What you can do

  • Verify API

    Start and check a code in two requests. Hashed, single use, five attempts.

  • Voice OTP

    A call that reads the code aloud, in English, Spanish, French, German, Portuguese or Hindi.

  • Call-in verification

    The user calls your own phone number, free for them. No SMS, $0.01 per approved verification plus the number's monthly price.

  • SMS OTP

    Codes by text in seven languages, sent from your brand name.

  • Your own codes

    Keep code generation in your app and send through the SMS or voice API instead.

How it works

Two requests from sign‑up form to verified number

The Verify API makes the code, sends it and checks it. You never store a code, and you pay only for the message or call that carried it.

  1. Step 1

    Take a key

    Open a free account and create a key with the Verify permission. A test key runs the whole flow on sandbox credit and hands you the code, so you can finish a check without a phone.

  2. Step 2

    Start a verification

    POST /verify/start with the number and a channel: sms, voice for a call that reads the digits aloud, or call_in to have the user call your own phone number. Codes go out on the best-quality route for the destination unless you name a strategy.

  3. Step 3

    Check what they typed

    POST /verify/check with the verification ID and the code. The answer is approved, denied, expired or max_attempts, and a code works once.

  4. Step 4

    Set the guard rails

    Fund a prepaid balance, set a daily spend alert and a low-balance alert. Per-number limits and blocked premium-rate ranges are on from the first request.

Verify API

No codes to generate, store or expire

Start a verification and we create a code of 4 to 10 digits, send it in your brand name and keep only a hash of it. Check it with the ID we returned: five attempts, one use, ten minutes by default. The code never appears in a database row, a log line or a live API reply, so there is nothing of value to leak on your side or ours.

  • SMS in English, Spanish, French, German, Portuguese, Hindi or Arabic; voice in all but Arabic
  • Expiry from 1 to 60 minutes, code length from 4 to 10 digits
  • Prefer your own codes? Send them through the SMS API, or speak them with POST /comms/voice-otp
  • Or no code at all: with channel call_in your user calls your own phone number, bought in the DID Store in their country
Verify API · start and checkExample
1. Send the code
SMS or voice
POST /v1/verify/start

{ "to": "+447700900431",
  "channel": "voice",
  "language": "es",
  "brand": "Acme" }
{ "verificationId": "5f0c…e21a",
  "status": "pending",
  "expiresAt": "…T10:10:00Z",
  "maxAttempts": 5 }

We generate the code and keep only a hash of it. The call reads the digits aloud in Spanish, twice, then hangs up.

2. Check what the user typed
5 attempts, single use
POST /v1/verify/check

{ "verificationId": "5f0c…e21a",
  "code": "482916" }
approveddeniedexpiredmax_attempts
Or let them call in
On your own number
POST /v1/verify/start

{ "to": "+17735550100",
  "channel": "call_in",
  "reference": "user-8812" }
{ "status": "pending",
  "callNumberDisplay": "+1 (773) 555-0142",
  "price": "0.010000" }

That is your own number from the DID Store. Your user calls it from their phone; the call ends unanswered, free for them, and the verification.approved webhook fires.

Voice OTP

A code they can hear, for when a text will not do

Landlines, patchy SMS coverage and users who never see the text: start the same verification with channel voice and the phone rings with the code. The call names your brand, reads the digits one at a time, repeats them, and hangs up. It rides the voice route for the destination and is billed on that route's increment, with no text-to-speech surcharge.

  • Six spoken languages: English, Spanish, French, German, Portuguese and Hindi
  • The digits are read twice by default, up to three times
  • If a carrier refuses the SMS, the reply tells you to retry by voice, and the refused attempt does not count against the number's limit
A woman at a desk listening to a phone call, pen ready over a notepad, to take down a spoken sign-in code

SMS pumping

An attack meets limits before it meets your balance

SMS pumping turns a sign-up form into someone else's revenue: scripts request codes to numbers that earn a payout per message. The Verify API refuses premium-rate, satellite and known pumping ranges outright, caps how often one number or one number range can be sent a code, and fails closed if those limits cannot be checked. Behind that sits a prepaid balance with a floor at zero, so the worst day has a ceiling you set.

  • 5 codes per number per hour, 30 seconds between resends, 20 per number range per hour
  • A daily cap of 1,000 verifications per account, raised on request
  • Embargoed destinations and numbers on your do-not-contact list are refused before anything is charged
  • Daily spend and low-balance alerts, the balance.low webhook, and auto-recharge with its own daily cap
  • Call-in verification sends no message at all, so there is nothing to pump: the user calls you, and the call is free for them
Billing · Spending alertsExample
Balance
$214.60
Prepaid, floor at $0.00
Spent today
$41.06
Since 00:00 UTC
Spending alerts
Email alerts on
Daily spend cap alert$40.00

Alert me when today's spend exceeds $40.00.

Low-balance alert

Alert me when my balance drops below $50.00.

$50.00
Auto-recharge on
Saved card
When balance falls below
$50.00
Reload amount
$100.00
Daily cap
$300.00
Daily spend cap reached14:05 UTC · also by email

You've spent $41.06 today, above your $40.00 daily cap.

One request

Verify a number in two requests

No onboarding call and no waiting for an account manager. Create an account, take your API key and post to the endpoint below, the same one that carries live traffic. Test keys let you try a request without sending a real message or call.

verify.sh
curl https://packetexchange.io/api/v1/verify/start \
  -H "Authorization: Bearer $PE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to":"+447700900123","channel":"voice"}'

curl https://packetexchange.io/api/v1/verify/check \
  -H "Authorization: Bearer $PE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"verificationId":"<id>","code":"482916"}'
REST API and MCPRated per SMS or call, ledger-verified

Built for verification

What sits between your login and the handset

  • Quality-first routing

    Codes default to the best-quality strategy: the most specific prefix, then the highest stated answer rate, with price only breaking a tie.

  • SMS, voice or call-in, one API

    The same start and check requests for SMS and voice codes. Or use call-in, where the user calls you and there is no code to type.

  • Hashed, single-use codes

    Only a keyed hash is stored. Five wrong guesses or the expiry ends the verification, and an approved code cannot be used twice.

  • Risky ranges refused

    Premium-rate, satellite and known pumping ranges are refused before a limit is spent or a cent is charged, and so are embargoed destinations.

  • Limits per number and range

    Resend cooldown, hourly caps per number and per number range, and a daily account cap. Two simultaneous resend taps cannot both slip through.

  • Keys scoped to verify

    Give your auth service a key that can start and check verifications and nothing else. It cannot buy routes, top up or read your account.

  • Seven languages

    Message templates in seven languages and spoken codes in six, with your brand name in the text or read out at the start of the call.

  • A record of every attempt

    Look up any verification for its status, attempts and the cost of its message or call, and find the send itself in your message history and CDRs.

Verification without the verification tax

A one-time code is a short message or a short call. Here it is priced like one.

Platform fee
2%, capped at $0.001
Prepaid from
$5, card or crypto
Contract
None, no monthly minimum
  • No per-verification fee on codes

    A code costs the route's rate for the SMS or call, plus a platform fee capped at $0.001. Nothing is added per attempt, per successful check or per month. Call-in has one flat price instead: $0.01 when approved, plus your phone number's monthly price, with no message to pay for.

  • Built to land, not just to leave

    Quality-first routing and stated route tiers put codes on the paths most likely to reach the handset, because a code that never arrives is a sign-up that never finishes.

  • Exposure capped in advance

    Blocked ranges, per-number limits, a prepaid balance with a floor at zero and a daily cap on auto-recharge put a number on your worst day before it happens.

  • Hosted or yours, same price

    Use the Verify API, or keep code generation in your own app and send through the SMS or voice API. Both bill the same way, so there is nothing to migrate away from.

Side by side

A typical verify product, and this one

What you payA typical verify product: A price per verification, on top of the messages it sendsOn PacketExchange: The route's rate for the SMS or call, plus a fee capped at $0.001. Call-in: your number's monthly price plus $0.01 when approved, nothing if it expires
ChannelsA typical verify product: Voice sold as a separate add-onOn PacketExchange: SMS and voice codes through the same start and check requests, plus call-in with no message at all
Route choiceA typical verify product: Decided inside the provider, out of viewOn PacketExchange: Best quality by default, or cheapest, balanced or a route you bought
Spend exposureA typical verify product: Often postpaid, so a pumping attack surfaces on the invoiceOn PacketExchange: Blocked risky ranges, per-number limits and a prepaid balance with a floor at zero
RetriesA typical verify product: A double tap can send two codesOn PacketExchange: A 30-second resend cooldown per number, claimed atomically

Built for

Who runs traffic on it

  • Login 2FA

    A second factor at sign-in and for step-up checks.

  • Transaction signing

    Confirm payments and account changes.

  • Sign-up checks

    Prove the number is real before the account is.

Pricing

A code costs what its message or call costs

verification fee on top of a code
$0
platform fee on the carrier cost
2%
fee cap per code
$0.001

An SMS code is billed per segment at the route's rate. A voice code is billed at the route's per-minute rate on its billing increment. Either way the platform fee is 2% of that amount, never above $0.001, and there is no verification fee or speech surcharge on top.

Call-in verification runs on your own phone number from the DID Store, at that number's normal monthly price, plus $0.01 per approved verification taken from your balance. There is no message or call to pay for, the caller pays nothing, and a verification that expires without a call is free.

No monthly fee and no minimum volume. Fund a prepaid balance from $5 by card or crypto, or from $100 by bank wire.

What you pay for

  • Route rate

    Per SMS segment or per call, as listed on the route for the destination's longest matching prefix.

  • Platform fee

    2% of the carrier cost, capped at $0.001 per code.

  • Refused sends

    An SMS a carrier refuses is reversed in full and does not count against the number's hourly limit.

  • Rates side by side

    Every SMS and voice route shows its rate before you send, on the marketplace and on developer pricing.

Test keys run the whole flow on invite-only sandbox credit, return the code so you can check it, and deliver nothing.

Questions

What security and growth teams ask

The questions buyers ask before they start. Anything not covered here is in the help centre, or ask the team directly.

Do I have to use the Verify API?
No. The Verify API generates, sends and checks the code for you. If you would rather keep codes in your own app, send them through POST /comms/sms in your own wording, or have a call speak them with POST /comms/voice-otp. The price is the same either way: the message or call.
Does it fall back from SMS to voice automatically?
No, you decide. If a carrier refuses the SMS, the start request returns an error that suggests channel voice, and the refused attempt does not use up the number's hourly limit. Start again with channel voice and the same check request works.
What does one code cost?
For SMS, the route's per-segment rate for the destination plus 2%, capped at $0.001. A short code message fits in one segment. For voice, the route's per-minute rate for the billed seconds of a short call, plus the same capped fee. The cost of each send is recorded against the verification.
How do I limit what an SMS pumping attack can cost?
The Verify API already refuses premium-rate and known pumping ranges and caps codes per number and per number range. Add a prepaid balance sized to a few normal days, a daily spend alert, a capped auto-recharge, and bot checks in your sign-up form where you can see the requests.
Which sender or caller ID is used?
SMS codes go from your brand name as an alphanumeric sender unless you pass your own. Every SMS route lists whether it carries alphanumeric, numeric or pre-registered senders before you buy. A voice code presents the caller ID you pass in from.
What is call-in verification, and when should I use it?
Instead of sending a code, your user calls one of your own phone numbers from the phone being verified. You buy the number in the DID Store, in the country of the people you verify, and switch on call-in for it. The call is matched by its caller ID and ended without being answered, so it is free for them, and you pay $0.01 when it is approved, plus the number's monthly price. With no text message there is nothing to pump, filter or block. It works in any country where you hold one of our phone numbers. A caller ID is weaker proof than a code, so use call-in for sign-up and phone number confirmation, and keep codes for account recovery, payments and other high-risk actions.
Can I test the whole flow first?
Yes. A test key runs against invite-only sandbox credit. The start is routed and priced on a real route, nothing is delivered, and the reply includes the code as testCode so you can complete the check in your test suite.

Put your next sign‑in code on a quality route

Open a free account, build the flow on a test key, then fund a balance from $5 and go live with SMS and voice codes on the same two requests.