Fraud prevention May 16, 2026 RequestGuard Team

How to build a risk-based signup flow

Design a signup flow that quietly scores risk, challenges suspicious sessions, and protects product value without punishing legitimate users.

A risk-based signup flow protects the business without making every real user prove they are not a bot. It quietly checks context first, then applies friction only when the risk justifies it.

Step 1: Score the signup

Send the request context before creating the account:

const assessment = await requestGuard.assess({
  ip,
  email,
  domain: email.split("@")[1],
  userAgent,
  event: "signup",
  sessionId,
  metadata: {
    plan,
    signup_source: source,
    invite_token: Boolean(inviteToken),
  },
});

Step 2: Map decisions to UX

Use four outcomes:

  • allow: create the account and continue onboarding.
  • challenge: require email verification, CAPTCHA, or OAuth.
  • review: create a limited account or delay sensitive features.
  • block: stop obvious abuse.

This keeps the normal path fast and reserves friction for suspicious sessions.

Step 3: Gate expensive features

Signup is only the first boundary. Re-score before API keys, team invites, exports, credits, coupons, or checkout.

Attackers often behave normally until they reach the feature that creates cost. Put fraud checks at those value boundaries.

Step 4: Store the request ID

Store request_id with the account. When support or fraud teams need to understand a decision, the request ID connects the account to the risk score, reasons, and signal snapshot.

Final pattern

Risk-based signup is not about adding a wall. It is about giving good users the fastest path and giving suspicious users the right amount of friction before they can create cost.