Captcha Generation
The /captcha endpoint generates a CAPTCHA image. It offers two modes: challenge, the default, which keeps the answer server-side so it can be verified later, and image, which returns the answer alongside the picture.
Changed in 6.0.0
challenge is now the default mode: the image comes with a signed token in X-Captcha-Token instead of the answer in clear. Code that read X-Captcha-Text without passing mode will no longer find it — pass ?mode=image to keep the previous behaviour.
Prefer proof of work
A visual captcha no longer stops a determined bot: vision models read them well, often better than people do. For anti-bot protection, prefer /pow, which cannot be shortcut by a model — the only way through is to spend the computation.
curl -X GET \ "https://api.moxon.dev/v6/captcha"Send the request to see the response here.
mode"image" | "challenge"optionalchallenge(default) orimagetextstringoptionalThe captcha text. If omitted, a random string is generated. Rejected in
challengemodelengthnumberoptionalLength of the auto-generated text, 1 to 20. Default:
6widthnumberoptionalImage width in pixels, 100 to 800. Default: 60 × the text length
heightnumberoptionalImage height in pixels, 50 to 400. Default:
120noise"low" | "medium" | "high"optionalNoise level:
low,medium(default) orhighbgstringoptionalBackground color in hexadecimal (e.g.
ffffff)colorstringoptionalText color in hexadecimal (e.g.
000000)
| Mode | Response |
|---|---|
challenge | PNG image, with a signed token in the X-Captcha-Token header — the answer is never sent |
image | PNG image, with the answer in the X-Captcha-Text header |
Both modes return a PNG image (Content-Type: image/png), usable in an <img> tag.
In challenge mode the answer never leaves the server: it exists only inside the token's signature, so intercepting the response does not reveal it. The rendering is also hardened against automated reading — glyphs overlap so they cannot be segmented, ride a sine baseline, mix font families, and are crossed by strokes drawn in the text's own colors, which no filter can subtract. Send the token and the user's answer to /v6/captcha to check it.
Good to know
Both headers are exposed to browser JavaScript through CORS, so a web page can read them from the response.
The auto-generated string avoids ambiguous characters (e.g. 0/O, 1/l).
If parameters are missing or invalid, the API will return an error:
- 400
Mode must be one of: image, challengeThemodevalue is not valid - 400
A custom text cannot be used in challenge modetextwas provided together withmode=challenge - 400
length must be a numberThelengthparameter is not a number - 400
length must be between 1 and 20Thelengthis out of range - 400
width must be a numberThewidthparameter is not a number - 400
width must be between 100 and 800Thewidthis out of range - 400
height must be a numberTheheightparameter is not a number - 400
height must be between 50 and 400Theheightis out of range - 400
Noise must be one of: low, medium, highInvalidnoisevalue - 400
Invalid color (use hex like ff6600)Abgorcolorparameter is malformed
- post/v6/captcha - Verify a challenge answer
- get/v6/pow - Proof of work, the recommended alternative
Last updated on September 13, 2026