# Stopping free-trial abuse without punishing real signups

_2026-09-08 · Boundstone (https://boundstone.io/blog/stop-free-trial-abuse)_


Free-trial abuse is an economics problem wearing a security costume. Nobody farms trials because your signup form is weak; they do it because a second account costs them almost nothing and is worth something.

So the question is not "how do I make this impossible." It is "how do I make the second account cost more than a trial is worth" — and the levers that do that are not the ones most teams reach for first.

## The cheapest identity is an email address

A throwaway inbox is free, instant, and infinitely renewable. Any abuse strategy that does not address it is optimising the wrong constraint.

`POST /v1/verify/email` returns a `disposable` boolean checked against a maintained list of throwaway providers, alongside syntax, a live MX lookup and role-account detection. Screening on that removes the highest-volume path in one call.

It is a strong filter, not a guarantee. A brand-new throwaway domain that nobody has catalogued yet will pass, and the response is honest about the boundary of what it checked: `smtp_mailbox` and `catch_all` come back in `checks.not_performed`, because nobody knocked on the individual mailbox.

## The second-cheapest is a VoIP number

If you ask for a phone number, ask what kind you got. `POST /v1/verify/phone` returns `line_type`, and a `voip` value means the number sits in a range designated for VoIP — which is where disposable numbers overwhelmingly come from.

Two cautions worth holding at the same time. Plenty of real people have VoIP numbers as their only phone, so this is a signal and not a verdict. And metadata catches *designated* VoIP ranges, not a VoIP service that has ported a number onto a mobile range — resolving that needs a live network dip, available with `hlr:true` at 5 credits on a paid plan.

## What raises the cost most, in order

1. **Disposable email screening.** Highest volume removed per unit of friction, and invisible to honest users.
2. **Line-type awareness on the phone field**, if you collect one. Cheap, and the ambiguity is manageable if you route rather than block.
3. **A payment card**, if your model tolerates it. This is the genuinely expensive one for a farmer and the genuinely expensive one for your conversion rate. It is a business decision, not a fraud one.

Notice what is not on the list: making the form longer. Extra required fields cost honest users far more than they cost someone running a script.

## Where these checks stop

Boundstone validates the email, phone or IP the form collected. It does not detect bots, fingerprint devices, or score behaviour — and on the IP side it does not do geolocation, ASN lookup, hosting or datacenter detection, proxy/VPN/Tor detection, or reputation. All five come back in `checks.not_performed`, because they need licensed data.

What the IP check does give you is format, version and range classification — enough to flag a source address that classifies as `private`, `loopback` or `reserved`, which have no business originating a public signup. That is a real signal and a narrow one.

If you need device fingerprinting or VPN detection, you need a fraud platform. We would rather say that than imply an `is_bogon` boolean is a threat verdict.

## Decide the policy before you collect the signals

The failure mode is not missing a signal. It is collecting three and having no rule for what a combination means, so every ambiguous signup becomes a judgement call somebody makes inconsistently at 4pm.

Write the policy first: which combinations allow, which route to a limited trial or a review queue, which block. Then collect only the signals that policy actually consumes.

## The short version

- **Trial abuse is economics, not security.** Aim to make the second account cost more than a trial is worth, not to make it impossible.
- **Disposable email is the cheapest identity.** Screening it removes the highest-volume path for the least friction.
- **A strong filter, not a guarantee.** New throwaway domains are not on any list yet, and the response names what it did not check.
- **`voip` line type is the second signal** — real people have VoIP numbers, so route on it rather than blocking.
- **Longer forms punish honest users, not scripts.** Friction is not a fraud control.
- **Boundstone does not fingerprint or detect VPNs.** Geolocation, ASN, hosting, proxy/VPN/Tor and reputation are all `not_performed`.
- **Write the policy before collecting signals**, or every ambiguous signup becomes an inconsistent judgement call.
