Quick Start
Get started with Clawptcha in 3 steps:
- Fetch a challenge from the API
- Solve it (factor the product into primes)
- Submit the answer within 5 seconds
That's it! Bots solve this instantly. Humans are too slow.
JavaScript / Node.js
// Clawptcha verification for bots
const API = 'https://verify.clawptcha.com';
async function verifyAsBot() {
// Step 1: Get a challenge
const challenge = await fetch(`${API}/challenge`).then(r => r.json());
console.log(challenge);
// { id: "...", question: "Find the prime factors of 301", product: 301 }
// Step 2: Solve it (factor the product)
const factors = factorize(challenge.product);
const answer = factors.join(','); // e.g., "7,43"
// Step 3: Submit answer (must be < 5 seconds)
const result = await fetch(`${API}/verify`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
challengeId: challenge.id,
answer: answer
})
}).then(r => r.json());
if (result.success) {
console.log('Verified!', result.token);
return result.token;
} else {
console.error('Failed:', result.error);
return null;
}
}
// Simple prime factorization (for products of 2 primes)
function factorize(n) {
for (let i = 2; i <= Math.sqrt(n); i++) {
if (n % i === 0) {
return [i, n / i].sort((a, b) => a - b);
}
}
return [n]; // n is prime
} Python
import requests
import math
API = 'https://verify.clawptcha.com'
def factorize(n):
"""Factor a product of two primes."""
for i in range(2, int(math.sqrt(n)) + 1):
if n % i == 0:
return sorted([i, n // i])
return [n]
def verify_as_bot():
# Step 1: Get challenge
challenge = requests.get(f'{API}/challenge').json()
print(f"Challenge: {challenge['question']}")
# Step 2: Solve it
factors = factorize(challenge['product'])
answer = ','.join(map(str, factors))
# Step 3: Submit (within 5 seconds)
result = requests.post(f'{API}/verify', json={
'challengeId': challenge['id'],
'answer': answer
}).json()
if result.get('success'):
print(f"Verified in {result['solveTimeMs']}ms!")
return result['token']
else:
print(f"Failed: {result.get('error')}")
return None
if __name__ == '__main__':
token = verify_as_bot()
print(f"Token: {token}") cURL / Shell
# Step 1: Get a challenge
CHALLENGE=$(curl -s https://verify.clawptcha.com/challenge)
echo $CHALLENGE
# {"id":"abc123","question":"Find the prime factors of 301","product":301}
# Step 2: Extract the challenge ID
CHALLENGE_ID=$(echo $CHALLENGE | jq -r '.id')
PRODUCT=$(echo $CHALLENGE | jq -r '.product')
# Step 3: Factor the product (your bot computes this)
# For 301: factors are 7 and 43
ANSWER="7,43"
# Step 4: Submit answer
curl -X POST https://verify.clawptcha.com/verify \
-H "Content-Type: application/json" \
-d "{"challengeId":"$CHALLENGE_ID","answer":"$ANSWER"}"
# Response:
# {"success":true,"token":"eyJ...","solveTimeMs":127} Website Widget
For websites, use the embeddable widget with just two lines of code:
<!-- Add the script -->
<script src="https://clawptcha.com/widget.js"></script>
<!-- Add the widget container -->
<div class="clawptcha" data-callback="onBotVerified"></div>
<script>
// Callback when verified
function onBotVerified(token, result) {
console.log('Bot verified!', token);
// Send token to your backend for validation
}
</script> Widget Options
Customize the widget with data attributes:
<div class="clawptcha"
data-theme="dark"
data-callback="myCallback">
</div>
| Attribute | Values | Description |
|---|---|---|
data-theme | light, dark | Widget color theme (auto-detects by default) |
data-callback | function name | Called with (token, result) on success |
Programmatic API:
// Render widget programmatically
const widget = Clawptcha.render('#container', {
theme: 'dark',
callback: (token, result) => console.log(token)
});
// Auto-solve (for bots)
const token = await Clawptcha.solve(widget);
// Reset widget
widget.reset();
// Check verification status
if (widget.isVerified()) {
const token = widget.getToken();
}For Site Owners
Want to protect a route so only bots can access it? Here's the flow:
- Bot gets verified through Clawptcha (gets a token)
- Bot sends the token to your API
- Your server validates the token with Clawptcha
- If valid → grant access. If invalid → reject or redirect.
The API returns a simple yes/no:
{ "success": true }= verified bot{ "success": false }= invalid (human, expired, or fake token)
// Express.js middleware example
async function requireBot(req, res, next) {
const token = req.headers['x-clawptcha-token'];
// No token? Redirect to verification
if (!token) {
return res.status(401).json({
error: 'Bot verification required',
verify: 'https://verify.clawptcha.com/challenge'
});
}
// Validate token with Clawptcha
const check = await fetch(
`https://verify.clawptcha.com/success?token=${token}`
).then(r => r.json());
if (check.success) {
next(); // ✅ Verified bot - allow access
} else {
res.status(403).json({ error: 'Invalid token' });
}
}
// Protect your route
app.get('/api/bot-only-data', requireBot, (req, res) => {
res.json({ secret: 'Only bots can see this!' });
}); Security Best Practices
Server-Side Validation
Always validate tokens on your server using the /success endpoint. Never trust client-side verification alone.
Token Expiry
Tokens expire after 1 hour. Request new verification for long-running sessions.
Rate Limiting
The API rate limits to 10 attempts per IP per 5 minutes. Implement your own limits too.
Time Window
Bots must solve within 5 seconds. This naturally filters out humans.