otp policy, and only fire the SMS if tracenow clears it.
Which event this protects
SMS pumping maps to theotp event. The Cloudflare Worker fires it on every POST to your OTP-send route, before your app calls your SMS provider. If the verdict is deny, the message is never sent and you pay nothing.
How it works
When a request hits your OTP endpoint, the Worker:- Reads the phone number from the request body and the IP from the request.
- Attaches the device fingerprint token.
- Calls
/tracewithevent: otp; phone enrichment and velocity checks run in parallel. - Evaluates your SMS pumping policy.
deny→ the Worker returns a block response; your SMS provider is never called.allow/challenge→ forwarded to your app.
Signals used
See Signals for the full field reference.
Fully covered at the edge. SMS-pumping signals (phone quality, IP, velocity, device) are all
available before sign-in, so the Cloudflare Worker covers this use case with no backend code.
Add the optional server-side call only if you want per-user OTP-failure
velocity tied to a real account.
Set it up
1
Connect Cloudflare (if you haven't already)
In the dashboard under Integration, paste a Cloudflare API token with Workers Scripts: Edit
and Zone → DNS: Read scopes. tracenow validates the token and lists your zones.
2
Add a route rule for your OTP endpoint
Under Integration → Routes, add a rule:
- Route pattern: e.g.
yourdomain.com/api/auth/otporyourdomain.com/send-otp - Method:
POST - Event:
otp - Mode: start with
Monitorto observe real traffic before blocking
3
Enable the SMS pumping policies
Under Guard, enable the pre-built SMS pumping policy templates for the
otp event in Monitor mode. To customize or add your own rules, see Rules.4
Switch to Enforce mode
After reviewing Monitor traces and confirming the rules catch the right traffic, edit the OTP route and change Mode to
Enforce. Click Deploy.In Enforce mode, deny verdicts stop the request at the edge, so your SMS provider never receives the call. This is the critical step: the protection only prevents charges when Enforce mode is active.Rules
You don’t build these by hand. The pre-built SMS pumping policy templates cover these patterns and enable in one click. See Rules to customize them or add your own.What a caught attempt looks like
A pumping run produces many traces like this in the event feed:duration_ms on OTP traces is typically low. Phone enrichment is fast, so by the time you’d call your SMS provider, the verdict is already back.
Going further
The Cloudflare layer is the right tool for SMS pumping. OTP requests are pre-authentication, so there’s no user ID to attach, and the edge evaluation is sufficient. If your app verifies an OTP code (not just sends it), you can send a follow-up/trace call with status: succeeded or status: failed after the user enters the code. This seeds OTP failure velocity, which lets you catch accounts that request many codes but never enter a valid one: a signal of probing or credential enumeration.
velocity.user.failed_count_1h signal on the otp event then catches accounts burning through OTP codes, a pattern distinct from the sending-side abuse the Cloudflare layer catches.
See server-side integration for the full request and response reference.