Integrations — Vehicle Keys | Quasar Store | Quasar Store
Documentation
Integrations
Frameworks, inventories, targets, text UI, police dispatch, sounds and garages supported by Vehicle Keys, how each is detected, and how to give keys from your own garage.
Vehicle Keys reaches your framework and inventory through small bridge files, picked at start by looking at what is already running. Nothing else in the script names a framework, so the same features work everywhere a bridge exists.
Layer
Supported
Without it
Framework
es_extended · qb-core · qbx_core
Standalone: keys work on ox_inventory only, and there are no owned vehicles — no owner access, recovery, admin list, saved plate swaps or paid copy shop.
Qbox is detected from qbx_core and served by the QBCore bridge, through the qb-core compatibility Qbox provides itself.
ESX
QBCore · Qbox
Standalone
Player id
identifier
citizenid
The player's first identifier
Owned vehicles
owned_vehicles — owner, plate, vehicle, stored; names from users
player_vehicles — citizenid, plate, mods, state; names from players.charinfo
None
Admins
Groups admin, superadmin
Permissions admin, god, or the command ace
The command ace
Copy shop pays from
money, or any account named in Account
cash, or any money type named in Account
Nothing — paid services are refused
Jobs
The ESX job
The QBCore job
Always unemployed — job limits shut everyone out
Usable items
ESX.RegisterUsableItem
QBCore.Functions.CreateUseableItem
ox_inventory's client.export
Scripts written for qb-vehiclekeys and qbx_vehiclekeys keep working through a compatibility layer that is always on — Replacing Other Key Scripts lists every event and export it answers.
Every key, plate and tracker is an item, and a key is only as good as the metadata the inventory keeps on it.
Inventory
Reached through
Extra
ox_inventory
Its own exports, directly
A plate created without a number gets one on creation. Plate swaps move ox's trunks and gloveboxes. Plates, GPS and trackers are used through client.export.
qs-inventory
The framework's item functions
Plate swaps move qs-inventory's trunks and gloveboxes.
qb-inventory · codem-inventory · tgiann-inventory
The framework's item functions
—
ESX's default inventory
—
Not supported: it keeps no item metadata.
On ox_inventory the script registers six client exports for client.export: useKey, useLockpick, useAdvancedLockpick, usePlate, useGps and useTracker. Inventory Items shows which item needs which.
Config.UseTarget = true turns on target options through ox_target or qb-target, whichever is running:
Where
Option
Also needs
Copy shop
Open key copy menu
Config.CopyShop.UseTarget
Nearest car
Run vehicle diagnostic · Measure window tint
Config.Diagnostic.UseTarget
Tracked cars
Remove GPS tracker
Config.Tracker.UseTarget and ox_target — this one does not depend on Config.UseTarget
Without targeting, the copy shop and the recovery clerk show a prompt and open with E, and the diagnostic tablet has /diagnostic. Removing a tracker has no fallback — it needs ox_target.
Config.TextUI picks how prompts — the hotwire hint, the clerk's Press E — are drawn:
Value
Look
ox_lib
ox_lib's text UI at the left of the screen. The default.
qs-textui
Quasar's 3D text. Falls back to native when qs-textui is not running.
native
Plain GTA text floating over the spot.
Notifications go through ox_lib, titled Vehicle Keys. Every message passes through one function in custom/client.lua — change it to use another system:
Another dispatch system? server/custom/dispatch/main.lua is open: add a branch to DispatchVehicleKeys that calls your resource with the title, message and coordinates it receives, and set Config.Dispatch to the name you chose.
The fob beep and the anchor are played through interact-sound, so the files live in that resource, not in this one. Put them in interact-sound's client/html/sounds/ folder, named:
File
Played when
carkeys.ogg
A car is locked or unlocked. The name comes from Config.SoundsFileName.
anchordown.ogg
The anchor is lowered.
anchorup.ogg
The anchor is raised.
Without interact-sound, GTA's own door sounds still play — unless Config.SoundsDisableDefault mutes them.
A car that another script spawns for a player — out of a garage, off a dealership forecourt, from a job depot — needs its key handed over by that script. One call does it, on either side:
lua
-- after spawning the car for this playerlocal plate = GetVehicleNumberPlateText(vehicle)
exports['qs-vehiclekeys']:GiveServerKeys(source, plate, 'sultan', false)
-- a job van returned
exports['qs-vehiclekeys']:RemoveServerKeys(source, plate, 'sultan')
lua
local plate = GetVehicleNumberPlateText(vehicle)
local model = GetDisplayNameFromVehicleModel(GetEntityModel(vehicle))
exports['qs-vehiclekeys']:GiveKeys(plate, model, false)
-- a job van returned
exports['qs-vehiclekeys']:RemoveKeys(plate, model)
The last argument, false, skips the key when the player already holds one for that plate — take the car out every day and the inventory still holds a single key. The client export also lets the player drive straight away, without waiting for the item to land, so nobody is asked to hotwire a car they were just given.
The server remembers each car's last lock state by plate. A garage putting a car back out can restore it:
lua
local state = lib.callback.await('vehiclekeys:server:getVehicleLockStateByPlate', false, plate)
if state then
SetVehicleDoorsLocked(vehicle, state)
end
These parts ship open, so you can change how the script talks to the rest of your server:
Path
Holds
config/main.lua
Every setting.
locales/
Every string, in 41 languages.
custom/esx/ · custom/qb/ · custom/standalone/
The framework bridges: players, jobs, items, admins, owned vehicles and plates.
custom/client.lua
Notifications, text prompts and the F4 interaction menu.
client/custom/
The dispatch blip, the ox_inventory item exports and the target zones.
server/custom/
The dispatch providers.
types.lua
The list of functions a framework bridge fills in.
A server bridge provides these functions. To support a framework of your own, add it to the frameworks table at the top of config/main.lua, pointing at a folder name, then copy the closest bridge into custom/<that name>/ and change the calls inside.
41 translations ship in locales/: Arabic (ar), Bulgarian (bg), Bengali (bn), Catalan (ca), Czech (cs), Danish (da), German (de), Greek (el), English (en), Spanish (es), Estonian (et), Persian (fa), Finnish (fi), French (fr), Hebrew (he), Hindi (hi), Croatian (hr), Hungarian (hu), Indonesian (id), Italian (it), Japanese (ja), Korean (ko), Lithuanian (lt), Latvian (lv), Malay (ms), Dutch (nl), Norwegian (no), Polish (pl), Portuguese (pt), Romanian (ro), Russian (ru), Slovak (sk), Slovenian (sl), Swedish (sv), Swahili (sw), Thai (th), Turkish (tr), Ukrainian (uk), Urdu (ur), Vietnamese (vi) and Chinese (zh).
Set Config.Locale to the code. To add a language, copy en.json to the new code, translate it and set the locale — anything left out falls back to English, and the interface uses the same file.