toolmix.io logotoolmix.io
/ Developer Tools / Creative CAPTCHA Maker

Creative CAPTCHA Maker

Design distorted CAPTCHA challenges, test expiry and lockouts, then export an embeddable snippet.

1 of 1 AI runs left today — Guest plan
Step 1 — distortion controlsStep 2 — ambiguity filters
Live preview

Layout, distortion and the playground run in your browser at 0 credits. Only the optional AI texture uses an AI credit.

charset size
29
combinations
29^6
current code
Step 3 — playground: expiration, lockouts and feedback
status
idle
time left
attempts left
token
none
toolmix://captcha-playground
0 events

Start a live challenge to simulate expiry, lockouts and instant feedback.

Step 4 — deploy: embed snippet
<!-- toolmix.io Creative CAPTCHA — drop into any page -->
<canvas id="tm-captcha" width="340" height="120"></canvas>
<input id="tm-answer" placeholder="Type the characters" />
<button id="tm-verify">Verify</button>

<script>
const API = "https://toolmix.io/api/public/captcha";
const CFG = {
  "length": 6,
  "jitter": 18,
  "noise": 90,
  "lines": 3,
  "useLower": false,
  "useDigits": true,
  "dropZeroO": true,
  "dropOneI": true,
  "ttl": 90,
  "maxAttempts": 3
};
let token = null;

function pool() {
  let p = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + (CFG.useLower ? "abcdefghijklmnopqrstuvwxyz" : "") + (CFG.useDigits ? "0123456789" : "");
  if (CFG.dropZeroO) p = p.replace(/[O0oQD]/g, "");
  if (CFG.dropOneI) p = p.replace(/[1Il|jL]/g, "");
  return p;
}

function draw(code) {
  const c = document.getElementById("tm-captcha"), x = c.getContext("2d");
  const r = (a, b) => a + Math.random() * (b - a);
  x.fillStyle = "#0b1220"; x.fillRect(0, 0, c.width, c.height);
  for (let i = 0; i < CFG.noise; i++) {
    x.fillStyle = "rgba(94,234,212," + r(0.15, 0.6) + ")";
    x.beginPath(); x.arc(r(0, c.width), r(0, c.height), r(0.5, 1.8), 0, 6.3); x.fill();
  }
  const step = c.width / (code.length + 1);
  code.split("").forEach((ch, i) => {
    x.save();
    x.translate(step * (i + 1), c.height / 2 + r(-8, 8));
    x.rotate(r(-CFG.jitter, CFG.jitter) * Math.PI / 180);
    x.font = r(38, 50) + "px monospace"; x.textAlign = "center"; x.textBaseline = "middle";
    x.fillStyle = "hsl(" + r(150, 200) + ",85%," + r(62, 82) + "%)";
    x.fillText(ch, 0, 0); x.restore();
  });
  for (let i = 0; i < CFG.lines; i++) {
    x.strokeStyle = "rgba(125,211,252,0.5)"; x.lineWidth = r(1, 2.4);
    x.beginPath(); x.moveTo(0, r(0, c.height));
    x.bezierCurveTo(r(0, c.width), r(0, c.height), r(0, c.width), r(0, c.height), c.width, r(0, c.height));
    x.stroke();
  }
}

async function refresh() {
  const p = pool();
  const code = Array.from(crypto.getRandomValues(new Uint32Array(CFG.length)),
    b => p[b % p.length]).join("");
  draw(code);
  const res = await fetch(API + "/issue", {
    method: "POST", headers: { "content-type": "application/json" },
    body: JSON.stringify({ answer: code, ttlSeconds: CFG.ttl, maxAttempts: CFG.maxAttempts })
  }).then(r => r.json());
  token = res.token;
}

document.getElementById("tm-verify").onclick = async () => {
  const answer = document.getElementById("tm-answer").value;
  const out = await fetch(API + "/verify", {
    method: "POST", headers: { "content-type": "application/json" },
    body: JSON.stringify({ token, answer })
  }).then(r => r.json());
  alert(out.message);
  if (!out.ok) refresh();
};

refresh();
</script>
API endpoints
POST https://toolmix.io/api/public/captcha/issue
content-type: application/json

{ "answer": "7KQF2M", "ttlSeconds": 90, "maxAttempts": 3 }
→ 200 { "token": "<uuid>", "expiresAt": "...", "maxAttempts": 3, "ttlSeconds": 90 }

POST https://toolmix.io/api/public/captcha/verify
content-type: application/json

{ "token": "<uuid>", "answer": "7KQF2M" }
→ 200 { "ok": true, "status": "solved", "attemptsLeft": n, "message": "..." }

Notes
• The answer is stored only as a salted one-way hash, keyed to the token id.
• A solved, expired or locked token is consumed immediately — replays always fail.
• Issue tokens from your own server when you want the answer never to reach the browser.

How the Creative CAPTCHA Maker works

Creative CAPTCHA Maker is a free browser tool on toolmix.io: design distorted captcha challenges, test expiry and lockouts, then export an embeddable snippet.

Enter or paste your input on the left and the result updates immediately — no sign-up, no upload queue for the tools that run locally.

Copy or download the output in one click, then jump to any other developer tools utility from the sidebar.

Frequently asked questions

Is Creative CAPTCHA Maker free to use?

Yes. Everyday use is free. A free account also saves your history, while watermark-free exports and higher AI limits come with a paid plan.

Do I need to create an account to use Creative CAPTCHA Maker?

No. You can use it as a guest. Signing in adds saved history, and paid plans add higher AI limits and clean, watermark-free exports.

Is my data kept private?

Text and image tools that can run in your browser do exactly that, so the content never leaves your device. AI tools send your prompt or file to the model provider only to produce the result.

Does Creative CAPTCHA Maker work on mobile?

Yes. The layout adapts to phones and tablets, so you can use it on the go without horizontal scrolling.

Related guides