01OTP fraud

Your SMS budget is someone else's revenue line.

SMS pumping isn't a break-in — it's a billing scheme. Automated traffic floods your “send code” endpoint with numbers that earn on delivery, and a share of what you pay for every message flows back to the operation behind it.

Spot the symptoms

Does this sound like you?

If even a couple of these feel familiar, it’s probably already happening on your platform.

Your SMS bill keeps climbing, but signups and successful logins stay flat.

What it means: You're paying to deliver codes that no one will ever read.

Codes go out by the thousands, but almost none are ever entered.

What it means: The traffic was never trying to sign in — delivery itself was the point.

Bursts of send-code requests go to number ranges that never once make it to verification.

What it means: Someone pointed your endpoint at numbers that get paid to receive messages.

Support occasionally hears “I never asked for this code” from real users.

What it means: A noisy pump also makes handy cover for the occasional real takeover attempt.

Two or more ringing true? It’s worth five minutes to find out for sure.
Under the hood

How the attack actually works

No security background needed — here’s the whole play, start to finish.

01

The route

The attacker controls numbers sitting on a route with high termination fees — their own ranges, or a revenue-share arrangement with a party in the delivery chain. Delivery is what pays.

02

The pump

An automated script hits your "send code" endpoint with those numbers. The code is never read, never entered. Nobody is trying to get in.

03

The payout

Your provider bills you per message. The fee travels down the chain and a share lands back with the attacker. Your telecom budget is their revenue line.

The costEvery party between your endpoint and the handset gets paid on volume. You're the only one who gets charged for it.
The fix

How SignalGate stops it

One call on your critical path. The verdict comes back before anything happens.

Campaign-scale detection

Reads your send-code traffic at system scale and separates one coordinated pumping operation from genuine verification requests — even when every single request looks normal on its own.

Visibility before enforcement

Start by logging sends and verifications — two fire-and-forget calls off your critical path. Within days the dashboard shows what share of your SMS spend belongs to a single operation, before anything is blocked.

Block before the message is sent

Once you turn on blocking, the verdict lands in under 3 ms at the send-code endpoint — the pump's message is never sent and the per-message fee is never charged. Real users' codes go out untouched.

allow for the real userblock for the attackin under 3 ms
In one sentence

Fingerprinting catches one device pretending to be many. SignalGate catches the opposite — many genuinely different devices working as one operation — the fraud that device fingerprinting alone was never built to see.

Integrate it

Wire it in, in minutes

Start with two fire-and-forget calls to /v0/log — log the action and the target action. No blocking, no user impact, nothing on your critical path.

Log OTP sends and verifications

from datetime import datetime, timezone
from signalgate import Client, Event, EncryptedPayload

client = Client(api_key="pk_live_...")

def sg_event(body: dict, method: str) -> Event:
    # Each request carries its OWN "signalgate" envelope from the browser SDK
    return Event(
        user_id=body["user_id"],
        ip=request.headers.get("X-Forwarded-For", request.remote_addr),
        method=method,
        timestamp=datetime.now(timezone.utc).isoformat(),
        payload=EncryptedPayload(**body["signalgate"]),
    )

@app.post("/api/otp/send")
def send_code():
    body = request.get_json()
    # ...send the SMS/email code...
    client.log(sg_event(body, method="otp.send"))      # AFTER the send succeeds
    return {"ok": True}

@app.post("/api/otp/verify")
def verify_code():
    body = request.get_json()
    # ...check the code the user entered...
    client.log(sg_event(body, method="otp.verified"))  # its own fresh envelope
    return {"ok": True}

Within days the dashboard shows how much of your traffic is one coordinated operation — before you turn on blocking.

SignalGate

Stop fraud before it reaches your backend.

Free for everyone through 2026. Two lines of code. No demo required.