Loading
Loading
The Cheater Database API is the programmatic version of the Query User page. It searches the cheater database by Discord ID and returns the community profile, the external network lookup, and every Ocean scan the account has been seen in.
Only accounts with database access can create an API key carrying the db:query permission. DB Access comes from an active DB Access plan, from a staff role, or from an owner granting it on your profile. The permission is greyed out in the API Keys tab until you have it.
Access is re-checked on every single request, not only when the key is created. If the DB Access plan expires the key keeps working for its other permissions but this endpoint starts answering 403.
Base URL: https://api.anticheat.ac/v1
Authentication: API Key required with db:query permission
Requires: Active license or enterprise membership, plus database access
Returns everything the database holds for a Discord ID across three independent sources. Any of them can come back null when there is nothing on record.
/v1/db/query/:discordId| Name | Type | Description |
|---|---|---|
| discordId | string | The Discord user ID to search. Must be 5 to 25 digits |
| Header | Required | Description |
|---|---|---|
| x-api-key | Yes | Your API key |
| x-server-name | No | A label for the server making the call. Recorded in the usage log so you can tell your own integrations apart. See Usage logging |
{
"discordId": "123456789012345678",
"botConfigured": true,
"botProfile": {
"username": "PlayerUsername",
"displayName": "Player",
"avatarUrl": "https://cdn.discordapp.com/avatars/...",
"firstSeen": "2024-03-02T18:41:00.000Z",
"lastSeen": "2026-08-11T22:05:00.000Z",
"perGameCounts": { "fivem": 12, "rust": 3 },
"totals": { "servers": 15, "roleChanges": 41, "messages": 208 },
"isConfirmedCheater": true,
"confirmedCheater": {
"reason": "Sold FiveM menus",
"caughtby": "OceanStaff",
"confirmedAt": "2025-11-30T14:02:00.000Z"
},
"roleHistory": [],
"messages": []
},
"networkLookup": {
"found": true,
"playerName": "Player",
"totalPlaytimeSeconds": 482910,
"identifiers": {
"discord": "123456789012345678",
"steam": "11000010aaaaaaa",
"all": ["discord:...", "steam:..."]
},
"servers": [
{
"serverName": "Some Roleplay",
"totalHours": 134,
"firstSeen": "2025-02-11T20:00:00.000Z",
"lastSeen": "2026-07-30T03:12:00.000Z"
}
],
"bans": { "total": 2, "activeCount": 1, "removedCount": 1, "active": [], "removed": [] },
"dangerousDiscords": { "count": 3, "guilds": [] },
"blacklist": { "listed": false }
},
"ocean": {
"scannedUser": {
"discordId": "123456789012345678",
"username": "PlayerUsername",
"overallStatus": "cheating",
"totalScans": 5,
"totalDetections": 3,
"allDetections": ["Generic Cheat Loader - Detection"],
"gamesScanned": ["FiveM"],
"firstSeenAt": "2025-01-10T08:00:00.000Z",
"lastSeenAt": "2026-08-20T15:45:00.000Z",
"relatedAccounts": [],
"scanHistory": []
},
"scanMatches": [
{
"discordIds": ["123456789012345678"],
"usernames": ["PlayerUsername"],
"cheating": "Yes",
"detects": ["Generic Cheat Loader - Detection"],
"suspicious": [],
"warning": [],
"country": "AR",
"scannedAt": "2026-08-20T15:45:00.000Z",
"matchType": "discord"
}
]
}
}| Field | Type | Description |
|---|---|---|
| discordId | string | The Discord ID that was searched |
| botConfigured | boolean | Whether the community database backend is reachable. When false, botProfile is always null |
| botProfile | object | null | Community database profile: servers seen in, role history, message activity, and confirmed-cheater status |
| networkLookup | object | null | External network profile: linked identifiers, playtime per server, ban history, and blacklist status |
| ocean.scannedUser | object | null | Ocean scan summary: status, detections, games, related accounts, and scan history |
| ocean.scanMatches | array | Individual scans this account matched, either by Discord ID or by shared HWID |
| Status | Meaning |
|---|---|
| 400 | The Discord ID is missing or is not 5 to 25 digits |
| 401 | The API key is missing, disabled, or expired |
| 403 | The key lacks the db:query permission, or the account no longer has database access |
| 429 | Rate limit exceeded for this API key |
A Discord ID with nothing on record returns a well-formed response with empty sources rather than a 404. Whitelisted Discord IDs return the same shape, so a whitelisted account is indistinguishable from an account with no records.
{
"discordId": "123456789012345678",
"botConfigured": true,
"botProfile": null,
"networkLookup": null,
"ocean": {
"scannedUser": null,
"scanMatches": []
}
}curl -X GET "https://api.anticheat.ac/v1/db/query/123456789012345678" \ -H "x-api-key: your_api_key_here" \ -H "x-server-name: Ocean RP | EU-1"
const response = await fetch(
'https://api.anticheat.ac/v1/db/query/123456789012345678',
{
headers: {
'x-api-key': 'your_api_key_here',
'x-server-name': 'Ocean RP | EU-1'
}
}
);
const data = await response.json();
if (data.botProfile?.isConfirmedCheater) {
console.log('Confirmed cheater:', data.botProfile.confirmedCheater.reason);
}
if (data.ocean.scannedUser) {
console.log('Ocean status:', data.ocean.scannedUser.overallStatus);
}
console.log('Active network bans:', data.networkLookup?.bans.activeCount ?? 0);import requests
headers = {
'x-api-key': 'your_api_key_here',
'x-server-name': 'Ocean RP | EU-1'
}
data = requests.get(
'https://api.anticheat.ac/v1/db/query/123456789012345678',
headers=headers
).json()
profile = data.get('botProfile')
if profile and profile['isConfirmedCheater']:
print(f"Confirmed cheater: {profile['confirmedCheater']['reason']}")
scanned = data['ocean']['scannedUser']
if scanned:
print(f"Ocean status: {scanned['overallStatus']}")This endpoint is for checking players you are about to let onto your server, not for mirroring the database. Every call is logged with the calling key, the IP, and the optional server name. Enumeration patterns and key sharing are grounds for revoking database access.
If you run several servers off one key, send a distinct x-server-name from each. It is the fastest way to prove which of your servers made a call if usage is ever questioned.