Home/ Documentation/ Use cases/ Fraud prevention Intermediate 15 min

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
truefalseLowProceed
truetrueMediumStep-up auth
falsefalseMediumStep-up auth
falsetrueHighBlock / 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 maxAge to 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