A normal server event is just a name. Anyone can call
TriggerServerEvent("payroll:givePaycheck", 999999) from a cheat menu with any
arguments they like, and your server cannot tell it apart from a real player
clicking a button.
A Safe Event can only be triggered by a real, Asphyxia-protected client. This page covers what the protection guarantees and how to register, handle and trigger one.
What it guarantees
- Your real event is never networked, so clients cannot reach it with
TriggerServerEvent. The client only learns a key you choose. - Triggering goes through an Asphyxia export, and each trigger is tied to the player’s live heartbeat session. No session, no trigger.
Anything that fails on the way — no session, a forged payload, an unregistered event, or a trigger during cooldown — results in a ban, logged like any other detection.
Setup
1. Register the event (server)
Call this at the top level of a server script, not inside a thread, callback or event handler.
exports.asphyxia:registerProtectedEvent("givePaycheck", {
eventName = "payroll:givePaycheck",
cooldown = 60 * 1000, -- optional, per player, in ms
})| Parameter | Type | Description |
|---|---|---|
eventKey |
string |
The key your client script uses to trigger it |
config.eventName |
string |
Your real event name. Never sent to the client |
config.cooldown |
number? |
Minimum ms between triggers, per player. Omit for none |
2. Handle it (server)
Use AddEventHandler, never RegisterNetEvent. The first argument is the
verified net ID of the player who triggered it.
AddEventHandler("payroll:givePaycheck", function(source, amount)
exports.your_framework:AddMoney(source, "bank", amount)
end)3. Trigger it (client)
local events = exports.asphyxia:getEvents()
RegisterCommand("claimpay", function()
exports.asphyxia:triggerSafeEvent(events.givePaycheck, 500)
end)getEvents() returns your resource’s registered keys, so you do not hardcode
strings. It returns nil if the resource registered nothing.
triggerSafeEvent(eventKey, ...) takes any number of arguments — strings,
numbers, booleans, tables — and otherwise behaves like TriggerServerEvent.
Notes
- Both client exports can be called as soon as your script starts. They wait for the anti-cheat session themselves.
- Cooldowns are enforced per player on the server. Looping
triggerSafeEventgets the player banned. - To exempt a player from false positives, see
Whitelisting (
safeEventsIntegrity).