Skip to content

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 32,000 hashes — 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.

Parameters ​

ParameterRequiredDescription
difficultyNoLeading hexadecimal zeros required, an integer from 1 to 6. Default: 4

Response Fields ​

FieldTypeDescription
algorithmstringHash algorithm used, always sha256
saltstringRandom 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

Code Examples ​

curl -X GET \
  "https://api.sylvain.sh/v6/pow?difficulty=4"

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:

js
const { salt, difficulty, token } = await (await fetch('https://api.sylvain.sh/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.

Try It ​

Error Handling ​

If parameters are missing or invalid, the API will return an error:

Error MessageDescription
Difficulty must be a numberThe difficulty parameter is not a number
Difficulty must be between 1 and 6The difficulty is out of the allowed range
  • POST /v6/pow - Verify a solved challenge
  • GET /v6/captcha - Visual captcha, the alternative this replaces