Check a player when they join. Get back a clear, evidence-backed answer and apply your own policy.
CheaterWatch supplies intelligence; your game controls enforcement. On join, your server sends the player’s identifiers and receives whether a verified record exists, the category, and a case reference. What you do with that answer (kick, flag for review, or allow) is entirely your policy.
Partners receive an API key, sent as a bearer token. Keep it on your game server only, never in client code.
Authorization: Bearer cw_live_xxxxxxxxxxxxxxxxQuery parameters: roblox_id (preferred, stable) or discord_id. Usernames can change, so key on IDs.
curl https://api.cheaterwatch.example/v1/players/lookup?roblox_id=123456789 \ -H "Authorization: Bearer cw_live_…"
{
"found": true,
"status": "verified",
"category": "exploiting",
"case_id": "CW-000142",
"reviewed_by_rank": "Warden",
"listed_at": "2026-09-30T12:00:00Z"
}{ "found": false }Only verified records are returned. Pending, rejected and overturned entries are never exposed to the API.
local HttpService = game:GetService("HttpService") local Players = game:GetService("Players") Players.PlayerAdded:Connect(function(player) local ok, res = pcall(function() return HttpService:RequestAsync({ Url = "https://api.cheaterwatch.example/v1/players/lookup?roblox_id=" .. player.UserId, Headers = { Authorization = "Bearer " .. API_KEY }, }) end) if ok and res.Success then local data = HttpService:JSONDecode(res.Body) if data.found then player:Kick("Listed by CheaterWatch: " .. data.case_id) end end end)
The API never tells you what to do. Common approaches: block on any verified record, flag for moderator review, or allow and log. Fail open if the request errors, so an outage never locks legitimate players out.