Production API · OpenAPI 3.0.3
Connection risk you can inspect, explain, and enforce.
BotGuard returns request-scoped bot, automation, proxy, VPN, protocol, and browser-consistency evidence with stable machine-readable detection codes. It exposes both a compact /me verdict and a privacy-oriented v21 fingerprint observation.
Quick start
A GET scores only what the service can observe from the connection and request. A POST adds optional browser telemetry while the server remains the sole scorer.
curl --silent --show-error https://bot.pwn-all.com/me
curl --silent --show-error https://bot.pwn-all.com/me \
--header 'content-type: application/json' \
--data '{"js":{"webdriver":false,"languages":["en-US"]},"locale":{"timezone":"Europe/London"}}'
Selected fields from a verdict:
{
"policy_version": "2026-07-12.1",
"score": 36,
"action": "observe",
"signals": [
{
"code": "network.geo_rtt",
"category": "network",
"message": "RTT below geo floor (proxy/VPN near server)"
}
],
"reasons": ["RTT below geo floor (proxy/VPN near server)"]
}
Do not cache API JSON. Every route listed below carries Cache-Control: no-store, max-age=0. Detection results belong to the current connection, while status, service, and contact data should be revalidated when requested.
Public client routes
The complete field schemas, nullability, and response variants are in the OpenAPI document. Unlisted administrative and compatibility handlers are not part of this public contract.
Choose the contract that matches your integration
/me: compact enforcement verdict
Use this for a direct 1–100 answer, scoring-policy version, structured detections, legacy human-readable reasons, and the underlying server signal object. The initial GET skips delayed HTTP/3 and honeypot-completion checks; the subsequent POST activates them and reports whether valid browser telemetry was merged.
The nominal action bands are clean, observe, challenge, and block. A block safety gate requires corroboration across independent modalities unless a decisive signature is present.
/api/fp/observation: normalized v21 evidence
Use this when you need separate network, browser, protocol, automation, contradiction, and temporal dimensions. Fingerprint groups have domain-separated HMAC identifiers and structured components; risk.signals[] uses the same stable detection object as /me.
The v21 actions are allow, allow_log, challenge, and review_block. They are a different vocabulary from /me; do not map them by string position.
curl --silent --show-error https://bot.pwn-all.com/api/fp/observation \
--header 'content-type: application/json' \
--data '{
"consent":{"security_purpose":true,"analytics_consent":false,"tracking_consent":false},
"platform":"linux",
"timezone":"Europe/London",
"capabilities":"111",
"webdriver":false,
"automation":false
}'
Stable detection metadata
Integrations should branch on action, signals[].code, and signals[].category. English reasons[] remains for backward compatibility, and each signal repeats that text in message, but wording can evolve without changing the underlying detection.
Forward compatibility. Ignore unknown codes or categories unless your policy explicitly handles them. Do not turn a newly introduced signal into a block merely because it is unfamiliar.
Action semantics
* A nominal /me block is downgraded to challenge when the score lacks two independent signal modalities and no decisive signature is present. All actions are advisory; this API does not change access in your application.
Limits and transport behavior
No per-client request-rate quota is published. Poll conservatively and back off on timeouts or server errors.
Fail-open is signal-local
Missing capture means unknown
If passive TCP, TLS/JA4, ASN, geo, DNS, HTTP/3, or browser telemetry is unavailable, rules that depend on it stay dormant. Null, false, empty, or an absent reason does not prove a human client.
Invalid input has route-specific handling
POST /me treats malformed or empty JSON as an absent client observation and returns a server-derived 200 verdict; bodies above 64 KiB return 413 on every transport. POST /api/fp/observation requires valid JSON and returns 400 when parsing fails. Valid partial objects use neutral defaults for omitted fields.
Kill switch is a 200 variant
Fingerprint routes can return {"telemetry_disabled":true}. Branch on that property before reading server_observed, risk, or group hashes.
Other evidence still counts
Fail-open does not force the final action to allow. Available, corroborated signals can still produce an observe, challenge, or block recommendation.
Integration checklist
- Treat each verdict as belonging to the current request path and connection, not as a permanent identity label.
- Branch on the documented action vocabulary and stable signal codes/categories; keep policy version, score, confidence, messages, and protocol for auditability.
- Use a proportional challenge before irreversible action, especially when confidence is low or important captures are absent.
- Honor
no-store on every documented JSON response, especially in shared reverse proxies.
- Keep request payloads below 64 KiB and tolerate new response properties for forward compatibility.
Privacy note. Direct connection responses can include the calling IP address and transport fingerprints. The normalized v21 observation uses a coarse /24 IPv4 or /48 IPv6 prefix plus HMAC-grouped identifiers, but it is still security telemetry and should be handled accordingly.