Proof of Work
The /pow endpoint issues a proof-of-work challenge, an anti-bot protection meant to replace the visual captcha. The server hands out a salt and a difficulty; the client looks for a nonce whose sha256 fingerprint starts with that many hexadecimal zeros, then posts it back for verification.
How it works?
At the default difficulty of 4, solving takes about 65,000 hashes on average (16⁴) — under a second in a browser and imperceptible to a person, but ruinous for a bot repeating it thousands of times. Unlike a visual captcha, no vision model can shortcut it: the only way through is to spend the computation.
The expected answer never travels to the client. The token carries the salt and difficulty in clear, but its signature is computed server-side with a secret, so it cannot be forged or read back.
curl -X GET \ "https://api.moxon.dev/v6/pow"Send the request to see the response here.
difficultynumberoptionalLeading hexadecimal zeros required, an integer from 1 to 6. Default:
4
algorithmstringHash algorithm used, always
sha256saltstringRandom salt to prefix the nonce with
difficultynumberNumber of leading hexadecimal zeros the digest must start with
expiresnumberExpiry timestamp of the token, in milliseconds
tokenstringSigned token to send back for verification
instructionsstringHuman-readable description of the work to perform
Solving the challenge is a loop, so it cannot be expressed as a single request. Increment a counter until the digest matches the required prefix:
const { salt, difficulty, token } = await (await fetch('https://api.moxon.dev/v6/pow')).json();
const target = '0'.repeat(difficulty);
let nonce = 0;
while (true) {
const bytes = new TextEncoder().encode(salt + nonce);
const hash = await crypto.subtle.digest('SHA-256', bytes);
const hex = [...new Uint8Array(hash)].map((b) => b.toString(16).padStart(2, '0')).join('');
if (hex.startsWith(target)) break;
nonce++;
}Then send token and nonce to /v6/pow to have the proof checked.
If parameters are missing or invalid, the API will return an error:
- 400
Difficulty must be a numberThedifficultyparameter is not a number - 400
Difficulty must be between 1 and 6Thedifficultyis out of the allowed range
- post/v6/pow - Verify a solved challenge
- get/v6/captcha - Visual captcha, the alternative this replaces
Last updated on October 17, 2026