Guide

Bot detection without CAPTCHAs: what actually works

Why the challenge stopped being a defence, which signals replaced it, and what an honest invisible-detection setup looks like in practice.

The challenge stopped working before it stopped being used

A CAPTCHA is a test that assumes solving it is expensive for a machine and cheap for a person. Both halves of that assumption have failed.

Solving is cheap for machines now. Commercial solver services accept a challenge over an API and return the token, priced per thousand, and the operators who care about your site have that line in their budget already. Machine vision handles most image grids without human help at all.

And solving is no longer cheap for people. The grids got harder precisely because the machines got better, so the cost landed on your customers rather than on the attacker. On a checkout, that cost is measurable in abandoned orders.

So the challenge is now a tax on real users that a determined bot pays a fraction of a cent to skip. That is the whole argument for looking elsewhere.

What replaces it: signals, not tests

Invisible detection stops asking the visitor to prove anything and instead reads what the session is already telling you. Three layers carry most of the signal.

Behavioural. How the session interacts with the page — the shape of pointer movement, the timing between events, the way focus moves through a form. Automation produces distributions that differ from human ones, and it differs most where it tries hardest to look human.

Transport. The TLS handshake and HTTP/2 settings describe the client stack. A JA3 or JA3N fingerprint tells you which library made the connection, and a headless browser driving a real TLS stack still announces a combination that a genuine Chrome on Windows does not produce. This is meaningfully harder to fake than a user-agent string, because it means matching a real client's crypto stack rather than editing a header.

Reputation. What this address did before — on your site, and optionally on other people's. An address is not judged only by the session in front of you.

No single layer is sufficient. Behavioural signals are thin on a session that lands and immediately submits; transport fingerprints are shared by everyone using the same library, including legitimate ones; reputation is empty the first time an address appears. The verdict comes from combining them.

The failure modes worth knowing about

Any honest description of invisible detection includes where it goes wrong, because the failures are quieter than a CAPTCHA's and therefore easier to miss.

  • Privacy-hardened real users look automated. Someone on a locked-down browser through a VPN produces thin behavioural signals and an unusual fingerprint. Your allow list exists for this, and it needs to actually be maintained.
  • Shared exit addresses. Corporate NATs, mobile carrier CGNAT and VPN exits put thousands of unrelated people behind one address. Reputation on such an address must be weighted differently, or you block a company because one person on their network ran a scraper.
  • Good bots that look bad. Your payment provider's webhook retry, your uptime monitor, a partner's integration — all automated, all necessary. They belong on the allow list before enforcement goes on, not after someone reports an outage.
  • The first appearance. A brand-new address has no history. This is exactly what a shared blocklist is for, and it is also why a system that only does reputation and no session analysis is weak on day one.
  • Silent drift. A CAPTCHA that breaks is loud. A detector that has quietly started passing a new bot pattern looks identical to a quiet week. Watch the block rate against the traffic, not just the dashboard's uptime.

What a defensible setup looks like

Ordered by how much of the outcome each step decides.

Start in observation mode. Run detection with enforcement off for long enough to see a full weekly cycle, including your quietest night and your busiest promotion. You are looking for verdicts that disagree with things you already know to be true.

Populate the allow list before you enforce, not after. Payment webhooks, monitoring, partner integrations, your own office ranges, the crawlers you want indexing you. This is the step people skip and then discover at 3 a.m.

Enforce at the gateway, not in the page. A decision applied in JavaScript is a decision an attacker can skip. Enforcement belongs where the request is served.

Fail open on the platform, closed on your own rules. If the verdict service is unreachable, traffic should flow — an outage that takes your site down is worse than a bot that gets through. Your own deny list is different: it is your explicit instruction and should survive.

Keep the verdicts explainable. When someone disputes a block, you need to see which signals produced it. A system that only returns a number leaves you unable to answer a customer.

Where Karma sits

Karma is this design as a product: one async snippet, behavioural and transport signals to a collector over TLS, a verdict against your own per-tenant reputation base and — if you opt in — a shared blocklist built from what other tenants saw.

Enforcement happens at your gateway, and decisions cache locally so a collector outage cannot take your site down. Your allow and deny lists always outrank the platform's verdict.

The free Detect plan is observation mode: 25,000 verdicts a month, permanently, with no card and no enforcement. That is the setup described above, and it is the right way to start regardless of what you eventually choose.

FAQ

Can bots be detected without a CAPTCHA?
Yes, and it is now the mainstream approach. Invisible detection reads behavioural signals from the session, transport fingerprints from the TLS handshake and HTTP/2 settings, and the address's reputation, then reaches a verdict without asking the visitor anything. Nothing is displayed, so there is no funnel step to lose real customers at.
Are CAPTCHAs still effective against bots?
Much less than their deployment suggests. Commercial solver services return a token over an API for a fraction of a cent, and machine vision handles most image grids unaided. The challenge has become a cost paid mainly by real users, while the attackers who matter treat it as a small line item.
What is TLS fingerprinting and why does it help?
The TLS handshake exposes an ordered set of cipher suites, extensions and curves that varies by client library — summarised as a JA3 or JA3N hash. It identifies the stack that made the connection, so a script claiming to be Chrome but using a Python TLS library is visible. It is far harder to fake than a user-agent, because it means matching a real client's crypto stack rather than editing a header.
What are the risks of invisible bot detection?
Chiefly false positives on real users who look automated — privacy-hardened browsers, VPN and CGNAT exits — and on good bots such as payment webhooks and monitoring. Both are managed with an allow list populated before enforcement is switched on, and with an observation period long enough to cover a full weekly traffic cycle.