Vercel BotID and Dregs: Check the Request, Then Score the Account
You turned on BotID.
It's a good choice. One package, a list of routes to protect, a checkBotId() call in
the handler, and the Playwright scripts hammering your signup form start getting a 403. No puzzle,
no checkbox, nothing your customers ever see.
Then the same fellow signs up for his fourth free trial anyway. Real browser, real keyboard, a fresh disposable address each time. BotID let him through because he isn't a bot, and it was right. He's just not a customer either.
That's not a gap in BotID. It answers one question, at one moment, very well: is this request coming from a bot? Whether the account behind it is a duplicate, a fabricated identity, or a freeloader working through your free tier is a different question, and it needs something that remembers accounts over weeks. Dregs is one such judgment layer, and it slots in behind BotID without changing anything you've already set up.
What Is Vercel BotID?
Vercel BotID is an invisible CAPTCHA for applications deployed on Vercel. A client-side challenge
runs in the browser and attaches its solution to requests for the paths you list; your server code
calls checkBotId(), Vercel validates the response, and you get a verdict back before
the handler does any work. Vercel positions it for high-value routes: signups, checkouts, and API
endpoints that bots like to imitate real users on.
It comes in two levels. Basic validates the challenge response and is free on
every plan. Deep Analysis, powered by Kasada, adds a machine learning model over
thousands of client-side signals. As of October 14, 2026, Vercel prices Deep Analysis at $1 per
1,000 checkBotId() Deep Analysis calls on Pro, with custom pricing on Enterprise. Page
views that never call checkBotId() cost nothing.
BotID also knows about good bots. Since botid 1.5.0, the result carries
isVerifiedBot, verifiedBotName, and verifiedBotCategory for
bots in Vercel's verified bot directory, so a route can let a known AI agent through while
refusing everything else. The full setup for Next.js, Nuxt, SvelteKit, and other frameworks is in
Vercel's BotID docs.
Per-Request Bot Checks vs Per-Account Scoring
BotID's verdict belongs to one request on one protected route. It's the right shape for a bouncer: look at whoever is at the door right now, and decide. It doesn't carry a memory of the account that request creates, and it isn't meant to.
Most of the abuse that costs a SaaS money is patient and human-shaped. The freeloader on trial number four. The enterprising operator registering forty "unique" accounts from one device to farm a referral bonus. The specimen whose name was assembled from a word list and whose email domain was created on Tuesday. Each signup request can look perfectly ordinary. The pattern only appears when you connect the account to the device, the identity data, and what happens over the following days.
That's where Dregs works. It scores every identity on four dimensions from the events you send:
- Humanity: whether the device and timing look like a person or like automation.
- Authenticity: whether the identity data (name, email, profile) looks real or fabricated.
- Uniqueness: whether this account shares a device or identity with others.
- Behavior: whether usage looks like a customer's, or like a script running a routine.
Scores update moments after new activity, and each one opens into its observations so you can see exactly why an account was marked down. Custom rules and lists turn those scores into badges and escalations, and webhooks tell your application. Dregs doesn't block anything itself: your app decides whether to refuse, restrict, or review.
| Question | Vercel BotID | Dregs |
|---|---|---|
| Is this request from a bot? | Yes, on each protected route, before your handler runs. | Humanity scores automation from device and timing evidence, across the whole session. |
| Is this a known good bot? | Yes, through Vercel's verified bot directory. | Mark known-good automation as disregarded so it stops affecting analysis. |
| Is this the same person as four other accounts? | Not its job. | Uniqueness links accounts by device and identity data. |
| Is the signup data fabricated? | Not its job. | Authenticity scores names, emails, and profile data. |
| Is the account behaving like a customer? | Not its job. | Behavior scores activity as it accumulates. |
| Who acts on the verdict? | Your route, usually with a 403. | Your app, through the API, badges, escalations, and webhooks. |
How to Use Vercel BotID With Dregs
The two fit together without overlap. BotID keeps clearing scripts at the door, and Dregs watches the accounts that get through. Four steps:
1. Keep BotID on your high-value routes
Leave your initBotId() protect list and your checkBotId() calls as they
are. Signup is the route that matters most here, because it's where the account Dregs will score
gets created.
2. Add the Dregs tracker and identify users
The browser tracker fingerprints the device and records the session on every page, which is what
Uniqueness and Behavior need. Add it to your root layout, then call dregs.identify()
with your own user id once someone signs up or logs in:
<script>
window.dregs = window.dregs || function() {
(window.dregs.q = window.dregs.q || []).push(arguments);
};
dregs('init', { key: 'pk_your_public_key_here' });
</script>
<script src="https://dregs.com/dregs.js" async></script>
dregs.identify(user.id, { email: user.email, name: user.name });
The public pk_ key is safe in the browser. The tracking
manual covers the rest of the browser API.
3. Send the BotID verdict with the signup event
In the signup route, keep the BotID check exactly where it was. When the request passes and you
create the user, send a user.signup event to Dregs with the
TypeScript SDK (npm i @dregs/sdk), and put
BotID's verdict in the event data:
// app/api/signup/route.ts
import { checkBotId } from 'botid/server';
import { Dregs } from '@dregs/sdk';
import { NextRequest, NextResponse } from 'next/server';
const dregs = new Dregs(); // reads DREGS_SECRET_KEY
export async function POST(request: NextRequest) {
const verification = await checkBotId();
// Your call: this lets verified agents through and refuses other bots.
if (verification.isBot && !verification.isVerifiedBot) {
return NextResponse.json({ error: 'Access denied' }, { status: 403 });
}
const { email, name } = await request.json();
const user = await createUser({ email, name }); // your existing signup logic
try {
await dregs.track('user.signup', {
identity: user.id,
eventId: `signup-${user.id}`,
data: {
botidIsBot: verification.isBot,
botidVerifiedBot: verification.isVerifiedBot ?? false,
botidVerifiedBotName: verification.verifiedBotName ?? null,
},
identityData: { email, name },
});
} catch (error) {
console.error('Dregs track failed', error); // never fail a signup over it
}
return NextResponse.json({ id: user.id });
}
A few details matter. The identity is the same id you pass to
dregs.identify() in the browser, which ties this server event to the device the
tracker saw. The eventId makes the event idempotent, so the SDK's automatic retries
can't record the signup twice. And the identityData carries the name and email that
Authenticity scores.
Dregs stores the event data with the event and shows it in the dashboard, so anyone reviewing the
account sees BotID's verdict and the verified agent's name next to Dregs's own observations. The
built-in analyzers don't read a field called botidIsBot. If you want the verdict to
count toward the score, custom analyzers can read your event data; contact
dregs@dregs.com to enable them.
4. Act on the account, not just the request
Scoring is asynchronous: scores land shortly after the events that move them, not inside the
request. Read them at decision points rather than straight after track(): before granting trial credits,
before paying out a referral bonus, before raising a usage limit.
const scores = await dregs.identities.scores(user.id);
if (scores.uniqueness !== null && scores.uniqueness < 40) {
await holdTrialCredits(user.id); // your logic
}
For anything you don't want to poll, use badge rules and a
webhook channel. A "Freeloader" badge on low Uniqueness, with an
apply delay so a passing dip doesn't trigger it, sends IDENTITY_BADGES_CHANGED to your
endpoint, and your app restricts the account. Escalations
put the borderline cases in front of a person instead, which keeps false positives away from real
customers and means less manual review for everyone else.
What Each Layer Catches
Run through the usual suspects and the division of labor is clean:
- Headless signup scripts get refused by BotID at the door. The ones that slip through, or arrive on a route you didn't protect, still score low on Humanity.
- A customer's AI agent can be allowed by BotID's verified bot fields, and the account it opens is scored on what it does from there.
- Repeat free trials from the same device pass BotID, since a person is driving. Uniqueness links the new account to the old ones. See free trial abuse.
- Fabricated identities pass BotID, since the request is real. Authenticity scores the name, email, and profile behind it.
- Slow abuse after signup (spam, scraping from inside an account, promo farming) happens on routes and days BotID never sees. Behavior scores it as it accumulates.
BotID makes the bouncer's job cheap and invisible, which is exactly what it was built for. The blister who walks in politely, signs the guest book with a borrowed name, and comes back every fortnight in a different hat is a matter for the house, and that's the part Dregs keeps track of.
Frequently Asked Questions
Q: What is Vercel BotID?
A: Vercel BotID is an invisible CAPTCHA from Vercel. A client-side challenge runs in the browser and attaches its solution to requests for the routes you list, and your server code calls checkBotId() to get a verdict before it does any work. Visitors never see a puzzle. BotID is meant for high-value routes such as signups, checkouts, and API endpoints.
Q: How much does Vercel BotID cost?
A: As of October 14, 2026, Vercel lists the Basic check as free on all plans. Deep Analysis, the machine learning layer powered by Kasada, costs $1 per 1,000 checkBotId() Deep Analysis calls on the Pro plan and has custom pricing on Enterprise. Page views and requests that don't call checkBotId() are not charged.
Q: Does Vercel BotID stop free trial abuse?
A: Only the automated part of it. BotID decides whether a request to a protected route came from a bot. A person signing up for a fourth free trial from the same laptop, with a fresh disposable address each time, is not a bot, so the check passes. Catching that needs something that remembers accounts and devices over time, which is the job of an account scoring layer such as Dregs.
Q: Should I use Vercel BotID or Dregs?
A: Both, if you're on Vercel. They answer different questions. BotID answers whether this request to this route came from a bot, and your route can refuse it on the spot. Dregs scores every account on Humanity, Authenticity, Uniqueness, and Behavior from the events you send, and keeps updating those scores as the account is used. Dregs then applies badges, opens escalations, and sends webhooks, and your application decides what to do.
Q: Does Vercel BotID block AI agents?
A: Not necessarily. BotID's checkBotId() result includes isVerifiedBot, verifiedBotName, and verifiedBotCategory for bots in Vercel's verified bot directory, so a route can let a known agent through while refusing other bots. Vercel's own example lets ChatGPT Operator through. Whether to allow agents is your product decision, and the account an agent opens can still be scored afterward like any other.
Q: Do I need to host on Vercel to use Dregs?
A: No. Dregs runs anywhere your application does. The browser tracker is a script tag, and the server SDKs cover Python, TypeScript, Java, Ruby, and PHP. BotID's setup assumes a project deployed on Vercel, so the combined setup in this guide is for Vercel apps, but the Dregs half works the same on any host.
Further Reading
Score the accounts behind your BotID-protected routes.
Dregs helps you catch the duplicates, fake signups, and trial abuse that pass a bot check. It scores every account on Humanity, Authenticity, Uniqueness, and Behavior, and each score opens into its observations so you can see exactly why before your app acts.
Start Free Trial