Stopping free-trial abuse without punishing real signups
You cannot make trial abuse impossible. You can make it more expensive than it is worth, and the levers that do that are not the ones most teams reach for first.
Contents
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
- Disposable email screening. Highest volume removed per unit of friction, and invisible to honest users.
- Line-type awareness on the phone field, if you collect one. Cheap, and the ambiguity is manageable if you route rather than block.
- 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.
voipline 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.