Guide · AI products
Stop free credit abuse in AI apps
Free credits are how AI products get tried, and the easiest thing on the internet to farm. Every fake account spends real GPU or API money. These are the checks that stop the farming at signup, in the order that gives the most for the least work.
By the Vetto team · Updated
Quick answer
Give credits to inboxes, not accounts. Block throwaway domains at signup, normalize Gmail dots and +tags so one inbox gets one grant, and hold the credits until the email is confirmed. Add a per-IP limit for scripts. That closes the cheap loops; keep cards and device fingerprinting for organized abuse.
Why AI products get hit harder than other SaaS
On a classic SaaS, a fake trial account costs you almost nothing: a row in a database and a skewed signup chart. On an AI product each free account spends money the moment it is used. A worked example, with assumptions you should swap for your own numbers:
| Example | Value |
|---|---|
| Free credits per signup | 50 image generations |
| Your cost per generation (example) | $0.01 |
| Cost of one free account | $0.50 |
| One person with a script, 200 throwaway accounts | $100 |
| Same person, if credits wait for a confirmed, unseen inbox | $0.50 (one account) |
The point is not the exact figure, it is the shape: abuse cost grows with the number of accounts one person can create, and that number is set by your signup form. Throwaway inboxes take seconds to get, and Gmail treats jane.doe@gmail.com, janedoe@gmail.com and jane.doe+7@gmail.com as the same inbox, so to your database they look like three people. Check your own list: the Gmail alias checker and the user list audit are free and run in your browser.
The five checks, cheapest first
| Tactic | Looks like | Check that stops it |
|---|---|---|
| Throwaway inbox | k8x@mailinator.com | Block the domain at signup |
| Gmail dots and +tags | j.a.n.e+42@gmail.com | One grant per normalized inbox |
| Domain with no mail server | x@qwe-rty.net | MX check; never grant before confirmation |
| Scripted signups from a cloud server | 30 accounts in 10 minutes | Per-IP limits, datacenter network flag, honeypot |
| Fresh real address each time | jane.may@outlook.com | Lower grant until a card or phone, usage caps per network |
1. Block throwaway inboxes at signup
A disposable-domain list stops the laziest farming, which is usually most of it. Lists differ a lot in false positives, so test the one you use: in our test of 7 lists, one blocked Outlook domains. Keep privacy relays (Apple Hide My Email, Firefox Relay, DuckDuckGo) allowed: they forward to a real inbox, and blocking them loses careful paying users.
2. One grant per inbox, not per account
Store a normalized key next to the email (lowercase, googlemail.com to gmail.com, drop the +tag, drop dots on Gmail only) and grant free credits once per key. A returning inbox can still have an account; it just does not get a second grant.
3. Credits after confirmation, not after signup
If credits arrive before the email is confirmed, a domain with no mail server is as good as a real one. Holding the grant until the confirmation click also catches typos and dead domains for free.
// On signup: give credits only to an inbox you have not seen before
// and only after the email is confirmed.
import { canonicalEmail } from 'better-auth-vetto'; // or your own aliasKey()
export async function onSignup(user) {
const key = canonicalEmail(user.email); // jane.doe+3@gmail.com -> janedoe@gmail.com
const seen = await db.creditGrants.findOne({ email_key: key });
await db.users.update(user.id, {
email_key: key,
credits: 0, // nothing until the email is confirmed
pending_credits: seen ? 0 : FREE_CREDITS, // repeat inbox: no second grant
});
}
export async function onEmailConfirmed(user) {
if (!user.pending_credits) return;
await db.creditGrants.insert({ email_key: user.email_key, at: new Date() });
await db.users.update(user.id, { credits: user.pending_credits, pending_credits: 0 });
}4. Limit signups per IP and flag datacenter networks
Scripts sign up from cloud servers in bursts. Cap signups per IP per hour (leave room for offices and universities) and flag signups from datacenter networks. Flag, do not block: some real people use VPNs. A flagged signup can still get an account, with credits after a second step.
5. Scale the grant with trust
A small grant for a confirmed email, more after a card or phone number, and a hard daily cap per network. This keeps the first experience free and fast while making each extra fake account worth very little.
Where Vetto fits
Vetto does checks 1, 2 and 4 in your signup form with one script tag: it blocks throwaway and dead domains, suggests a fix for typos like gmial.com, recognizes a returning inbox (stored as a salted hash, never the plain email), and flags datacenter networks and signup bursts. Free on 1 site with 1,000 checks a month, with the repeat and network signals in shadow mode so you can see your numbers first. Pro ($12/mo) turns them on and adds a server-side API. It does not do device fingerprinting or payment fraud, and if it does not answer within 800 ms your form submits as if it were not installed.
On Better Auth there is an open-source plugin, better-auth-vetto, that exports the canonicalEmail() used above. Guides for Clerk, Supabase, Firebase and Next.js show the same checks on other stacks.
Frequently asked questions
How do people abuse free credits in AI apps?
Mostly by creating many accounts: throwaway inboxes from temp-mail sites, Gmail dot and +tag variants of one address, and scripts that sign up from cloud servers. Each new account collects the signup credits again, and every credit is compute you pay for.
Should I require a credit card to get free credits?
A card stops most abuse but also most curious visitors. A common middle ground: a small grant after email confirmation for everyone, and a larger grant or trial after a card. Cheap email checks remove most of the abuse before you need the card wall.
Is blocking disposable emails enough?
It removes the laziest abuse, which is usually the most common. Pair it with one grant per normalized inbox (so Gmail aliases do not count as new people), credits only after confirmation, and a per-IP limit. That combination closes the cheap loops; device fingerprinting is for when abuse is organized.
Will this block real users?
It should not, if you keep privacy relays like Apple Hide My Email and Firefox Relay allowed: they forward to a real inbox. Warn on repeat inboxes instead of blocking them outright, because teams and forgotten accounts are common.
Give your signup form sharp eyes.
Free on one site. One line of HTML. Remove it any time and your form works exactly as before.
Founding offer: Pro for life for $69 once, first 100 buyers, until Nov 27.