Asphyxia exposes a set of server-side exports so your own resources can ban, strike, whitelist and look players up.
Everything here is either read-only or an action Asphyxia would take itself, so calling one can’t leave the anti-cheat in a broken state. Nothing that touches its internals — the heartbeat, integrity checking, licensing, the config loader — is exported, on purpose: getting one of those wrong would quietly disable protection rather than fail loudly.
Moderation
banPlayer(playerId, reason, details?)
Permanently bans a connected player. Returns the new Ban ID, or nil if the
ban didn’t happen (the player is whitelisted, is an admin with
bypassDetections, or isn’t connected).
local banId = exports.asphyxia:banPlayer(source, "Cheating", "Caught by my script")
if banId then
print(("Banned. Ban ID: %s"):format(banId))
end| Parameter | Type | Description |
|---|---|---|
playerId |
number |
Net ID of a connected player |
reason |
string |
Shown on the ban record and the player’s ban card |
details |
string? |
Free-form context stored with the ban |
The ban records which resource requested it, so bans from your scripts are distinguishable from Asphyxia’s own.
unbanPlayer(banId, reason?, unbannedBy?)
Lifts a ban. Returns true if a matching active ban was found.
exports.asphyxia:unbanPlayer("A1B2-C3D4", "Appeal accepted", "AdminName")strikePlayer(playerId, reason, description?, severity?)
Issues a strike. Severity is 1 (low), 2 (medium,
default) or 3 (high).
exports.asphyxia:strikePlayer(source, "Suspicious movement", "Moved 40 units in 1s", 2)Enough strikes of one severity in a session bans the player automatically.
addRisk(playerId, amount)
Raises a player’s risk score, capped at 100.
exports.asphyxia:addRisk(source, 5)createLog(data)
Writes an entry to the audit log, visible on the Logs page.
exports.asphyxia:createLog({
type = "admin_action",
severity = "warning",
playerName = GetPlayerName(source),
identifier = license,
message = "Something worth recording happened",
detail = { anything = "you want" },
})severity is info, warning or critical.
Whitelists
See Whitelisting for when to use these.
whitelistPlayer(playerId, detection?, durationSeconds?)
Exempts a player from a detection. Pass "*" for every detection, and omit the
duration to last until the resource restarts. Returns true, or false plus
an error string.
exports.asphyxia:whitelistPlayer(source, "Godmode", 120)
exports.asphyxia:whitelistPlayer(source, "*")playerId also accepts a license string, so you can exempt someone who isn’t
currently connected.
removeWhitelist(playerId, detection?)
Removes an exemption. Omit the detection to clear all of them.
exports.asphyxia:removeWhitelist(source, "Godmode")isWhitelisted(playerId, detection?)
Whether a player is currently exempt. A live * entry matches everything.
if exports.asphyxia:isWhitelisted(source, "Godmode") then
-- skip whatever would have tripped it
endgetWhitelists()
Every active exemption, as a list.
for _, entry in ipairs(exports.asphyxia:getWhitelists()) do
print(entry.playerName, entry.detection, entry.secondsLeft)
endLookups
isAdmin(playerId)
Whether a connected player is a registered Asphyxia admin.
if exports.asphyxia:isAdmin(source) then
-- let them use your own admin command
endgetAdmin(playerId)
Returns whether they’re an admin, plus their permission set.
local isAdmin, permissions = exports.asphyxia:getAdmin(source)
if isAdmin and permissions.banPlayers then
-- reuse Asphyxia's permissions instead of maintaining your own
endPermission keys are listed on Admin menu.
getPlayer(playerId) / getPlayerFromLicense(license)
The stored record for a player — name, identifiers, risk score, notes, session heartbeat counts.
local player = exports.asphyxia:getPlayer(source)
if player and player.risk_score > 50 then
-- treat them with more suspicion
endisBanned(identifiers) / isGloballyBanned(identifiers)
Whether a set of identifiers matches an active ban on your server, or on the global banlist.
local banned, details, banId = exports.asphyxia:isBanned({ discord = "276497429396979713" })hasSentHeartbeat(playerId)
Whether a player has completed at least one heartbeat this session — a cheap way to know their client is fully protected before trusting it with something sensitive.
if not exports.asphyxia:hasSentHeartbeat(source) then
return -- not protected yet, don't hand them anything
endPanel data
These are the same paginated queries the dashboard and admin menu use. They’re here so you can build your own tooling on the same data.
| Export | Returns |
|---|---|
getPlayersList(page, limit, onlineOnly?, query?, sortKey?, sortDir?) |
A page of players |
getBansList(page, limit, query?, hideUnbanned?, sortKey?, sortDir?) |
A page of bans |
getStrikesList(page, limit, query?, sortKey?, sortDir?, severity?) |
A page of strikes |
getAdminsList(page, limit) |
A page of admins |
getLogsList(page, limit, query?, sortKey?, sortDir?, type?, severity?) |
A page of log entries |
getDashboardStats() |
The aggregate stats behind the dashboard |
addPlayerNote(license, note, addedBy) |
Appends a note to a player |
createAdmin(name, identifiers, permissions) |
Registers a new admin |
resolveStrike(strikeId, resolved, resolvedBy) |
Marks a strike resolved |
Deprecated names
The original short names still work, so nothing breaks, but prefer the verb-and-noun names above in new code.
| Old | Use instead |
|---|---|
ban |
banPlayer |
unban |
unbanPlayer |
strike |
strikePlayer |