{"slug": "captcha-proves-you-re-human-hatcha-proves-you-re-not", "title": "Captcha proves you're human. HATCHA proves you're not", "summary": "Monday.com has released HATCHA, an open-source reverse CAPTCHA system that gates access behind challenges trivial for AI agents but difficult for humans, such as large-number multiplication and binary decoding. The system uses server-side verification with HMAC-signed tokens and includes framework adapters for Next.js and Express. This tool aims to help developers distinguish AI agents from human users in web applications.", "body_md": "**CAPTCHA proves you're human. HATCHA proves you're not.**\n\nHATCHA (**H** yperfast **A** gent **T** est for **C** omputational **H** euristic **A** ssessment) is a reverse CAPTCHA that gates access behind challenges trivial for AI agents but painful for humans — large-number multiplication, string reversal, binary decoding, and more.\n\n**Server-side verification**— answers never reach the client. HMAC-signed tokens, stateless, no database required.** 5 built-in challenge types**— math, string reversal, character counting, sorting, binary decode.** Extensible**— register custom challenge generators at runtime.** Themeable**— dark, light, or auto mode via CSS custom properties.** Framework adapters**— Next.js App Router and Express middleware out of the box.\n\n```\nnpm install @mondaycom/hatcha-react @mondaycom/hatcha-server\njs\n// app/api/hatcha/[...hatcha]/route.ts\nimport { createHatchaHandler } from \"@mondaycom/hatcha-server/nextjs\";\n\nconst handler = createHatchaHandler({\n  secret: process.env.HATCHA_SECRET!,\n});\n\nexport const GET = handler;\nexport const POST = handler;\njs\n// app/layout.tsx\nimport { HatchaProvider } from \"@mondaycom/hatcha-react\";\nimport \"@mondaycom/hatcha-react/styles.css\";\n\nexport default function RootLayout({ children }) {\n  return (\n    <html lang=\"en\">\n      <body>\n        <HatchaProvider>{children}</HatchaProvider>\n      </body>\n    </html>\n  );\n}\njs\n\"use client\";\nimport { useHatcha } from \"@mondaycom/hatcha-react\";\n\nfunction AgentModeButton() {\n  const { requestVerification } = useHatcha();\n\n  return (\n    <button\n      onClick={() =>\n        requestVerification((token) => {\n          console.log(\"Agent verified!\", token);\n        })\n      }\n    >\n      Enter Agent Mode\n    </button>\n  );\n}\n# .env.local\nHATCHA_SECRET=your-random-secret-here\nClient                            Server\n  │                                 │\n  │  GET /api/hatcha/challenge      │\n  │────────────────────────────────►│\n  │                                 │  Generate challenge\n  │                                 │  Hash answer\n  │                                 │  HMAC-sign { hash, expiry }\n  │  { challenge (no answer), token }\n  │◄────────────────────────────────│\n  │                                 │\n  │  Agent solves the challenge     │\n  │                                 │\n  │  POST /api/hatcha/verify        │\n  │  { answer, token }              │\n  │────────────────────────────────►│\n  │                                 │  Verify HMAC signature\n  │                                 │  Check expiry\n  │                                 │  Compare answer hash\n  │  { success, verificationToken } │\n  │◄────────────────────────────────│\n```\n\nThe answer **never** reaches the client. The signed token is opaque and contains only a hashed answer + expiry. Verification is stateless — no database needed.\n\n| Type | Icon | What it does | Time limit |\n|---|---|---|---|\n`math` |\n× | 5-digit × 5-digit multiplication | 30 s |\n`string` |\n↔ | Reverse a 60–80 character random string | 30 s |\n`count` |\n# | Count a specific character in ~250 characters | 30 s |\n`sort` |\n⇅ | Sort 15 numbers, return the k-th smallest | 30 s |\n`binary` |\n01 | Decode binary octets to ASCII | 30 s |\n\n``` js\nimport { registerChallenge } from \"@mondaycom/hatcha-server\";\n\nregisterChallenge({\n  type: \"hex\",\n  generate() {\n    const n = Math.floor(Math.random() * 0xffffff);\n    return {\n      display: {\n        type: \"hex\",\n        icon: \"0x\",\n        title: \"Hex Decode\",\n        description: \"Convert this hex number to decimal.\",\n        prompt: `0x${n.toString(16).toUpperCase()}`,\n        timeLimit: 30,\n        answer: String(n),\n      },\n      answer: String(n),\n    };\n  },\n});\n```\n\nHATCHA uses CSS custom properties scoped under `--hatcha-*`\n\n. Override them on any parent element:\n\n```\n[data-hatcha-theme] {\n  --hatcha-accent: #3b82f6;\n  --hatcha-accent-light: #60a5fa;\n  --hatcha-bg: #060b18;\n  --hatcha-fg: #e4eaf6;\n  --hatcha-success: #22c55e;\n  --hatcha-danger: #ef4444;\n}\n```\n\nPass `theme=\"dark\"`\n\n, `theme=\"light\"`\n\n, or `theme=\"auto\"`\n\nto `<HatchaProvider>`\n\nor `<Hatcha>`\n\n.\n\n``` python\nimport express from \"express\";\nimport { hatchaRouter } from \"@mondaycom/hatcha-server/express\";\n\nconst app = express();\napp.use(express.json());\napp.use(\"/api/hatcha\", hatchaRouter({ secret: process.env.HATCHA_SECRET! }));\n\napp.listen(3000);\n```\n\n| Package | Description |\n|---|---|\n`@mondaycom/hatcha-core` |\n\n`@mondaycom/hatcha-react`\n\n`@mondaycom/hatcha-server`\n\n```\ngit clone https://github.com/mondaycom/HATCHA.git\ncd HATCHA\npnpm install\npnpm build\ncd examples/nextjs-app\npnpm dev\n```\n\nContributions are welcome! See [CONTRIBUTING.md](/mondaycom/HATCHA/blob/master/CONTRIBUTING.md) for setup instructions and guidelines.", "url": "https://wpnews.pro/news/captcha-proves-you-re-human-hatcha-proves-you-re-not", "canonical_source": "https://github.com/mondaycom/HATCHA", "published_at": "2026-06-26 12:06:17+00:00", "updated_at": "2026-06-26 12:33:34.466900+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "ai-agents", "ai-infrastructure"], "entities": ["Monday.com", "HATCHA", "Next.js", "Express"], "alternates": {"html": "https://wpnews.pro/news/captcha-proves-you-re-human-hatcha-proves-you-re-not", "markdown": "https://wpnews.pro/news/captcha-proves-you-re-human-hatcha-proves-you-re-not.md", "text": "https://wpnews.pro/news/captcha-proves-you-re-human-hatcha-proves-you-re-not.txt", "jsonld": "https://wpnews.pro/news/captcha-proves-you-re-human-hatcha-proves-you-re-not.jsonld"}}