FiveM Docs
Addons

esx_license

esx_license stores player licenses such as driving, weapon and boat licenses in ESX Legacy. Server events, client callbacks, permissions and SQL explained.

esx_license keeps track of which licenses each player owns, for example a driving license or a weapon permit. Other resources such as esx_dmvschool, esx_boat, esx_vehicleshop and esx_weaponshop grant and check licenses through it.

Overview

FactValue
Resourceesx_license
SideServer only
Dependenciesesx_lib, es_extended, oxmysql
SQLesx_license.sql (licenses, user_licenses)

Installation

Import the SQL

esx_license.sql
CREATE TABLE `licenses` (
	`type` varchar(60) NOT NULL,
	`label` varchar(60) NOT NULL,
	PRIMARY KEY (`type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

CREATE TABLE `user_licenses` (
	`id` int NOT NULL AUTO_INCREMENT,
	`type` varchar(60) NOT NULL,
	`owner` VARCHAR(60) NOT NULL,
	PRIMARY KEY (`id`),
	UNIQUE KEY `uq_user_licenses_owner_type` (`owner`, `type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

licenses is the catalog of license types. The addons that use a license insert their own rows, for example:

INSERT INTO `licenses` (`type`, `label`) VALUES ('weapon', 'Weapon License');

Start it

server.cfg
ensure esx_license

On start the resource checks user_licenses for duplicate owner + type rows. If it finds any it stops granting licenses and prints Schema migration failed; grants disabled. Remove the duplicates and restart. If the unique key is missing it adds it. The same migration is shipped as sql/security_hardening_2026_10_02.sql in the addons repo; see the addons overview.

Configuration

KeyDefaultDescription
Config.allowedJobs{ ['police'] = true }Jobs that may read and remove other players' licenses.
Config.LicenseCheckDistance5.0 (not in config.lua)Max distance in meters between an allowed-job player and the target. Add the key to config.lua to change it.

Who may read another player's licenses

A client request for another player passes when one of these is true:

  • The caller asks about themselves.
  • The caller's group is admin or superadmin.
  • The caller's job is in Config.allowedJobs, the job's onDuty is not false, and the target is within Config.LicenseCheckDistance.

Server events

Local events for other server scripts. Clients cannot trigger them, except removeLicense.

esx_license:addLicense

TriggerEvent('esx_license:addLicense', playerId, licenseType, cb)
NameTypeDescription
playerIdnumberServer ID of an online player.
licenseTypestringA type from the licenses table.
cbfunction or nilCalled with false if the player already owns it, otherwise with the insert result.
server/main.lua
TriggerEvent('esx_license:addLicense', source, 'weapon', function(result)
    if result then
        TriggerClientEvent('esx:showNotification', source, 'Weapon license issued')
    end
end)

If licenseType is not in the licenses table, the license is not added, a warning is printed and cb is never called.

esx_license:checkLicense

TriggerEvent('esx_license:checkLicense', playerId, licenseType, cb)

cb(hasLicense) receives a boolean. Nothing happens if the player is offline.

server/main.lua
TriggerEvent('esx_license:checkLicense', source, 'drive', function(hasLicense)
    if not hasLicense then
        return TriggerClientEvent('esx:showNotification', source, 'You need a driving license')
    end
    -- continue
end)

esx_license:getLicenses

TriggerEvent('esx_license:getLicenses', playerId, cb)

cb(licenses) receives an array of { type, label } for an online player.

esx_license:getLicense

TriggerEvent('esx_license:getLicense', licenseType, cb)

cb({ type = licenseType, label = label }). label is nil when the type does not exist. This reads the catalog; it does not check a player.

esx_license:getLicensesList

TriggerEvent('esx_license:getLicensesList', function(list)
    for _, license in ipairs(list) do
        print(license.type, license.label)
    end
end)

Returns the cached catalog, loaded on start and refreshed on esx:sqlCatalogReady.

esx_license:removeLicense (net event)

TriggerServerEvent('esx_license:removeLicense', targetId, licenseType)
NameTypeDescription
targetIdnumberServer ID of the player who loses the license.
licenseTypestringLicense type.

Security

This is the only event clients can send. The server checks that the caller's job is in Config.allowedJobs, the license type exists, and the caller may read the target (see the rules above). Otherwise the caller gets "Your job is not allowed to remove the license".

To remove a license from server code, delete the row yourself:

server/main.lua
local xTarget = ESX.Player(targetId)

MySQL.update('DELETE FROM user_licenses WHERE type = ? AND owner = ?', {
    'weapon', xTarget.getIdentifier(),
})

Client callbacks

Call with ESX.TriggerServerCallback, ESX.AwaitServerCallback or xLib.callback.

CallbackArgumentsReturns
esx_license:checkLicensetargetId, licenseTypeboolean
esx_license:getLicensestargetId?array of { type, label } (empty when denied)
esx_license:getLicenselicenseType{ type, label }
esx_license:getLicensesListnonearray of { type, label }

targetId defaults to the caller when omitted. Reading someone else uses the permission rules above.

client/main.lua
ESX.TriggerServerCallback('esx_license:checkLicense', function(hasLicense)
    if hasLicense then
        OpenGunShop()
    else
        ESX.ShowNotification('You need a weapon license')
    end
end, GetPlayerServerId(PlayerId()), 'weapon')

Common issues

  • addLicense does nothing: the type is missing in licenses, or the player is offline. Check the server console for Missing license type in db.
  • Grants disabled after update: duplicate rows in user_licenses. Remove them and restart.
  • Police cannot see licenses: the officer is too far away (5 m), off duty, or the job is not in Config.allowedJobs.

Frequently asked questions

Independent documentation

esx-fivem.com is a community project and is not affiliated with the ESX Framework team. Facts on this page were checked against the upstream source. Official resources: docs.esx-framework.org and github.com/esx-framework.
Edit on GitHub

Last updated on

On this page