PYRMI security
OPEN SOURCE · MIT

Bot and tamper detection
for your site. One script tag.

Pyrmi spots bots, scrapers, replayed requests and tampered pages in the browser. Your server asks for a verdict before it trusts a sign-up, a vote, a checkout or a score, and the dashboard shows every flag and why.

// how it works

1

Add the script

Each visit gets a signed session from a real page load. The script watches for automation, scripted input, replaced browser functions, devtools and clock tricks.

2

Check on your server

Before you act on a request, call pyrmi.verify(). You get accept, review or reject, a risk score from 0 to 100, and the reasons.

3

Watch it work

The dashboard shows every verdict, which checks fired, and which users keep getting flagged, so you see how well it's working instead of a yes or no.

in your page
<script src="https://pyrmi.com/sdk/pyrmi.js" data-site="pk_..."></script>
<script>
  const s = await Pyrmi.start();   // on page load
  // when the user signs up, votes, buys...
  await Pyrmi.flush();
  await fetch('/signup', { method: 'POST',
    body: JSON.stringify({ token: s.token, email }) });
</script>
on your server
const { Pyrmi } = require('pyrmi-server');
const pyrmi = new Pyrmi({ secretKey: process.env.PYRMI_SECRET_KEY });

const v = await pyrmi.verify({ token, user: email });
if (v.verdict === 'reject') return res.status(403).end();

// what it catches

Bots and headless browsersWebdriver flags, headless Chrome, Playwright, Puppeteer, Selenium and Cypress markers.
Scrapers and direct API callsA request with no signed session from a real page, or a session that never reported from one, gets flagged.
Replayed requestsEach session token works once and expires. Sending the same request twice fails.
Forged or edited tokensSessions are signed on the server. Change one byte and the verdict is reject.
Tampered pagesReplaced fetch, performance.now, requestAnimationFrame and other built-ins.
DevtoolsAn open devtools panel is noted on the session, so you can weigh it with everything else.
Scripted inputSynthetic events and typing or clicking that's too even or too fast for a human hand.
Impossible valuesActions sent faster than a person could, numbers past your caps, or values that grow too fast.
What it won't doBlock devtools or "stop code running". Whoever owns the browser can switch any of that off. Pyrmi watches and reports, and your server has the final say.

// sandbox: try to get flagged

This box stands in for a form on your site. Each button really does what it says, and the verdict is the one your server would get. Then check the public sandbox dashboard to see it logged.

a protected action

Want more? Open devtools, or paste performance.now = () => 0 into the console, then send it normally again.

// set it up with your ai agent

Building with Claude Code, Cursor or another coding agent? Paste this in and it will wire Pyrmi into your pages and your server.

prompt
Read https://pyrmi.com/install.md and add Pyrmi Security to this site. Find the requests worth protecting (sign-ups, logins, votes, checkouts, scores, any endpoint bots hit), wire in the script tag and pyrmi-server as described, keep my secret key in an environment variable, and tell me which env vars to set.

// open source

MIT licensed

The browser script, the server SDK, the API and the dashboard are all MIT. Read how every check works, fork it, or send a fix.

Host it or self-host it

Use pyrmi.com for free while it's in early access, or deploy your own copy to Vercel with a free Upstash Redis. Point pyrmi-server at your URL.