Embed demo

The widget your site will run.

This page loads widget.js, the script you paste, and it works without an account. Pick a site key and read the status the server actually returns.

Live widget

site_key

site_live_imnotahumanpublicdemo

Production key for this site. Only a registered agent signature verifies it. Server verification accepts the token.

Status

  • LOADING
  • PENDING
  • VERIFIED
  • REJECTED
  • EXPIRED
  • ERROR

LOADING. Asking the server for a challenge.

Challenge
Expires in
—
Mode
—
Error
—

1 · Paste

The tag matches the key selected on the left, including data-action="demo". The widget adds input[name=imnotahuman-token] after it verifies.

HTML
<!-- Live key. Verify the token on your server before you change behaviour. -->
<form method="post" action="/your-endpoint">
  <script src="https://imnotahuman.ai/widget.js"
          data-site-key="site_live_imnotahumanpublicdemo"
          data-action="demo"></script>
  <button type="submit">Continue</button>
</form>

Widget reference

2 · Verify on your server

Never trust the widget state alone. consume: true marks the token used so it cannot be replayed. Leave allow_test off for a live key.

tokens/verify
curl -X POST https://imnotahuman.ai/api/v1/tokens/verify \
  -H "content-type: application/json" \
  -d '{"token":"<token from the widget>","site_key":"site_live_imnotahumanpublicdemo","consume":true}'

Server verification

3 · Complete it with an agent

A registered agent signs the challenge. Test keys can also use Simulate agent on the widget, which calls POST /api/v1/challenges/:id/simulate.

terminal
curl -fsSL https://imnotahuman.ai/agent.mjs -o imnotahuman-agent.mjs
node imnotahuman-agent.mjs verify https://imnotahuman.ai/c/ch_00000000000000000000000000

Trying this page works without an account. The terminal command needs a registered agent (register one) and Node 18+. A test key can be finished here with Simulate agent.

Or programmatically

agent.ts
import { AgentIdentity } from "@imnotahuman/agent";

const agent = new AgentIdentity({
  privateKey: process.env.IMNOTAHUMAN_PRIVATE_KEY!,
  agentId: process.env.IMNOTAHUMAN_AGENT_ID,
  keyId: process.env.IMNOTAHUMAN_KEY_ID,
});

await agent.verify(challengeUrl);

Not on npm yet. Source is in packages/; the HTML tag and the REST API work today.

Try to forge it

Your browser can generate a valid Ed25519 signature over this challenge. It still fails, because the key is not registered to any agent. The challenge stays PENDING.

What this proves

A verified result means one thing: this challenge was signed by a recognized agent credential. It does not mean no human was involved, that the agent is well-behaved, or that it should be granted anything. That decision belongs to the website. Security page.