Markets open
A laptop at a two-factor sign-in step while a phone in hand shows a one-time code
OTP & Verification

Codes on yourbest routes

Send one-time passcodes by SMS on routes picked for quality over price, from a prepaid balance, with spend alerts that flag an SMS pumping spike early.

Quality-first routingYour code, your templateSpend you control
In short

You generate the code and check it; we carry it.

Each code goes out on the best-quality route for its destination, from a numeric or alphanumeric sender, and you pay the route rate per segment instead of a per-verification premium. A prepaid balance and spend alerts keep an SMS pumping attack from running up a bill.

What you can do

SMS OTP

One-time passcodes sent through the SMS API, in your own wording.

2FA / MFA

Second-factor codes for login and step-up auth.

Number verification

Confirm a user controls a phone number at signup.

Spend controls

Prepaid balance and spend alerts, so abuse shows up before it costs you.

From sign-up form to first code

Codes flowing in four steps

You keep the code, the template and the check in your own app. PacketExchange supplies the route, the price and the guard rails.

  1. 01

    Keep the code in your app

    Generate the code, store it and set its expiry and resend rules where your login logic already lives. Nothing about your flow is hosted with us.

  2. 02

    Choose how codes are routed

    Send with strategy best_quality for every destination, or name an SMS route you bought for the markets that matter most to your sign-ups.

  3. 03

    Set the guard rails

    Fund a prepaid balance, set a daily spend alert and a low-balance alert, and give the sending key the Send SMS permission only.

  4. 04

    Send, then check

    Post the code with an idempotency key, then check what the user types against your own record. The reply tells you exactly what the message cost.

Quality before price

Codes on the route most likely to land

An abandoned sign-in costs more than any message. With strategy best_quality, Smart Routing takes the SMS routes that serve the destination, prefers the most specific prefix, ranks them by quality and uses price only to break a tie. Every route states its tier, so you can see whether a code went over a direct interconnect or a path through several carriers. And because the code rides the route's own rate, choosing quality adds no per-verification premium.

  • Direct: the seller's own carrier interconnect to the destination
  • Premium: at most one carrier between the route and the destination
  • Sent or failed, the segment count and the exact cost, all in the same reply
SMS send · best_qualityExample
POST /v1/comms/sms
X-Idempotency-Key: signup-8c41e2

{ "to": "+447700900431", "from": "Acme",
  "strategy": "best_quality",
  "message": "Your Acme code is 482916. It expires in 10 minutes." }
Smart Routing candidates
UK mobile, +44 7
RouteTierStated ASRPer segmentPick
Route ADirect96%$0.0342Chosen
Route BPremium91%$0.0296·
Route CStandard84%$0.0231·

Ranked by stated ASR first. Price only breaks a tie.

Segments
1
51 characters, GSM-7
Charged
$0.0349
Includes a $0.0007 fee
Status
Sent
Retry with the same key: same reply
SMS pumping

An attack can only spend what you funded

SMS pumping turns a sign-up form into someone else's revenue: scripts request codes to numbers that earn a payout per message, and the bill lands on you. On PacketExchange that bill has a ceiling you set in advance. Every code is paid from a prepaid balance, alerts reach you while the spike is still running, and any number abusing your form can be blocked with one API call.

  • A hard floor at a zero balance, and no credit line to run up
  • A daily spend alert by notification and email, checked every five minutes against today's spend
  • A low-balance alert and the balance.low webhook, so your own systems can react
  • Auto-recharge with its own daily cap, so a spike cannot keep refilling from your card
  • Numbers on your do-not-contact list are refused before routing and cost nothing
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 segment per code

One apostrophe can double the cost of a code

At verification volumes, segments are the bill. A curly apostrophe pasted from a design file, or a padlock emoji, is not a GSM-7 character: it switches the whole message to Unicode, where one segment holds 70 characters instead of 160. A 79-character code message that fits one GSM-7 segment splits into two and costs twice as much. Segments are counted in the real encoding before sending and returned on every reply, so a template that drifts shows up in your first test send rather than on the invoice.

  • Send a template on a test key and read its segments and cost from the reply
  • Your wording, language and code length, with no hosted template to fit into
Message segmentsExample
Straight apostrophe

Your Acme code is 482916. It expires in 10 minutes. Don't share it with anyone.

Encoding
GSM-7
Characters
79
Segments
1
Per code
$0.0349
Curly apostrophe, pasted from a design file

Your Acme code is 482916. It expires in 10 minutes. Dont share it with anyone.

Encoding
UCS-2 (Unicode)
Characters
79
Segments
2
Per code
$0.0694
100,000 codes, straight
$3,488.40
1 segment each
100,000 codes, curly
$6,940.00
2 segments each, same words
One request

Send the first one in a minute

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 it without sending a real message or call.

send-otp.sh
one request
curl https://packetexchange.io/api/v1/comms/sms \
  -H "Authorization: Bearer $PE_KEY" \
  -d to="+447700900123" \
  -d from="Verify" \
  -d message="Your code is 482-916" \
  -d strategy="best_quality"   # OTP-grade route
REST API + MCPrated per message · ledger-verified
Built for verification

What sits between your login and the handset

Each of these works on the send path today, through the same API your other messages use.

Quality-first routing

strategy=best_quality picks the highest-rated SMS route for each destination, with price as the tiebreak and the most specific prefix preferred.

Routes you pin

Name a purchased SMS route in the request and codes for that market always take it, at that route's own rate.

Safe retries

An X-Idempotency-Key makes a retried send harmless: the first reply comes back again and no second message goes out.

Keys that can only send

Give the key your auth service holds the Send SMS permission and nothing else. It cannot buy routes, create top-ups or read your account.

A limit on every key

Each key is held to 10 send requests a second, so a scripted burst through your form is capped at the API before it becomes a bill.

Embargo screening

Destinations under embargo are refused before any route is chosen and before anything is charged, on every API send.

Codes in any language

Write templates in any script. Non-Latin text is counted as UCS-2 before sending, so a code message in Arabic, Thai or Cyrillic is priced on its real segments.

An audit trail for every code

Each send is recorded with its destination, segments and cost, and listed by date range in your message history and CDRs when you investigate a spike.

Why PacketExchange

Verification without the verification tax

A one-time code is a short SMS. Here it is priced like one.

No per-verification premium

A code costs the route's rate per segment plus a platform fee capped at $0.001. Nothing is added per attempt, per successful check or per month.

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

A prepaid balance, a floor at zero, spend alerts and a daily cap on auto-recharge put a number on your worst day before it happens.

Your flow stays yours

Codes, templates, expiry and checks live in your app, so there is no hosted flow to migrate away from and nothing to rebuild when your sign-in changes.

Side by side

A hosted verify product, or your own flow on quality routes

A hosted verify productOn PacketExchange
What you payA price per verification, on top of the messages it sendsThe route's per-segment rate plus a fee capped at $0.001 per message
Codes and templatesGenerated and worded inside the provider's templatesGenerated, worded and checked in your own app
Route choiceDecided inside the provider, out of viewbest_quality on each request, or a route you bought, with its tier stated
Spend exposureOften postpaid, so a pumping attack can surface on the invoicePrepaid with a floor at zero, daily spend alerts and a capped auto-recharge
RetriesA timed-out request can send a second codeAn idempotency key replays the first reply instead
Blocking a numberA support request, or a separate fraud productOne API call to your do-not-contact list, refused before routing and never billed
Built for

Login 2FA

Secure account access with step-up verification.

Transaction signing

Confirm high-value or sensitive actions.

Signup checks

Confirm the number is real before the account is.

Pricing

A code costs what the message costs

Each code is an SMS, billed per segment at the route's rate with a platform fee of 2% of that amount, never above $0.001 per message. A short code message kept to GSM-7 characters fits in one segment.

There is no per-verification fee, no monthly fee and no minimum volume. Fund a prepaid balance from $5 by card or crypto, or from $100 by bank wire.

See SMS routes by destination
  • Route rate

    Per segment, 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

    Reversed in full when a route refuses the message.

  • Auto-recharge, if you want it

    A reload from a saved card when your balance falls below your threshold, within a daily cap you set.

Test keys run your whole verification flow against $50 of sandbox credit, with no codes delivered.

Questions

What security and growth teams ask

Do you generate or check the codes?

No. Your application creates the code, sends it through the SMS API in whatever wording you choose, and checks what the user enters against its own record. That keeps expiry, attempt limits and resend rules under your control.

What does one code cost?

The route's per-segment rate for the destination, multiplied by the segments, plus 2% of that, capped at $0.001. A code message of up to 160 GSM-7 characters is one segment, and the exact cost is returned in every reply.

How does best_quality choose a route?

It takes the SMS routes that serve the destination, prefers the most specific prefix match, then ranks by quality with price as the tiebreak. If you would rather fix the choice for a market, pass the ID of a route you bought.

How do I limit what an SMS pumping attack can cost?

Keep the prepaid balance to what a normal few days of codes needs, set a daily spend alert and a low-balance alert, cap auto-recharge per day, and add abusive numbers to your do-not-contact list. Attempt limits and bot checks belong in your sign-up flow, where you can see the requests.

What if a request times out and my server retries?

Send an X-Idempotency-Key with each code. A retry with the same key and the same body returns the original reply for 24 hours, so the user receives one code and you pay for one message.

Which sender ID should I use?

A numeric or alphanumeric sender that the route for the destination carries. Every SMS route lists its sender ID type, alphanumeric, numeric or pre-registered, before you buy.

Can I test the whole flow first?

Yes. A test key runs against $50 of sandbox credit, added when you redeem an invite code. Each test send is routed and priced on a real route and returns its segments and cost, but no code is delivered and your balance is untouched.

What happens when my balance reaches zero?

Sends are refused with an insufficient balance error and nothing is charged. To keep codes flowing, turn on auto-recharge with a saved card: it tops the balance up when it falls below your threshold, within the daily cap you set.

Put your next code on a quality route

Open a free account, build the flow on a test key with $50 of sandbox credit, then fund a balance and set your spend alerts before the first real code goes out.