All articles Bot detection

When AI Agents Sign Up: Handling Agent-Created Accounts in SaaS

For years, the question on a signup form was “human or bot?” That question is getting less useful. A growing share of web traffic comes from AI agents acting on behalf of a person: an assistant told to “sign me up for a trial of three note-taking apps and compare them” will fill in your form, click the confirmation link and start poking around. It is automation, and it is also a real prospect.

Treating that traffic like a credential-stuffing botnet loses you customers. Treating it like a human loses you control over who and what holds accounts on your platform. This post is a policy guide for the middle ground.

Three kinds of automated signup

It helps to separate automated signups by what is behind them:

  1. Declared assistants. The agent identifies itself. A person asked it to do something, and the agent is doing it in the open.
  2. Undeclared automation driving a real browser. Headless Chrome, Playwright or an agentic browser that does not announce itself. It might be a person’s agent, a QA script, or a farm.
  3. Classic bots. Scripts posting directly to your endpoint, form-fillers and account-creation tooling built for abuse.

Only the first group is easy to treat kindly, because it is the only one that tells you what it is.

What the signals tell you

Prynt reports these as separate Smart Signals rather than folding them into one “bot” bit:

  • aiAgent recognizes AI assistants and crawlers that identify themselves. The signal includes the agent name and a category: assistant for user-directed actions, crawler for training and indexing bots. When it fires, the decision carries the AI_AGENT reason code.
  • bot covers automation frameworks and headless environments, with the BOT reason code.
  • tlsFingerprint compares the JA4 TLS fingerprint with the claimed browser; a mismatch adds TLS_AUTOMATION. It needs the JA4 value, so it appears when traffic passes through an edge connector or proxy that forwards it.
  • behavioral looks at how the form was filled; scripted input produces AUTOMATION_BEHAVIOR.

On your server the event for the signup’s requestId gives you all of them at once:

import { PryntServer } from '@prynt/node';
const prynt = new PryntServer({ secretKey: process.env.PRYNT_SECRET_KEY });

const ev = await prynt.getEvent(requestId);
const agent = ev.smartSignals?.aiAgent;          // { result, agent, category }
const isBot = ev.smartSignals?.bot?.result === true;
const others = ev.accountsOnDevice?.count ?? 0;

The aiAgent signal is part of the Smart Signals included from the Pro plan. Bot detection is available on every plan.

Separate “who filled the form” from “how many accounts”

The most common policy mistake is letting the agent question swallow the abuse question. They are independent:

  • A person using an assistant to create one account on one device is a normal signup with an unusual input method.
  • A farm creating hundreds of accounts may never touch an AI agent; it uses scripts, proxies and humans.
  • An agent creating account after account from the same environment is multi-accounting, and the device count shows it.

So evaluate accountsOnDevice and the overall decision first, exactly as you would for any signup, and treat the agent signal as an input that changes the response, not as the response itself. Our bot signup guide covers the device-limit half in detail.

A decision table

Here is a starting policy for a typical SaaS product with a free trial:

SituationAction
decision is block, or device over your account limitRefuse, regardless of agent
Declared assistant (aiAgent.category is assistant), clean deviceAllow, tag the account as agent-created
Declared crawler (category is crawler) submitting a signupRefuse: crawlers have no reason to create accounts
Undeclared automation (BOT, TLS_AUTOMATION, AUTOMATION_BEHAVIOR)Challenge or require email and phone verification
Agent-created account later used heavilyRoute to a plan with agent-appropriate limits

In code, the core of it is short:

function signupAction(ev) {
  const agent = ev.smartSignals?.aiAgent;
  if (ev.decision === 'block' || (ev.accountsOnDevice?.count ?? 0) >= 2) return 'block';
  if (agent?.result && agent.category === 'crawler') return 'block';
  if (agent?.result && agent.category === 'assistant') return 'allow_tagged';
  if (ev.smartSignals?.bot?.result) return 'verify';
  return ev.decision === 'challenge' ? 'verify' : 'allow';
}

Store the tag with the account. Knowing that an account was created by an agent is useful later, for support, for analytics and for deciding what that account can do.

Why a separate plan beats a block

Agent-created accounts behave differently once they exist. An agent may hit your API or UI far faster than a person, fan out across features in minutes, or run long sessions unattended. If your free tier was sized for human usage, an agent can consume it in an afternoon without any bad intent.

Rather than banning agents, many teams are moving toward explicit agent paths:

  • a plan or account flag with rate limits sized for automated use;
  • an API key flow, so the agent uses the interface designed for programs rather than scraping the UI;
  • terms of service that state what agents may do on behalf of a user.

That turns an enforcement problem into a product decision. The AI agent detection page describes the signals in more depth, and our post on managing agentic checkout traffic covers the same question at the payment step.

Challenges that make sense for agents

If you challenge, pick a step an honest agent can pass with its user’s help and a farm cannot scale:

  • Email verification is cheap for both, so it only confirms deliverability.
  • Phone verification puts a real cost on each account.
  • Prynt’s proof-of-work challenge (challenge() in the browser, validated server-side with the single-use passToken) adds computational cost per attempt without asking anyone to click on traffic lights. An agent running in a browser can complete it; a farm pays for it on every account.
  • MFA on first login keeps the account usable for a real user and expensive for anyone holding hundreds.

Watch it before you enforce it

Agent traffic patterns are changing quickly, so run the policy in monitor mode first. Log the decision you would have taken and the AI_AGENT, BOT and TLS_AUTOMATION codes for every signup, then review a week of data. You will probably find fewer declared agents than the headlines suggest, a handful of QA scripts from your own team, and a clearer view of where real abuse comes from. Our guide to detecting ChatGPT agent and similar assistants shows what those requests look like in practice.

Agents are becoming another kind of user agent. Give them a lane, keep your device limits in place, and decide the rest from your own data.

Try it free

Prynt is device intelligence with a free tier — visitor IDs, bot & fraud Smart Signals, and behavioral biometrics, powered by a cross-site network. Start free.

Keep reading