Tutorial
Hand Off a CAPTCHA API Integration to an AI Coding Assistant
A walkthrough: give Claude Code, Cursor, Copilot or Codex ZeroCaptcha's integration brief and rule files, then check its work against the brief's checklist.
By ZeroCaptcha Engineering5 min readPublished
To have an AI coding assistant integrate ZeroCaptcha, give it one file: the integration brief at /ai/integration.md. It is generated when the site is built, from the API’s own OpenAPI contract and tested reference clients, and holds everything the assistant needs: configuration, every call, polling and callbacks, every error code and what to do about it, the retry rules, reference clients in Node, Python, Go and bash, and a checklist it works through before it says it is done. Save the rule file for your assistant too (Claude Code, Cursor, AGENTS.md or Copilot), put your key in the environment rather than the chat, and then check the result against the same checklist.
This walkthrough takes you from an empty branch to a reviewed integration. The files are listed on the docs page Hand off to AI; nothing below needs anything else.
Step 1: get the files
The site serves six files for assistants, none of which contains a key:
| File | What it is | Where it goes |
|---|---|---|
/ai/integration.md |
The integration brief | Give it to the assistant, or keep it in the repository |
/ai/zerocaptcha.json |
The brief as JSON, for tools | Wherever your tooling reads it |
/ai/claude/SKILL.md |
A Claude Code skill | .claude/skills/zerocaptcha/SKILL.md |
/ai/cursor/zerocaptcha.mdc |
A Cursor rule | .cursor/rules/zerocaptcha.mdc |
/ai/AGENTS.md |
A section for AGENTS.md, read by Codex, Jules, Gemini CLI and other agents |
Paste into your AGENTS.md |
/ai/copilot-instructions.md |
GitHub Copilot instructions | .github/copilot-instructions.md |
The brief starts the assistant; the rule files keep the same rules in front of it whenever it touches your ZeroCaptcha code later. In the dashboard, Hand off to AI on the API keys page downloads the brief with your account’s API address filled in.
Fetching them into a repository, with ZEROCAPTCHA_SITE set to this site’s address:
mkdir -p .claude/skills/zerocaptcha .cursor/rules .githubcurl -fsSL "$ZEROCAPTCHA_SITE/ai/claude/SKILL.md" -o .claude/skills/zerocaptcha/SKILL.mdcurl -fsSL "$ZEROCAPTCHA_SITE/ai/cursor/zerocaptcha.mdc" -o .cursor/rules/zerocaptcha.mdccurl -fsSL "$ZEROCAPTCHA_SITE/ai/AGENTS.md" >> AGENTS.mdcurl -fsSL "$ZEROCAPTCHA_SITE/ai/copilot-instructions.md" >> .github/copilot-instructions.mdThe last two append, so existing instructions in those files are kept.
Step 2: put the key where the code will read it
The brief tells the assistant to read the key from ZEROCAPTCHA_KEY (or your project’s secret
store) and the API’s address from ZEROCAPTCHA_API, and never to write the key into source, logs,
error messages, URLs or anything sent to a browser. Set both in your shell or .env before you
start, and keep .env out of version control. Don’t paste the key into the chat: anyone who has it
can spend your balance. A key with its own daily spend cap limits what a mistake can cost while you develop.
Step 3: prompt
A prompt that names the brief, the page and the key’s variable is enough:
Read https://your-docs-site/ai/integration.md and integrate ZeroCaptcha into this project to solvethe Cloudflare Turnstile widget on https://staging.example.com/login. Read the API key from theZEROCAPTCHA_KEY environment variable. Work through the brief's checklist before you finish.Replace the address with this site’s. If your assistant can’t fetch URLs, attach the file instead.
Say which page and which widget, and whether the site sets an action or cData: the assistant
can’t guess them, and a token with the wrong action may be refused by the site.
Step 4: review against the checklist
The brief ends with a checklist, and it is the fastest review you can do. Each line, shortened from the brief, with what to look for in the diff:
| The brief’s checklist says | Look for |
|---|---|
The base URL is read from ZEROCAPTCHA_API, and no other host is called |
One place that reads the variable |
The API key is read from ZEROCAPTCHA_KEY (or the project’s secret store), never written in source, logs, error messages, URLs or anything sent to a browser |
No key literal; no key in log lines or exceptions |
Every create sends an Idempotency-Key made once per task and reused only when retrying that same create |
The key made outside the retry loop |
| Results are read every 2 seconds, or received by a signed callback, and the wait stops at a deadline | A sleep of 2 seconds and a deadline; no endless loop |
| Both the HTTP status and the body are checked on every reply; a non-JSON reply is an error | Status checked before parsing |
429, 5xx and idempotency_key_in_use are retried after Retry-After, else with exponential backoff from 1 s to 16 s with jitter; nothing else is retried as is |
A retry list, not a blanket retry |
failed and expired tasks are reported with their errorCode and never retried in a loop |
No “try again forever” |
| A Turnstile token is used at once: it works once, for 300 seconds | The token submitted right after it arrives, never cached |
A challenge page’s cf_clearance cookie is sent with solution.userAgent, through the same proxy the task used |
User agent and proxy kept with the cookie |
| Callbacks, if used, are checked with the HMAC-SHA256 signature over the raw body, in constant time, refusing timestamps more than 300 seconds away | Verification before JSON parsing |
| Money is handled as the decimal strings the API sends, never as floats | No float(cost) |
| Tests run against a stand-in for the API, not the real one: every real task is charged | A mock server or recorded replies in the tests |
The idempotency keys guide and createTask and getTaskResult explain the two rules assistants most often get wrong. For signed callbacks, see verify a webhook’s HMAC-SHA256 signature.
Step 5: run it once for real
When the tests pass against the stand-in, run the integration once against the real API on a page you are allowed to automate. That one task is charged if it succeeds, as every task is: ZeroCaptcha has no test mode or test keys. For your own forms’ CI, use Cloudflare’s testing sitekeys instead, which cost nothing: see Cypress and Cloudflare Turnstile.
Brief or MCP server?
The brief is for an assistant writing code. If you want the assistant to call ZeroCaptcha itself while you work, to check a sitekey, read a task or search the docs, connect the ZeroCaptcha MCP server instead. Many setups use both: the rule file for the code, the server for questions. The product itself is on the Cloudflare Turnstile solver page.
Sources
- ZeroCaptcha docs: hand off to AI and the integration brief (checked 1 October 2026).
- ZeroCaptcha docs: errors and retries (checked 1 October 2026).
- AGENTS.md, the open format for agent instructions (checked 1 October 2026).
- GitHub Docs: adding repository custom instructions for GitHub Copilot (checked 1 October 2026).
The team that builds and runs the ZeroCaptcha API. Articles are drafted with AI tools, then checked against the API's code and the primary sources each one cites.