Shield
Server-Side Validation
Every token must be validated from your server with the siteverify endpoint. The response shape is compatible with Cloudflare Turnstile, plus a humanity score.
The Endpoint
POST https://shield.edge.network/siteverify
Content-Type: application/x-www-form-urlencoded
secret=es_secret_...&response=<token>
Both application/x-www-form-urlencoded
and application/json bodies are accepted.
| Parameter | Required | Description |
|---|---|---|
secret | Yes | Your widget's secret key (es_secret_…) |
response | Yes | The token from the edge-shield-response form input |
Responses
Success:
{
"success": true,
"score": 92,
"challenge_ts": "2026-07-21T08:00:00.000Z",
"hostname": "example.com",
"error-codes": []
} Failure:
{
"success": false,
"error-codes": ["timeout-or-duplicate"]
} | Field | Description |
|---|---|
success | Whether the token is genuine, unexpired, unused, and matches your widget |
score | Humanity score, 1–100. Not present on failures. (Shield extension — not in Turnstile) |
challenge_ts | ISO 8601 timestamp of when the token was issued |
hostname | The hostname the widget ran on |
error-codes | Machine-readable failure reasons (see below) |
Error Codes
| Code | Meaning |
|---|---|
missing-input-secret | No secret was supplied |
invalid-input-secret | The secret doesn't match any active widget |
missing-input-response | No token was supplied |
invalid-input-response | The token is malformed, expired, from a different widget, or from a disallowed hostname |
timeout-or-duplicate | The token was already used — tokens are strictly single-use |
Using the Humanity Score
The score expresses confidence: 1 is confirmed automation, 100 is a confirmed human. "Not human" doesn't have to mean "not welcome" — a legitimate AI agent acting for a customer will score low, and you may prefer to route it to your API rather than block it.
const { success, score } = await siteverify(token)
if (!success) reject() // invalid, expired, or replayed token
else if (score >= 70) allow() // confident human
else if (score >= 40) stepUp() // uncertain — e.g. require email confirmation
else routeOrBlock() // automation — block, or redirect to your API The thresholds are yours to tune. As reference points: in managed mode, background attempts scoring below 40 are automatically escalated to an interactive confirmation before a token is issued, so tokens arriving at your server from managed widgets already had a floor applied.
Token lifetime is 5 minutes and each token is valid for exactly one siteverify call. Validate at the moment of form processing, not ahead of time.