Guide

Signup abuse signals: what to check before you create an account

Short answer. Check four groups before you create the account: automation (headless browser, scripted input, filled decoy field), repeats (same device, browser or mailbox as earlier accounts), email quality (disposable, newly registered or alias domain) and network (many signups from one network in a day). No single signal is proof; combine them into a graded decision.

Last updated 2026-10-26 ยท Written by the Nolgard team

The signals

Signup abuse signals
SignalGroupNolgard field or reasonHow much to trust itCommon false positive
Headless or automated browserAutomationBrowser check tokenStrong aloneReal users with privacy extensions can look unusual.
Filled decoy fieldAutomationHoneypotMedium; enforced at most as challengeAgents that skip off-screen inputs avoid it.
Fourth account on one device in 30 daysRepeatrepeat_deviceStrong for trialsOffices and families share devices.
Email alias of an existing accountRepeatrepeat.emailAliasesStrongSome people use plus tags for filtering, honestly.
Disposable email domainEmailemail.disposableMediumPrivacy-minded users use relay services.
Newly registered email domainEmailDomain age and MXMediumNew companies have new domains.
Ten accounts from one network in 24 hoursNetworkrepeat_networkWeak to medium; never joins clustersUniversities, carriers and offices.
Burst of signups on one email domainEmailDomain burstMediumA team onboarding together.

Thresholds are Nolgard defaults from repeat accounts; you can tune them per site.

Steps

  1. Collect the browser token at submit with client.js, and pass it, the request IP and the account to /v1/verify.
    // Your signup handler, after the browser sent `token`
    const res = await fetch('https://nolgard.com/v1/verify', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        secret: process.env.NOLGARD_SECRET,
        token, remoteIp, action: 'signup',
        account: { id: newUserId, email }
      }),
      signal: AbortSignal.timeout(3000)
    });
    const result = await res.json();
    if (!result.success) return createAccount({ share: 0.2 }); // fail open, reduced grant (see /docs/#failures)
    if (result.decision === 'allow' || result.decision === 'limit')
      return createAccount({ credits: result.grant.credits ?? result.grant.share });
    if (result.decision === 'challenge') return askForEmailConfirmation();
    return reject();
  2. Read the reasons, not only the score. The response carries scores.automation, scores.repeat, scores.abuse and reason ids, so you can explain each decision to support or to the user.
  3. Map signals to a graded response. Automation goes to block or shadow, repeats to limit with a smaller grant, doubtful ones to challenge with your own email confirmation.
  4. Keep checking after signup. An account that passed can still burn credits. Send usage events and set spend caps.
  5. Feed back labels. POST /v1/feedback with Fraud or Legit so your next decisions use your own ground truth.

Questions

Which single signal catches the most abuse?

It depends on the product. For free trials it is usually repeats on the same device or mailbox; for contact forms it is automation. Run Observe mode and read your own events.

Should IP reputation decide a signup?

Not alone. Many honest people share one address behind a carrier or office. Nolgard counts network accounts but never joins accounts into a cluster by IP prefix.

Are disposable emails always abuse?

No. Some people use relay addresses for privacy. Treat a disposable domain as a reason for a smaller grant or email confirmation, not a block.

How do I explain a decision to a user who complains?

Use the reason ids in the event and the appeals flow. Label the account Legit if you were wrong.

What about AI agents signing up?

Verified agents are identified by Web Bot Auth signatures or the operator's official IP ranges, not the user agent string. See AI agents.

Sources

Related