Skip to Content
ReferenceServer Event Contracts

FiveM server event reference

Identify the event’s context before writing the handler. Some events supply a player explicitly; others expose an implicit source. Entity handles and network IDs are different namespaces. A visibility notification is not a connection, and a client-originated game request is not proof of an outcome.

This table combines the generated server catalog with the individual upstream event pages, including bucket changes, drops, respawns and vehicle components. Use the linked sources for complete payload fields; the payload guide explains which documented fields support a decision and which remain opaque.

Arguments and supported cancellation

Server event contracts reviewed 2026-09-22
Event and argumentsCancellationMeaning and constraints
entityCreating
entity: server handle
Yes: delete pending entitySynchronous pre-creation policy hook. A handle is not a player ID or network ID; owner information can still be incomplete. Source
entityCreated
entity: server handle
NotificationPost-creation observation. Server state still needs existence checks before later asynchronous work. Source
entityRemoved
entity: server handle
NotificationRemove cached entries by handle; do not require the entity to remain available for native queries. Source
onResourceListRefresh
none
NotificationThe resource list was refreshed. Rebuild an owned resource-discovery cache, not every gameplay cache. Source
onResourceStarting
resourceName: string
Yes: prevent startupA running policy resource may veto startup. Do not put the veto inside the resource that has not started yet. Source
onResourceStart
resourceName: string
NotificationRuns while startup occurs; filter resourceName before running initialization. Source
onResourceStop
resourceName: string
NotificationRuns while stopping. Clear in-memory ownership and timers synchronously. Source
onServerResourceStart
resourceName: string
NotificationQueued after server-side startup; useful for consumers that discover a newly started provider. Source
onServerResourceStop
resourceName: string
NotificationPost-stop server notification. Do not call exports from a provider that has stopped. Source
playerConnecting
playerName: string, setKickReason: function, deferrals: object
Connection policy / deferralsImplicit source is a temporary player ID, not a fourth argument. Follow the documented tick separation for deferrals. Source
playerJoining
oldID: string
NotificationImplicit source is the final session ID; oldID is the previous temporary ID. Neither is a permanent account identifier. Source
playerDropped
reason: string, resourceName: string, clientDropReason: uint32
NotificationImplicit source identifies the departing session. Capture it immediately and invalidate pending work before ID reuse. Source
playerEnteredScope
data: { for: string, player: string }
Notificationfor is the observer; player is the entering player. Scope visibility is not a login or authorization event. Source
playerLeftScope
data: { for: string, player: string }
NotificationThe player left an observer's scope, not necessarily the server. Avoid expensive work for every visibility pair. Source
onPlayerBucketChange
player: string, bucket: number, oldBucket: number
NotificationPlayer is an explicit first argument here. Do not replace it with implicit source or a FromSource parameter. Source
onEntityBucketChange
entity: server handle, bucket: number, oldBucket: number
NotificationExplicit entity handle and old/new bucket values; moving a player does not automatically move every owned entity. Source
respawnPlayerPedEvent
player: session ID, content: object
Not documentedOneSync respawn notification; content includes posX/posY/posZ. Do not treat it as a native function or confirmed reward entitlement. Source
weaponDamageEvent
sender: player ID, data: object
Yes: reject requested damageA damage request involving a remotely owned entity. willKill is a prediction, hitGlobalId is a network ID, and weaponDamage is relevant when overrideDefaultDamage is set. Source
startProjectileEvent
sender: player ID, data: object
Not documentedInspect named projectileHash/weaponHash and position fields. Do not infer opaque fields or ban on a single client-originated request. Source
ptFxEvent
sender: player ID, data: object
Not documentedParticle effect request with effectHash/assetHash and attachment/position fields. Attached effects and world effects differ. Source
removeAllWeaponsEvent
sender: player ID, data: { pedId: number }
Not documentedpedId is the request's target ID, not an account identity. Correlate to current server state before deciding anything. Source
vehicleComponentControlEvent
sender: player ID, data: object
Not documentedOneSync component-control request. Upstream explicitly leaves request semantics uncertain; do not interpret it as confirmed acceptance. Source
rconCommand
command: string, arguments: string[]
DeprecatedMigrate to RegisterCommand with restricted=true and a narrow ACE grant; do not introduce new password-based RCON handlers. Source

“Notification” is a report of a lifecycle change, not a documented pre-action veto. “Not documented” deliberately avoids promising that cancellation blocks that event. Use secure custom events for your own request validation. Do not make engine event names network-safe with RegisterNetEvent merely to listen to them.

Source is not always an argument

In server.lua, these handlers have intentionally different signatures:

local pendingBySession = {} local bucketViews = {} AddEventHandler('playerDropped', function(reason, resourceName, clientDropReason) local player = source -- Implicit; capture before any future async work. pendingBySession[player] = nil bucketViews[tostring(player)] = nil end) AddEventHandler('onPlayerBucketChange', function(player, bucket, oldBucket) -- Explicit first argument, NOT the implicit source of a network request. bucketViews[tostring(player)] = nil end)

Place these in a server-only resource manifest. They demonstrate invalidation rather than persistence: an old callback must compare its session token with the currently registered session before sending a result. A numeric player ID can be reused. The JavaScript runtime lab includes that check and a regression test for disconnect/reconnect reuse.

For playerJoining, the argument is oldID; implicit source identifies the new active session. A connection deferral operates on the earlier temporary ID and cannot assume that all player natives are available yet. Do not use either ID as a database account key.

Entity lifecycle without a global deny rule

An entity cache should be invalidated when the entity disappears:

local observedModels = {} AddEventHandler('entityCreated', function(entity) if DoesEntityExist(entity) then observedModels[entity] = GetEntityModel(entity) end end) AddEventHandler('entityRemoved', function(entity) observedModels[entity] = nil -- No native query required after removal. end)

This illustrative cache is not an anti-cheat and does not own the entity. In a real resource, track only the entities the feature needs; avoid collecting every model on a busy server. Do not copy an entityCreating rule that cancels everything: it can prevent legitimate server resources from creating entities. Prefer explicit server-side creation policy and appropriate OneSync lockdown, tested with the actual frameworks and game track.

Scope and bucket changes solve different problems

playerEnteredScope and playerLeftScope describe observer/subject visibility. Read data['for'] as the observer and data.player as the subject. One subject can generate many observer changes, so a database lookup, broadcast or full inventory operation per pair scales poorly. State-bag changes are usually a better integration point for replicated feature state; see state bags.

Routing buckets partition game state. The player and entity bucket-change events are separate. A vehicle does not become correctly assigned to an instance merely because its driver moved. Keep bucket membership changes in server-controlled logic and invalidate any cached membership when a change is observed. Do not treat these notifications as an authorization grant.

Veto a resource start from a separate policy resource

For a reversible local test, an already-running server-only resource can reject one deliberately named fixture:

AddEventHandler('onResourceStarting', function(name) if name == 'fd_lab_disabled_fixture' then CancelEvent() end end)

Start the policy resource first, then attempt to start fd_lab_disabled_fixture; it should be denied. Stop the policy resource and retry to restore normal behavior. The blocked resource cannot reliably prevent its own startup by installing a handler after startup has begun. Do not asynchronously query a service and then call CancelEvent after the dispatch has finished.

Sources and verification

Generated server catalog , individual event contracts , OneSync , and event cancellation  underpin the reference. Opaque network fields are not guessed. Confirm engine behavior on the recorded artifact/game build before deploying policy changes.