API
Proof-of-work challenges
Create, solve, and validate site-bound challenges while keeping authorization on your backend.
On this page
Challenge lifecycle
- Your backend keeps the sensitive operation pending when the decision is challenge.
- Create a challenge using the same site, or use a challenge supplied with the decision.
- Solve in the browser and submit the nonce for verification.
- If proof validation succeeds, continue your application’s additional verification or review policy. Do not treat proof validity as a checkout approval.
typescript
const challenge = await bastion.createChallenge();
const proof = await bastion.solveChallenge(challenge);
if (!proof) {
throw new Error('Challenge did not validate');
}
// The protected operation remains subject to your backend policy.HTTP contract
json
{
"challenge_id": "challenge_example",
"prefix": "server_random_prefix",
"difficulty": 4,
"expires_at": "2026-10-14T12:05:00.000Z"
}POST /challenge or /verify/challenge creates the challenge. POST /challenge/verify or /verify/challenge/verify accepts {challenge_id, nonce}. The nonce is a string; the browser solver uses base-36 strings. SHA-256(prefix + nonce) must begin with difficulty zero hexadecimal characters. Difficulty is bounded to 4–6.
Challenges expire after five minutes and are single-use and site-bound. Expired, replayed, or wrong-site proofs fail. Browser solving can be stopped by SDK teardown; provide a clear retry path for interrupted or expired work. Do not run an unbounded challenge loop in a server request handler.