# How to stop free-trial abuse in a SaaS or AI app | Nolgard

> Link new signups to earlier accounts on the same device or mailbox and give repeats a smaller trial. Steps, code, approaches compared and FAQ.

Source: https://nolgard.com/guides/stop-free-trial-abuse/
Last updated: 2026-10-26

[Nolgard](https://nolgard.com/) / [Guides](https://nolgard.com/guides/) / How to stop free-trial abuse in a SaaS or AI app

Guide

# How to stop free-trial abuse in a SaaS or AI app

**Short answer.** Link each new signup to accounts already created from the same browser, device or mailbox, then give repeats a smaller trial instead of blocking them. Normalize email aliases, flag disposable domains, run in watch-only mode for two weeks, and fail open with a reduced grant when the check is unavailable. A CAPTCHA does not stop one human with many inboxes.

Last updated 2026-10-26 · Written by the Nolgard team

## Why trials get abused

A free trial or a bag of free credits is worth real money when each account costs you model tokens, SMS or compute. The cheapest way to get more of it is a new email address. Most repeat signups are one real person in one real browser, so bot checks pass them every time.

## Steps

- **Normalize the email before you look it up.** Gmail ignores dots and plus tags, so `jane.doe+2@gmail.com` and `janedoe@gmail.com` are one mailbox. Nolgard folds aliases for Gmail, Outlook, iCloud, Fastmail and Proton and reports them as `repeat.emailAliases`.

- **Link accounts to the browser and device.** Load `client.js` on the signup page and send the token with the form:

```
<script src="https://nolgard.com/v1/client.js" data-site-key="SITE_KEY" defer></script>
<script>
  // on submit
  await Nolgard.ready;
  const token = await Nolgard.execute({ action: 'signup' });
  // send token with the form to your backend
</script>
```

- **Verify on the server with the account.** Pass your account id and email so the signup joins its cluster:

```
// 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();
```

- **Grade the trial, do not block.** A repeat gets `decision: "limit"` and a smaller `grant.share`. Offices and families share devices, so a smaller grant costs a false positive far less than a rejection. See [trial grants](https://nolgard.com/features/trial-grants/).

- **Start in Observe mode.** Nothing is enforced and every event records `wouldDecide`. Compare it with accounts you already know were abuse, then switch to enforcing. See [Observe and tuning](https://nolgard.com/docs/tuning/).

- **Label what you learn.** Send chargebacks and confirmed abuse as Fraud, paying users as Legit, with `POST /v1/feedback`. A Legit device label clears repeat limits for 30 days.

## Approaches compared

| Approach | Stops the same person with a new email? | Friction for real users | Notes |
| --- | --- | --- | --- |
| Email verification | No. A new inbox verifies fine. | Low | Still worth keeping; it proves the inbox exists. |
| Block disposable domains | Partly. Gmail aliases pass. | None | Lists go stale; pair with alias folding. |
| CAPTCHA or Turnstile | No. A human solves it every time. | Low to medium | Good against scripts, not against repeat humans. |
| Card on file | Mostly, with card fingerprinting by your payment provider. | High; fewer trials start | Changes your funnel, not just your fraud rate. |
| Phone verification | Mostly, until virtual numbers. | High; SMS costs money | Can invite SMS pumping. See [SMS pumping](https://nolgard.com/docs/sms-pumping/). |
| Device and alias linking (Nolgard) | Yes, within 30 days on the same browser or device, or the same mailbox. | None visible | A fresh device, browser and email can still evade it. |

## Questions

### Should I block repeat signups outright?

Usually no. A shared device is evidence, not proof: an office, a classroom or a family shares one. Give repeats a smaller trial with `limit` and keep `block` for clear automation.

### How many accounts per device are normal?

Nolgard's default repeat threshold is three. The fourth distinct device-linked account within 30 days triggers `repeat_device`. You can tune it per site.

### What if the check is down or I am over quota?

Fail open with a reduced grant, for example 20 percent of the trial. The Node SDK does this with `failOpenShare`, default 0.2. Fail closed only on config errors such as a wrong secret.

### Do I need a credit card on signup to stop abuse?

No. A card cuts abuse and trial starts at the same time. Measure repeat signups first with the [trial abuse calculator](https://nolgard.com/tools/trial-abuse-calculator/), then decide.

### Does this work for mobile apps?

Not yet. Nolgard covers browsers only.

## Sources

- [Nolgard docs: trial grants and decisions](https://nolgard.com/docs/#trial)
- [Nolgard: repeat accounts and limits](https://nolgard.com/features/repeat-accounts/)
- [Nolgard docs: when verify fails](https://nolgard.com/docs/#failures)
- [Google: Gmail ignores dots in addresses](https://support.google.com/mail/answer/7436150)

## Related

- [Detect repeat signups without storing raw PII](https://nolgard.com/guides/detect-repeat-signups-without-storing-pii/)
- [Signup abuse signals](https://nolgard.com/guides/signup-abuse-signals/)
- [Nolgard compared](https://nolgard.com/compare/)

[Read the docs](https://nolgard.com/docs/)[Start free](https://nolgard.com/app/#/signup)
