Reference

API reference

The endpoints below are what the on-server resource talks to. They're also available to your own integrations — keys are managed in the dashboard.

Authentication

Every API request carries a server-scoped key in an x-api-key header. Each key is bound to a single server and can be rotated from the dashboard at any time — rotations take effect immediately; the previous key is revoked.

HTTP requestHTTP
POST /v1/score
Host: api.hoaxeye.net
x-api-key: hx_live_…
content-type: application/json

Don't bake keys into source control. The on-server resource reads the key from config.lua only; if you want it sourced from environment instead, replace the literal in config.lua with a GetConvar read and set the convar in server.cfg.

Endpoints

MethodPathPurpose
POST/v1/scoreScore an incoming join. Input: identifier list. Output: verdict + flags + risk bucket.
GET/v1/players/:identifier/riskRead the latest risk for a player by any of their identifiers.
GET/v1/players/:identifier/historyRecent verdicts and events for the player. Paginated.
GET/v1/server/statusLightweight liveness check. Use for monitoring.

Sample response — POST /v1/score

responseJSON
{
  "verdict": "high_risk",
  "flags": ["datacenter", "behavioral_alt_cluster"],
  "risk_bucket": "high",
  "decision_window_ms": 38
}

Note that the response carries a risk_bucket (low / medium / high) rather than a numeric score. The numeric thresholds are intentionally not exposed publicly — see the Overview for why.

Status codes

Status-code semantics are the same across all endpoints — and they're load-bearing for the on-server resource's behavior:

CodeMeaningResource behavior
200OK — body is the verdict.Apply the configured action for the verdict.
401Key invalid or revoked.Fail-closed: deny the join. A working server should never see this; if it does, rotate the key.
429Rate-limited.Back off. The resource has built-in jitter and retries with a cap.
5xx / timeoutService degraded or unreachable.Fail-open: allow the join, write an offline-mode log entry. The next successful request resumes normal operation.

The fail-closed-on-4xx, fail-open-on-5xx split is deliberate: a 4xx means we know something is wrong with the request (e.g. revoked key); a 5xx means we don't have a verdict, and a verdict-less server shouldn't lock out its players.

Rate limits & quotas

Rate limits are tied to your plan and are intentionally generous for the connect path — we don't want a busy server to be throttled when it matters most. Off-path bulk-history queries have a tighter cap. The dashboard exposes your current usage; if you're consistently approaching the cap, contact us.

Idempotency & retries

POST /v1/score is safe to retry: identical inputs within a short window return identical verdicts (cached). The on-server resource handles this for you; external integrations should retry with exponential backoff and a hard cap.