Analytics of OpenWAF Verify on a zone, the browser challenge page (gate, rate limits, AI Crawl Control, under attack mode) and the widgets. The settings are the challenge block of the zone's edge settings.
| Operation | Endpoint |
|---|---|
| Get Verify analytics | GET /v1/orgs/{org}/zones/{zone}/challenge/analytics |
Get Verify analytics
GET /v1/orgs/{org}/zones/{zone}/challenge/analyticsReturns, for the last days (1–30, default 7), the challenges issued, solved, failed, abandoned and solved with a click (interactive), the solve rate and solve time, failures by cause, siteverify answers, one row per trigger (gate, rate_rule, ai_agents, pipeline, crawler, under_attack) and per widget, and one per day. risk is the zone's risk scoring mode and thresholds and what it decided in the window, always present (zeros without data); in log mode its levels, escalations and blocks are what would have been applied. See Browser challenge analytics.
Required role: readonly or higher.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
org | path | string (uuid) | Yes | Organization id. Every route checks that it is the token's organization (otherwise 404). |
zone | path | string (uuid) | Yes | Zone id (see List zones). |
days | query | integer | No | UTC days ending today. Default 7. From 1 to 30. |
Response
200: Returns ChallengeAnalytics.
| Field | Type | Description |
|---|---|---|
zone | string | |
days | integer | |
from | string (date-time) | |
to | string (date-time) | |
totals | object | |
totals.issued | integer | |
totals.solved | integer | |
totals.failed | integer | |
totals.abandoned | integer | |
totals.interactive | integer | |
totals.solve_rate | number | |
totals.latency_p50_ms | integer | |
totals.latency_p95_ms | integer | |
totals.latency_mean_ms | integer | |
failures | object | |
failures.invalid | integer | |
failures.expired | integer | |
failures.replayed | integer | |
failures.solution | integer | |
failures.elsewhere | integer | |
siteverify | object | |
siteverify.ok | integer | |
siteverify.invalid | integer | |
siteverify.duplicate | integer | |
siteverify.expired | integer | |
siteverify.bad_secret | integer | |
siteverify.remoteip_mismatch | integer | |
siteverify.error | integer | |
by_label | array of object | |
by_label[].source | string | One of interstitial, widget. |
by_label[].widget_id | string | |
by_label[].widget_name | string | |
by_label[].label | string | |
by_label[].issued | integer | |
by_label[].solved | integer | |
by_label[].failed | integer | |
by_label[].solve_rate | number | |
by_label[].latency_p50_ms | integer | |
by_label[].latency_p95_ms | integer | |
by_label[].risk_levels | ChallengeRiskLevels | |
daily | array of object | |
daily[].date | string (date) | |
daily[].issued | integer | |
daily[].solved | integer | |
daily[].failed | integer | |
risk | ChallengeRiskReport | |
settings | ZoneEdgeChallenge |
Errors
| Status | Description |
|---|---|
400 | Malformed request (bad_request). |
404 | Not found, or not visible to the token (not_found). |
503 | Not available right now (unavailable); retry later. |
Example
No SDK method yet: use the HTTP request.
curl "https://dash.openwaf.dev/v1/orgs/$OPENWAF_ORG/zones/6f1d2c3b-8a4e-4b7d-9c21-5e3f7a8b9c0d/challenge/analytics?days=7" \
-H "Authorization: Bearer $OPENWAF_TOKEN"{
"zone": "example.com",
"days": 0,
"from": "2026-10-27T09:30:00Z",
"to": "2026-10-27T09:30:00Z",
"totals": {
"issued": 0,
"solved": 0,
"failed": 0,
"abandoned": 0,
"interactive": 0,
"solve_rate": 0.5,
"latency_p50_ms": 0,
"latency_p95_ms": 0,
"latency_mean_ms": 0
},
"failures": {
"invalid": 0,
"expired": 0,
"replayed": 0,
"solution": 0,
"elsewhere": 0
},
"siteverify": {
"ok": 0,
"invalid": 0,
"duplicate": 0,
"expired": 0,
"bad_secret": 0,
"remoteip_mismatch": 0,
"error": 0
},
"by_label": [
{
"source": "interstitial",
"widget_id": "b37fe5d7-b6b8-4af4-ad93-0e98076dac07",
"widget_name": "example",
"label": "AI training",
"issued": 0,
"solved": 0,
"failed": 0,
"solve_rate": 0.5,
"latency_p50_ms": 0,
"latency_p95_ms": 0,
"risk_levels": {
"pass": 0,
"harder": 0,
"interactive": 0,
"block": 0
}
}
],
"daily": [
{
"date": "2026-10-27",
"issued": 0,
"solved": 0,
"failed": 0
}
],
"risk": {
"mode": "off",
"thresholds": {
"harder": 0,
"interactive": 0,
"block": 0
},
"evaluated": 0,
"levels": {
"pass": 0,
"harder": 0,
"interactive": 0,
"block": 0
},
"scores": [
0
],
"top_signals": [
{
"signal": "example",
"count": 128
}
],
"escalated": 0,
"blocked": 0
},
"settings": {
"pass_ttl_minutes": 720,
"difficulty": 16,
"pass_scope": "host",
"color": "",
"gate": {
"enabled": false,
"paths": [
"/checkout"
],
"pages": [
"example"
]
},
"under_attack": {
"enabled": false,
"until": "2026-10-27T09:30:00Z",
"hosts": [
"www.example.com"
],
"exempt_paths": [
"example"
],
"difficulty": 0,
"pass_ttl_minutes": 0,
"interactive": true
},
"risk": {
"mode": "log",
"thresholds": {
"harder": 30,
"interactive": 60,
"block": 90
}
}
}
}