← All guides

How to handle AI agents signing up to your product

Start from the uncomfortable part. Every fraud signal the industry has built is a proxy for "is a human here", and a capable AI agent genuinely has the things those proxies measure. It drives a real browser, so the fingerprint is real. It arrives on a residential connection, so the address is clean. It controls a real mailbox, so it receives the verification code. It is not defeating your checks; it is satisfying them. So detection is an arms race you lose slowly, and the useful question is a different one.

  1. 1

    Stop asking whether it is a bot

    "Is this automated" has become a bad question, because a growing share of legitimate traffic is somebody's assistant doing what they explicitly asked it to do. Refusing that refuses a customer who is standing right there. The question that still has an answer is: on whose authority is this acting, and can they be held to it?

  2. 2

    Verify the agents that identify themselves

    Web Bot Auth is the emerging standard for this — RFC 9421 HTTP Message Signatures, with an IETF working group chartered in early 2026 and Cloudflare, Google, Amazon and OpenAI behind it. The agent signs its request with a key its operator publishes at a well-known URL, and you check the signature. This is the one check in fraud detection with no false-positive rate, because it is arithmetic rather than judgement. Increasingly agents do sign, because operators want their traffic accepted.

    curl -X POST "https://www.layercall.com/v1/agent/authorize" \
      -H "X-Api-Key: YOUR_KEY" -H "Content-Type: application/json" \
      -d '{
        "method": "POST",
        "url": "https://yoursite.com/signup",
        "headers": { "signature": "…", "signature-input": "…", "signature-agent": "…" }
      }'
  3. 3

    Use trigger, not user agent, to tell them apart

    An operator's Signature Agent Card declares a trigger with exactly two values: fetcher, meaning a person initiated this request, and crawler, meaning nobody did. That distinction is invisible to every classical signal — both are "a bot", and both may be perfectly signed — and it is the whole game. A customer's assistant filling in a signup because they asked it to is a customer. An autonomous crawler POSTing to the same endpoint on nobody's behalf is not, and never was.

    const r = await score({ ip, email, device_id, agent: { method, url, headers } });
    
    // proven is true for exactly one thing: a signature that verified.
    if (r.actor.proven && r.actor.type === "verified_agent") {
      if (r.actor.trigger === "fetcher") return allow();   // a person asked for this
      if (req.method !== "GET")          return reject();  // nobody asked for this
    }
  4. 4

    Separate what you can prove from what you inferred

    A verified signature is proof. Headless detection and automation markers are inference, and inference a capable adversary patches in an afternoon. Keep those apart in your own code, because the moment they are the same field you will start treating a guess like a certainty — and acting automatically on a guess is how you refuse real customers. Branch on a single boolean that means "this was settled cryptographically", not on a vocabulary.

  5. 5

    Catch volume with linkage, not with identity

    Signing does not make an agent harmless. Someone can tell their assistant to open fifty trial accounts and it will honestly declare itself user-initiated every single time, because it is telling the truth. The card cannot see that and does not claim to. What gives it away is the shape: one device across twelve addresses, fifty signups from one /24 inside an hour. Score the pattern, not just the request.

What this gets wrong

Every check here has a cost in real customers. These are the ones that actually bite — several because we shipped them ourselves.

  • Blocking all automation. That reflex gets more expensive every month as more real customers delegate to assistants, and it is invisible in your metrics — refused signups do not file complaints.
  • Treating an unsigned request as malicious. Most traffic is unsigned and most of it is fine. Absence of a signature says nothing; it is a missing claim, not a false one.
  • Trusting a user agent string. It is self-asserted plain text with no verification of any kind, which is precisely why the signature standard exists.
  • Believing a vendor who claims to detect any AI agent. A capable agent driving a real browser on a residential connection is indistinguishable from a person by construction — anyone selling certainty there is selling you an arms race.
  • Assuming a verified fetcher is safe. It means a person asked for this request, not that the person is honest. Pair it with velocity.

Try it before you integrate

Paste any IP, email, phone or domain into the playground — no signup. Or get a free API key for 1,000 lookups a month, no card.