Where the request actually came from
Address reputation, network ownership and routing, resolved in memory on the edge. No lookup in your request path, and no dependency on a feed being awake.
Design partnersPilot programme open — 2026
kavra separates your customers from the automation pretending to be them — and does it without a puzzle, a checkbox or a single thing for a real person to solve.
What it is built to hold
The platform
Automation can imitate any one signal. What it cannot do is make all four agree — because the layers below the browser are chosen by the operating system and the network, not by the script pretending to be a customer.
Address reputation, network ownership and routing, resolved in memory on the edge. No lookup in your request path, and no dependency on a feed being awake.
How a client opens a connection is decided by its operating system and its TLS stack. It is the hardest part of a visitor to fake, and it is settled before a single byte of your page is served.
Device, rendering and environment, collected in a few kilobytes with no framework and no dependency. Treated as a claim, never as proof — which is exactly what it is.
The layer competitors do not have. A client whose easy-to-forge evidence exonerates its hard-to-forge evidence has told us something about itself that no single layer could.
The cost of a puzzle
A challenge is a tax on your funnel. Real customers pay it in seconds and abandoned carts; the people who find it hardest pay the most. The automation it was meant to stop has been buying its way past for years, at a fraction of a cent a solve.
Use cases
Protection is configured per action. A page view can be cheap and permissive while a payment is strict, and both are the same integration and the same signed token.
Disposable accounts are the first step of almost everything that comes after them.
Run from residential proxies, which is what makes rate limiting useless against it.
The automated buying that empties a limited drop before a customer finishes reading it.
Competitors lifting your catalogue continuously, from thousands of addresses.
The abuse that costs trust rather than money, and takes far longer to win back.
Server-side verification for the calls your app makes, with the same token and audit trail.
Why kavra
Bot defence has settled on handing you a number and asking you to trust it. That is fine until a customer complains, a colleague disagrees, or somebody with authority asks why a person was refused.
Every decision records the exact versions of the rules that made it, so it can be re-read as it was — not as today's settings would judge it.
"Low risk" and "we could not see much" are different answers. You get both, and your policy decides what to do about the second.
We return confidence and reasons. Whether that is enough for a payment is a question about your business, and we do not answer it for you.
A device nobody has seen before raises a question, not an accusation. New hardware and minority browsers are customers.
For developers
A few kilobytes in the browser, and one signature check on your server. There is no call to us in your request path, which means there is no outage of ours that can take your checkout down with it.
<!-- One tag, on your own subdomain. --> <script src="https://p-7f3k9m2qw8xz.k-collector.site/v1/bootstrap.js" async></script> <!-- Send the token with the action you want protected. --> const token = await window.kavra.verify({ action: 'checkout' }); await fetch('/api/checkout', { method: 'POST', headers: { 'X-Kavra-Token': token }, body: JSON.stringify(order), });
import { verify } from '@kavra/verify'; // Public keys, fetched once and cached. No call to us in the path. const claims = await verify(req.headers['x-kavra-token'], { jwksUrl: 'https://p-7f3k9m2qw8xz.k-collector.site/.well-known/jwks.json', projectId: process.env.KAVRA_PROJECT_ID, action: 'checkout', }); // Throws on anything wrong: expired, replayed, another project, // another action, another origin. Reaching here is the guarantee. placeOrder(req.body);
use Kavra\Verifier; $claims = (new Verifier( jwksUrl: 'https://p-7f3k9m2qw8xz.k-collector.site/.well-known/jwks.json', projectId: getenv('KAVRA_PROJECT_ID'), ))->verify($request->header('X-Kavra-Token'), action: 'checkout'); // $claims carries confidence and the audit ids — never the // reasoning. What moved a score is not a client's business. Order::place($request->validated());
The alternative
| Image & checkbox CAPTCHA | kavra | |
|---|---|---|
| What the customer does | Solves a puzzle, sometimes twice | Nothing at all |
| Cost to an attacker | A fraction of a cent per solve | Rebuilding a browser they do not control |
| Accessibility | A known barrier for screen readers and low vision | Nothing to see, nothing to operate |
| When it gets one wrong | A number, and no way to ask why | The evidence, kept and replayable |
| If the service is down | Your form is blocked | Your backend verifies offline against public keys |
| Granularity | One setting for the whole site | Per action — a page view and a payment differ |
Questions
If yours is not here, an engineer will answer it directly — not a form that routes to one in a fortnight.
No. Everything is scoped to your project — an identifier from one customer's site means nothing on another's, by construction rather than by policy. No advertising identifiers, nothing sold or shared, and the browser script needs no cookie to work.
They are never shown a wall. Ambiguity produces a quiet additional check rather than a rejection, and the decision to refuse anything is always yours — we return confidence and reasons, your policy decides. When you need to know why, the evaluation is there to open.
A few kilobytes, loaded asynchronously, blocking nothing. Verification finishes while the page is still rendering, and your server's check is a signature verification against a cached public key.
Your backend keeps verifying tokens it already holds, offline, against published keys. New sessions degrade to whatever your policy says they should — you choose whether an unverified visitor is refused or let through, rather than inheriting our opinion of it.
A score compresses everything that happened into one number and throws the rest away. We keep the rest: which checks contributed, how confident each was, how much of the picture was missing, and which versions of which rules produced the answer.
Yes. Every project starts on a subdomain of ours and can move to a hostname of your own with a CNAME, with certificates issued and renewed for you. One origin for your content security policy either way.
We are onboarding a small number of design partners. You bring a real abuse problem; we bring the platform and the attention that comes with being early.