Fraud prevention with Network APIs
Account takeover (ATO) is one of the most common fraud vectors in digital onboarding and login. This guide shows how to combine two Konera signals — Number Verification and SIM Swap — into a single, real-time risk decision, without OTPs or friction for legitimate users.
The account-takeover problem
Attackers who gain access to a victim's phone number — through a SIM swap or port-out — can intercept SMS one-time passcodes and take over accounts protected by SMS-based 2FA. The two questions you need to answer at a high-risk moment are:
- Is this number actually bound to the device making the request? → Number Verification
- Has this number's SIM changed recently? → SIM Swap
What you'll need
- An application registered to Number Verification and SIM Swap (both use the same auth strategy — see Your first verified API call)
- A valid access token (see OAuth2 with Konera)
- The end user's phone number, captured at the moment of the risk event
Step 1 — Verify the number is bound to the device
Number Verification confirms the phone number belongs to the SIM in the device making the request — silently, over the mobile network, with no OTP.
curl -X POST https://api.pxg.konera.com/camara/number-verification/v2/verify \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"phoneNumber":"+14155550123"}'Response:
{ "devicePhoneNumberVerified": true }false here is a strong signal: the number the user claims is not the one on the device. Treat as high risk.
Step 2 — Check for a recent SIM swap
SIM Swap tells you whether the SIM associated with the number changed within a recent window. A swap just before a login or high-value transaction is a classic ATO indicator.
curl -X POST https://api.pxg.konera.com/camara/sim-swap/v2/check \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"phoneNumber":"+14155550123","maxAge":2400}'Response:
{ "swapped": false }maxAge is the lookback window in hours (here, 100 days ≈ 2400h). swapped: true means the SIM changed inside that window — escalate.
Step 3 — Combine the signals into a decision
Neither signal alone is a verdict — together they form a risk score. A simple decision matrix:
| Number verified | SIM swapped | Risk | Action |
|---|---|---|---|
| true | false | Low | Proceed |
| true | true | Medium | Step-up auth |
| false | false | Medium | Step-up auth |
| false | true | High | Block / manual review |
A minimal orchestration:
const verified = await numberVerification(phone); // { devicePhoneNumberVerified } const swap = await simSwapCheck(phone, 2400); // { swapped }
if (!verified.devicePhoneNumberVerified && swap.swapped) { return "BLOCK"; // high risk } if (!verified.devicePhoneNumberVerified || swap.swapped) { return "STEP_UP"; // medium risk — extra verification } return "PROCEED"; // low risk
Interpreting the signals well
- Tune
maxAgeto the action's value. A login might look back 72h; a high-value transfer might look back 30 days. - Don't block on SIM swap alone. Legitimate users replace SIMs (lost phones, upgrades). Pair it with another signal before a hard block.
- Number Verification needs the request over mobile data — on Wi-Fi the network can't always confirm the binding. Fall back to step-up auth, not a block.
- Log the correlation ID from each response so a declined session can be traced (see Rate limits & error handling).
Next steps
- KYC & identity verification — add identity matching on top of these signals.
- Testing with sandbox numbers — synthetic numbers that return each signal combination above.
- Working with callbacks — for asynchronous verification flows.