Before You Begin#
Before installing Vehicle Keys, make sure your server meets the minimum requirements. Four things are mandatory; everything else is optional and detected on its own.
Requirement | Status | Notes |
|---|---|---|
| Required | Callbacks, menus, progress circles, skill checks and notifications. |
| Required | Owned vehicles, plate changes and GPS trackers. The tracker table installs itself. |
OneSync | Required | Lock states, plate changes and NPC robberies travel as networked entities. Enabled by default on current servers. |
Inventory with metadata | Required |
|
Framework | Optional | ESX, QBCore or Qbox — auto-detected. Standalone runs, but has no owned vehicles: no owner access, key recovery, admin list or paid copy shop. |
Target | Optional |
|
Dispatch | Optional |
|
| Optional | The key-fob beep and the anchor sounds. GTA's own door sounds play without it. |
| Optional | One of three text-prompt styles. ox_lib's is the default. |
Everything framework- or inventory-specific sits behind a small bridge file, and the resource picks the right one by looking at what is already running:
Layer | Detected from | Nothing found |
|---|---|---|
Framework |
|
|
Inventory |
|
|
Run one inventory only: detection does not rank them, so with two started the pick is not guaranteed. Integrations covers each one and what it changes.
github.comReleases · overextended/ox_libA FiveM resource and script library for Lua and JS.github.comReleases · overextended/oxmysqlMySQL resource for FXServer.Downloading Vehicle Keys#
After purchasing Vehicle Keys, the resource is automatically linked to your CFX Portal account.
Sign in to the CFX Portal using the same account used during checkout, open Granted Assets, and download Vehicle Keys.
After extracting the download, you should have the following folder:
qs-vehiclekeys/
├── config/main.lua -- every setting, in one file
├── custom/ -- framework bridges, notifications and text UI (editable)
├── client/custom/ -- dispatch, inventory and target bridges (editable)
├── server/custom/ -- the dispatch bridge (editable)
├── locales/ -- 41 languages
├── sql/database.sql -- optional: the GPS tracker table
├── docs/ -- offline notes: commands, exports and items
└── web/ -- the interface, already builtThe folder must be named
qs-vehiclekeys. The interface loads fromnui://qs-vehiclekeys/web/, the script calls its own exports by that name, and every garage, dealership or job that hands out keys looks forexports['qs-vehiclekeys']. A renamed copy breaks all three.
Installing the Resource#
Move the qs-vehiclekeys folder into your server's resources directory. It can live anywhere inside it, including a category folder:
resources/
└── [qs]/
└── qs-vehiclekeys/Then open your server.cfg and make sure every dependency — and everything it should detect — starts before Vehicle Keys:
ensure oxmysql
ensure ox_lib
# Framework
ensure es_extended
# ensure qb-core
# ensure qbx_core
# Inventory, target, sounds, dispatch
ensure ox_inventory
ensure ox_target
ensure interact-sound
# ensure qs-dispatch
ensure qs-vehiclekeys
# Garages, dealerships and jobs that hand out keys
ensure qs-advancedgaragesThe loading order matters. Detection only sees resources that are already started, so a framework or inventory that starts after Vehicle Keys is not found and the script falls back to standalone. Scripts that call its exports — garages, dealerships, job scripts — go after it.
Adding the Items#
Keys, lockpicks, plates and trackers are inventory items, so they have to exist in your inventory before anything works. The script uses eight, each renameable in config/main.lua:
Item | What it is |
|---|---|
| A key. Unique — it carries the plate and model of its car. |
| The master key, for staff. |
| The standard and advanced lockpicks. |
| A license plate, carrying its plate number. |
| The tool needed to swap plates. Not used up. |
| The GPS tracker that gets fitted to a car. |
| The handheld receiver that finds tracked cars. |
Inventory Items has every definition ready to paste for ox_inventory, qb-inventory and qs-inventory.
The Database#
There is no key table: a key lives in the player's inventory and nowhere else. Vehicle ownership is read from your framework's own table — owned_vehicles on ESX, player_vehicles on QBCore and Qbox — for owner access, key recovery, cleaning keys, plate swaps and the admin panel.
The only table of its own is vehiclekeys_trackers, and it creates itself on start while GPS trackers are enabled. sql/database.sql holds the same statement for anyone who prefers to import it by hand:
CREATE TABLE IF NOT EXISTS `vehiclekeys_trackers` (
`plate` VARCHAR(16) NOT NULL,
`model` VARCHAR(64) NOT NULL,
`installed_by` VARCHAR(80) NOT NULL,
`installed_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`plate`),
KEY `idx_vehiclekeys_trackers_installed_by` (`installed_by`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;One row per plate, so a car carries at most one tracker.
installed_byis the framework identifier of whoever fitted it — that player can always find the car, key or no key.
Admin Access#
The admin panel (/vkadmin), /givekeys and the master key's full access all ask whether a player is an admin. The answer comes from your framework — there is no separate list to maintain:
Players in the admin or superadmin group. Set it with ESX's own command:
setgroup <server id> adminPlayers with the admin or god permission, or with the command ace — the one txAdmin's admins already have. In server.cfg:
add_ace group.admin command allow
add_principal identifier.license:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx group.adminPlayers with the command ace:
add_ace group.admin command allow
add_principal identifier.license:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx group.adminEach framework's rule lives in custom/<framework>/server.lua as playerIsAdmin — edit it there if your staff use another group.
Configuring the Resource#
Every setting lives in one file, config/main.lua, grouped by feature. Usage walks through each block next to the feature it shapes. The values worth reviewing first:
Config.Locale = 'en' -- 41 languages, see locales/
Config.TextUI = 'ox_lib' -- 'ox_lib' · 'qs-textui' · 'native'
Config.OwnerAccessWithoutKey = true -- database owners need no key item
Config.UseTarget = false -- true = ox_target / qb-target
Config.Dispatch = 'default' -- 'default' · 'qs-dispatch' · 'qs-smartphone' · 'origen'
Config.PoliceJobs = { police = true }
Config.KeyMappings = {
UseVehicleKey = 'U', -- lock / unlock
HotwireVehicle = 'H',
StealNpcDriverKey = 'G',
ToggleEngine = 'M'
}
Config.Debug = true -- set false on a live server
Config.Debugships on and prints extra lines to the console — turn it off once the server is live. Keybinds in the config are defaults only: once a player has joined, their own binding in Settings → Key Bindings → FiveM wins. Changes to the file take effect afterrestart qs-vehiclekeys.
Verifying the Installation#
Restart the server and look for the line that names the bridge it loaded — in the server console, and in the F8 console once you join:
VEHICLEKEYS INFO: Framework server loaded: esx
VEHICLEKEYS INFO: Framework client loaded: esxstandalone means it found no framework running — if you do have one, move it above ensure qs-vehiclekeys. Then join your server and work through the first loop:
Sit in a car you do not own
Get into the driver's seat of any parked car. The engine stays off, the pedals do nothing, and a prompt reads Press H to hotwire the vehicle.
Hotwire it
Press
H, wait out the progress circle and pass the skill check. The engine starts and avehiclekeysitem for that plate lands in your inventory.Lock it
Step out and press
U. The fob clicks, the lights flash twice and the doors lock. Press it again to unlock.Open the admin panel
/vkadminlists every owned vehicle on the server. From there, Usage covers everything else.



