Backend Verification
Always verify the captcha token server-side. Never trust the client alone.
Flow
- User completes captcha → widget sets hidden input
crovly-token - User submits form → your server receives the token
- Your server →
POST api.crovly.com/verify-token - Crovly returns
success+score - Your server decides: accept or reject
IP Binding
Pass expectedIp in the verify-token request. Crovly checks that the IP that solved the puzzle matches the IP making the request. This prevents token farming — a bot can't solve the captcha on one IP and use the token from another.
// Node.js / Express
app.post("/submit", async (req, res) => {
const token = req.body["crovly-token"];
const ip = req.headers["cf-connecting-ip"]
|| req.headers["x-real-ip"]
|| req.headers["x-forwarded-for"]?.split(",")[0]
|| req.ip;
const result = await fetch("https://api.crovly.com/verify-token", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.CROVLY_SECRET_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ token, expectedIp: ip }),
}).then(r => r.json());
if (!result.success || result.score < 0.5) {
return res.status(403).json({ error: "Captcha failed" });
}
// Process the form...
});Score Thresholds
The score ranges from 0.0 (definitely bot) to 1.0 (definitely human).
| Threshold | Use Case |
|---|---|
| 0.3 | Lenient — allows most traffic, blocks obvious bots |
| 0.5 | Default — good balance for most sites |
| 0.7 | Strict — login forms, payment pages |
| 0.9 | Very strict — high-value actions only |
You can configure the default threshold per site in the dashboard.