Most fraud shows up somewhere you are already looking: a chargeback, a stolen account, a shipped order nobody paid for. SMS pumping shows up on a telecom invoice, and the fraud team usually hears about it from finance.
The mechanism is simple enough to explain in one sentence. Someone with a revenue share on terminating traffic to a particular number range drives your application to send one-time passcodes to numbers in that range, and gets paid a slice of what your messaging provider charges you. Nothing is stolen. You paid to send messages to yourself, and the industry name for it — artificially inflated traffic, or AIT — is more accurate than the popular one.
Why it stays invisible for weeks
Every alarm a fraud stack has is tuned for someone taking something. Pumping takes nothing:
- No accounts are created. The attacker usually abandons the flow at the OTP step, so your signup conversion barely moves.
- No chargebacks. No payment instrument is involved anywhere.
- No support tickets. Nobody is a victim in a way that generates a complaint.
- No traffic spike worth alerting on. A campaign that adds a few thousand sends a day disappears into normal volume on a busy service.
The result is that the loss accumulates as a line item on a bill nobody in the fraud team reads until the bill is surprising.
What it looks like in your own data
You do not need a vendor to find out whether this is happening to you. Four queries against the OTP log you already have will tell you.
1. Send-to-verify ratio, by country. This is the single strongest tell. Real users request a code and type it in; the ratio sits somewhere in the high tens of percent. Pumped traffic requests codes and never verifies, so the ratio collapses. A country where 4% of sent codes are ever entered is not a country with a delivery problem — it is a country with a pumping problem.
2. Country mix over time. Plot sends per country per day for the last ninety days. Pumping campaigns show up as a country that was a rounding error becoming a top-five destination in a week, with no marketing spend or press coverage to explain it.
3. Number-range concentration. Group by the first several digits after the country code. Legitimate traffic spreads across the carriers and prefixes people actually use. Pumped traffic concentrates hard, because the attacker only earns on ranges they control — a handful of prefixes taking a large share of a country's volume is the signature.
4. Resend behaviour. Real users who do not get a code hit resend once or twice and then give up or switch channel. Automated pumping often walks the resend button to its limit on every attempt, because each resend is another billable message.
Run those four and you will know within an hour whether you have a problem, and roughly what it costs per month.
The fixes, in the order they pay off
The instinct is to add a CAPTCHA. Do the cheap structural things first — they cost nothing and they do not tax every real user.
Cap the resend path. One code per number per minute, a small number per hour, a hard daily ceiling per number and per account. Most campaigns lose most of their value to this alone, and no real user notices.
Constrain the destinations. If you do not do business in a country, do not send to it. If you do business in twelve countries, an allowlist of twelve is not a restriction, it is a description of your business. For countries you do serve but where the ratio looks wrong, require a verified account or a second factor before the first SMS.
Charge the flow something. Not money — friction that is cheap for a person and expensive for a script: require the email step to complete first, or make the phone step reachable only from an authenticated session.
Screen before the send. The message costs money the moment it leaves. Everything you can learn about the session before that point is free, and the request that triggers an OTP is a request like any other: it comes from a network and from a device.
// POST /api/otp/send — screen BEFORE the message costs anything.
const verdict = await sentinel.evaluate({
token, // the client token from the form
accountId: user?.id, // stable id, if the user is known
});
// Automation, residential proxies and antidetect browsers are what
// drives pumped traffic. A plain VPN is a customer on a train.
if (verdict.decision === 'block') {
return res.status(403).json({ error: 'blocked', reasons: verdict.reasons });
}
if (verdict.decision === 'review') {
return sendAfterChallenge(phone); // CAPTCHA or email confirmation first
}
return sendOtp(phone);
Note the shape: review does not refuse the code, it makes the sender do something cheap first. Refusing every ambiguous session from a login flow is how you lock out real customers, and a locked-out customer costs more than one SMS.
Then talk to your provider. Most messaging platforms now offer geographic permissions, per-number rate controls and some form of pumping protection. They are worth enabling, and they are a backstop rather than a fix: the provider sees the message, you see the session, and the session is where the decision is cheaper.
Alert on the ratio, not the volume
Whatever you fix, leave the detector in place. A volume alert catches a burst and misses a slow campaign; a ratio alert catches both.
- Send-to-verify ratio per country, alerting on a relative drop rather than an absolute floor — countries legitimately differ.
- Share of daily sends going to the top five number prefixes per country.
- New-country alert: any destination that was under 0.1% of sends last month and is over 2% this week.
- Cost per completed verification, by country. This is the number to put in front of finance, because it converts the whole problem into one figure that either moves or does not.
That last metric is also how you prove the fix worked. Volume charts after an intervention are ambiguous — traffic could have fallen for a dozen reasons. Cost per completed verification is not: if it drops and completions hold, you removed waste rather than customers.
The short version
- SMS pumping bills you for messages you sent yourself; nothing is stolen, so nothing alerts.
- Find it with send-to-verify ratio by country, country mix over time, and prefix concentration.
- Fix the cheap structural things first: resend caps, destination allowlists, ordering the flow so SMS is not the first step.
- Screen the session before the send — automation and proxies are the traffic that pumps.
- Route
reviewto a challenge, not a refusal, or you will block real users out of a login flow. - Alert on ratios and cost per completed verification, not on volume.
Frequently Asked Questions
What is SMS pumping fraud?
A scheme where someone with a revenue share on terminating traffic to certain number ranges drives an application to send one-time passcodes to those numbers, earning a slice of what the messaging provider bills. The industry term is artificially inflated traffic, or AIT. Nothing is stolen from users — the loss lands entirely on the sender’s telecom bill.
How do I know if my app is being used for SMS pumping?
Check the send-to-verify ratio by country in your own OTP logs: real users enter the code they asked for, pumped traffic never does, so the ratio collapses. Then look at country mix over the last ninety days and at how concentrated sends are within a few number prefixes. A country that jumped from nothing to top-five, with a low verify ratio and heavy prefix concentration, is the signature.
Does a CAPTCHA stop SMS pumping?
It helps, and it is rarely the best first move. Resend caps, destination allowlists and requiring an earlier step to complete cost nothing and remove most of the value without taxing real users. A challenge is well placed on the ambiguous middle — sessions that come back as review — rather than on everyone requesting a code.
Where in the flow should the fraud check run?
Before the message is sent. The SMS costs money the moment it leaves your provider, so the decision has to happen on the request that triggers it. Screening the session at that point catches the automation, residential proxies and antidetect browsers that drive pumped traffic, while the message is still free to not send.
Screen the session before the SMS leaves
Maskbreak returns a verdict on the request that triggers the code — automation, residential proxy, antidetect browser. Free tier: 1,000 requests per hour, no card.
Try Maskbreak free →