cd /news/ai-tools/captcha-proves-you-re-human-hatcha-p… Β· home β€Ί topics β€Ί ai-tools β€Ί article
[ARTICLE Β· art-40753] src=github.com β†— pub= topic=ai-tools verified=true sentiment=Β· neutral

Captcha proves you're human. HATCHA proves you're not

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.

read3 min views1 publishedJun 26, 2026
Captcha proves you're human. HATCHA proves you're not
Image: source

CAPTCHA proves you're human. HATCHA proves you're not.

HATCHA (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.

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.

npm install @mondaycom/hatcha-react @mondaycom/hatcha-server
js
// app/api/hatcha/[...hatcha]/route.ts
import { createHatchaHandler } from "@mondaycom/hatcha-server/nextjs";

const handler = createHatchaHandler({
  secret: process.env.HATCHA_SECRET!,
});

export const GET = handler;
export const POST = handler;
js
// app/layout.tsx
import { HatchaProvider } from "@mondaycom/hatcha-react";
import "@mondaycom/hatcha-react/styles.css";

export default function RootLayout({ children }) {
  return (
    <html lang="en">
      <body>
        <HatchaProvider>{children}</HatchaProvider>
      </body>
    </html>
  );
}
js
"use client";
import { useHatcha } from "@mondaycom/hatcha-react";

function AgentModeButton() {
  const { requestVerification } = useHatcha();

  return (
    <button
      onClick={() =>
        requestVerification((token) => {
          console.log("Agent verified!", token);
        })
      }
    >
      Enter Agent Mode
    </button>
  );
}
HATCHA_SECRET=your-random-secret-here
Client                            Server
  β”‚                                 β”‚
  β”‚  GET /api/hatcha/challenge      β”‚
  │────────────────────────────────►│
  β”‚                                 β”‚  Generate challenge
  β”‚                                 β”‚  Hash answer
  β”‚                                 β”‚  HMAC-sign { hash, expiry }
  β”‚  { challenge (no answer), token }
  │◄────────────────────────────────│
  β”‚                                 β”‚
  β”‚  Agent solves the challenge     β”‚
  β”‚                                 β”‚
  β”‚  POST /api/hatcha/verify        β”‚
  β”‚  { answer, token }              β”‚
  │────────────────────────────────►│
  β”‚                                 β”‚  Verify HMAC signature
  β”‚                                 β”‚  Check expiry
  β”‚                                 β”‚  Compare answer hash
  β”‚  { success, verificationToken } β”‚
  │◄────────────────────────────────│

The answer never reaches the client. The signed token is opaque and contains only a hashed answer + expiry. Verification is stateless β€” no database needed.

Type Icon What it does Time limit
math
Γ— 5-digit Γ— 5-digit multiplication 30 s
string
↔ Reverse a 60–80 character random string 30 s
count
sort
β‡… Sort 15 numbers, return the k-th smallest 30 s
binary
01 Decode binary octets to ASCII 30 s
import { registerChallenge } from "@mondaycom/hatcha-server";

registerChallenge({
  type: "hex",
  generate() {
    const n = Math.floor(Math.random() * 0xffffff);
    return {
      display: {
        type: "hex",
        icon: "0x",
        title: "Hex Decode",
        description: "Convert this hex number to decimal.",
        prompt: `0x${n.toString(16).toUpperCase()}`,
        timeLimit: 30,
        answer: String(n),
      },
      answer: String(n),
    };
  },
});

HATCHA uses CSS custom properties scoped under --hatcha-*

. Override them on any parent element:

[data-hatcha-theme] {
  --hatcha-accent: #3b82f6;
  --hatcha-accent-light: #60a5fa;
  --hatcha-bg: #060b18;
  --hatcha-fg: #e4eaf6;
  --hatcha-success: #22c55e;
  --hatcha-danger: #ef4444;
}

Pass theme="dark"

, theme="light"

, or theme="auto"

to <HatchaProvider>

or <Hatcha>

.

import express from "express";
import { hatchaRouter } from "@mondaycom/hatcha-server/express";

const app = express();
app.use(express.json());
app.use("/api/hatcha", hatchaRouter({ secret: process.env.HATCHA_SECRET! }));

app.listen(3000);
Package Description
@mondaycom/hatcha-core

@mondaycom/hatcha-react

@mondaycom/hatcha-server

git clone https://github.com/mondaycom/HATCHA.git
cd HATCHA
pnpm install
pnpm build
cd examples/nextjs-app
pnpm dev

Contributions are welcome! See CONTRIBUTING.md for setup instructions and guidelines.

── more in #ai-tools 4 stories Β· sorted by recency
── more on @monday.com 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/captcha-proves-you-r…] indexed:0 read:3min 2026-06-26 Β· β€”