Player Commands#
Every player command is a FiveM key mapping, so players can rebind them in GTA's Settings → Key Bindings → FiveM or in the inventory's own Settings → Keys. The starting keys are set in /inventoryconfig → Key binds.
Command | Key | Description |
|---|---|---|
|
| Opens or closes the inventory, with the glovebox, trunk, bag, dumpster or vending machine you are at. |
|
| Shows or hides the quick-slot bar. In wheel mode, holding the same key ( |
|
| Uses quick slot 1–5; |
|
| Reloads the weapon in hand from a matching ammo item. |
|
| Raises or lowers your hands, which lets armed players rob you. Only with Hands up on. |
|
| Throws the weapon in your hand. Only with throwing on. |
|
| Opens the inventory's pause menu. ESC is bound only while Replace the GTA pause menu is on. |
| — | Searches the closest player within 2.5 m who has their hands up or is dead. Police jobs skip the hands-up rule. |
|
| Stop and save, save, or discard a Rockstar Editor clip started from the pause menu. |
Admin and Console Commands#
Admin commands are open to ESX admin / superadmin, QBCore and Qbox god / admin, and the server console. The two panels also accept their own ace — see Claiming Admin Access.
Command | Description |
|---|---|
| Opens the creator. Ace |
| Opens the settings. Ace |
| Gives an item to a player. ID cards and licences are filled with that player's data. For weapons use |
| Gives one weapon with a serial and up to 1,000 rounds. |
| Empties a player's inventory — yours without an id. |
| Opens another player's inventory, wherever they are. |
| Sets the quality (0–100) of the weapon in your hands. Also needs the ace |
| Unlocks a container stuck as in use. Its items are kept. |
| Gives a player XP, levelling them up if it is enough. |
| Testing: ten random items, or a lockpick carrying sample metadata, to yourself. |
| Console only. Posts a test to every Discord webhook and prints which ones answered. |
Client Exports#
For your own client scripts — a HUD that hides while the inventory is open, a job that opens a stash, a minigame that needs an item.
The inventory window
local open = exports['qs-inventory']:inInventory() -- is it open?
exports['qs-inventory']:closeInventory()
-- Block the inventory, the hotbar and the slot keys (a cutscene, handcuffs...)
exports['qs-inventory']:setInventoryDisabled(true)
local blocked = exports['qs-inventory']:CheckIfInventoryBlocked()
-- Give GTA's weapon wheel back while your script needs it
exports['qs-inventory']:WeaponWheel(true)
-- Open the pause menu on its Information page
exports['qs-inventory']:OpenPauseMenu()
-- Fired on every open (true) and close (false)
AddEventHandler('inventory:setFocus', function(focused) end)Items the player carries
-- A name, a list of names, or { name = amount }
local hasKit = exports['qs-inventory']:HasItem('weapon_repairkit')
local hasAll = exports['qs-inventory']:HasItem({ lockpick = 1, screwdriver = 1 })
local items = exports['qs-inventory']:getUserInventory() -- slot -> item
local itemList = exports['qs-inventory']:GetItemList()
-- ox_inventory style: a count, or the slots holding it
local count = exports['qs-inventory']:Search('count', 'water_bottle')
local slots = exports['qs-inventory']:Search('slots', 'water_bottle')
-- Refreshed after every change
AddEventHandler('inventory:client:inventoryCacheUpdated', function() end)The same slot table is mirrored in LocalPlayer.state.inventory.
Opening a stash from the client
-- Opens the stash 'Stash_police_locker' with 50 slots and 100 kg
exports['qs-inventory']:RegisterStash('police_locker', 50, 100000, 'Police locker')
-- Or any id, with the server event
TriggerServerEvent('inventory:server:OpenInventory', 'stash', 'gang_safe', { maxweight = 200000, slots = 60 })
TriggerEvent('inventory:client:SetCurrentStash', 'gang_safe') -- so closing saves itWeights are in grams. Stashes placed in game are better made in the creator, which also handles access by job and gang.
Weapons, blips and look
local weapon = exports['qs-inventory']:GetCurrentWeapon() -- the item in hand: name, info (serie, ammo, quality, attachments)
local name = exports['qs-inventory']:getCurrentWeapon() -- just the name, lowercase
-- Name your blips on the pause-menu map
exports['qs-inventory']:SetBlipName(blip, 'Weed farm')
local colors = exports['qs-inventory']:getColors() -- the player's interface coloursServer Exports#
How another resource drives the inventory — a job reward, a heist, a crafting script, a shop of your own.
Adding and removing items
-- AddItem(source, item, amount, slot, info)
local ok = exports['qs-inventory']:AddItem(source, 'water_bottle', 5)
if ok == true then
-- added
end
-- With metadata: whatever you put in info travels with the item
exports['qs-inventory']:AddItem(source, 'id_card', 1, nil, {
firstname = 'John',
lastname = 'Doe',
})
-- RemoveItem(source, item, amount, slot)
exports['qs-inventory']:RemoveItem(source, 'lockpick', 1)
-- Check before you give
local canCarry = exports['qs-inventory']:CanCarryItem(source, 'goldbar', 10)
local fits, reason = exports['qs-inventory']:CanCarryItems(source, { { name = 'goldbar', amount = 10 } })Compare the result of AddItem with == true: a refusal for weight or a carry limit returns nothing rather than false. Weapons get a serial and full quality on their own, and every item gets a quality of 100 unless you pass one. Every add is recorded in the creator's Stats tab under the name of your resource.
Reading a player's items
local has = exports['qs-inventory']:HasItem(source, 'lockpick') -- or a list, or { name = amount }
local total = exports['qs-inventory']:GetItemTotalAmount(source, 'water_bottle')
local item = exports['qs-inventory']:GetItemByName(source, 'phone') -- first match
local list = exports['qs-inventory']:GetItemsByName(source, 'phone') -- every match
local inSlot = exports['qs-inventory']:GetItemBySlot(source, 3)
local all = exports['qs-inventory']:GetInventory(source) -- slot -> item
local used, weight = exports['qs-inventory']:GetTotalUsedSlots(source)
local maxWeight = exports['qs-inventory']:GetPlayerMaxWeight(source) -- carry skills included
local label = exports['qs-inventory']:GetItemLabel('water_bottle')
local items = exports['qs-inventory']:GetItemList()Changing items and inventories
-- Replace the metadata of the item in a slot
exports['qs-inventory']:SetItemMetadata(source, slot, { quality = 50, label = 'Old phone' })
-- Empty an inventory, keeping some items or whole sections
exports['qs-inventory']:ClearInventory(source, { 'id_card', 'phone' })
exports['qs-inventory']:ClearInventoryKeepSections(source, { 'wallet', 'hotbar' })
-- Change an item definition live, for every player
exports['qs-inventory']:UpdateItem('water_bottle', newDefinition)
local serial = exports['qs-inventory']:CreateSerialNumber()
local plate = exports['qs-inventory']:GeneratePlate()Usable items
exports['qs-inventory']:CreateUsableItem('energy_drink', function(source, item)
-- item.name, item.slot, item.info...
exports['qs-inventory']:RemoveItem(source, 'energy_drink', 1, item.slot)
end)
-- Fired whenever any item is used
AddEventHandler('inventory:usedItem', function(itemName, source, itemData) end)On QBCore it registers through QBCore's own usable items; on ESX the items your other scripts registered with ESX are picked up too. The item must be marked useable.
Opening inventories and shops
-- OpenInventory(name, id, other, source)
exports['qs-inventory']:OpenInventory('stash', 'gang_safe', { maxweight = 200000, slots = 60, label = 'Gang safe' }, source)
exports['qs-inventory']:OpenInventory('otherplayer', targetId, nil, source)
-- A shop of your own, opened as the inventory's Shop page
exports['qs-inventory']:CreateShop({
name = 'mechanic_parts',
label = 'Mechanic Parts',
coords = vector3(-347.0, -133.0, 39.0), -- the player must be within 5 m
account = 'money', -- money, bank, black_money / crypto
restock = 60, -- minutes, for items with stock
items = {
{ name = 'repairkit', price = 250, amount = 1, stock = 20, category = 'Tools' },
{ name = 'tirekit', price = 120 },
},
})
exports['qs-inventory']:OpenShop(source, 'mechanic_parts')OpenInventory is trusted: it skips the distance and robbery checks, so call it only after your own. A shop can also take locations, a license item, categories and groups (the jobs allowed, each with the grade a player must be above); each product can take jobs, license and attachments. Scripts can also trigger inventory:openShop with the shop name from the client.
Stashes, trunks and gloveboxes
local items = exports['qs-inventory']:GetStashItems('gang_safe')
exports['qs-inventory']:AddItemIntoStash('gang_safe', 'goldbar', 5)
exports['qs-inventory']:RemoveItemIntoStash('gang_safe', 'goldbar', 2)
local fits = exports['qs-inventory']:StashCanCarryItem('gang_safe', 'goldbar', 5, 60, 200000)
-- 'stash', 'trunk' or 'glovebox'
local trunk = exports['qs-inventory']:GetOtherInventoryItems('trunk', plate)
exports['qs-inventory']:ClearOtherInventory('glovebox', plate)
-- A plate change keeps the trunk and glovebox
exports['qs-inventory']:UpdateVehiclePlate(oldPlate, newPlate)Stashes opened with RegisterStash are stored as Stash_<id> — use that full id with these exports.
XP, levels and missions
local skill = exports['qs-inventory']:GetSkill(source) -- { level = 4, xp = 120 }
exports['qs-inventory']:AddExperience(source, 250) -- call it from a thread
-- Progress a mission of type From another script (adds, capped at 100)
exports['qs-inventory']:UpdateQuestProgress(source, 'deliver_packages', 20)
AddEventHandler('inventory:updateLevel', function(source, level) end)
AddEventHandler('inventory:questFinished', function(source, questName) end)The creator's mission form shows the exact UpdateQuestProgress line for each scripted mission, ready to copy.
Weapons, creator records and player data
local weapon = exports['qs-inventory']:GetCurrentWeapon(source) -- the weapon item in that player's hands
local shops = exports['qs-inventory']:GetCreatorRecords('shop') -- stash, shop, crafting, seller, item, weapon
local trading = exports['qs-inventory']:IsPlayerTrading(source)
-- A small key/value store per player, kept by the inventory
local data = exports['qs-inventory']:GetMetaData(identifier)
exports['qs-inventory']:SetMetaData(identifier, { armor = 50 })
AddEventHandler('inventory:addAttachment', function(source, item, component, kind, tint) end)
AddEventHandler('weapons:weaponRepaired', function(source, weaponName, label, ammotype) end)Hooks#
A hook runs your function when something happens in the inventory. The one fired today is buyItem, after every successful shop purchase — money taken, item given:
exports['qs-inventory']:registerHook('buyItem', function(payload)
-- payload.source, payload.itemName, payload.amount
-- payload.info / payload.metadata (the item's metadata)
-- payload.externalMeta.shopType (the shop it came from)
end)
-- When your resource stops, remove it yourself
AddEventHandler('onResourceStop', function(res)
if res == GetCurrentResourceName() then
exports['qs-inventory']:unregisterHook('buyItem')
end
end)Each resource has one function per hook; registering again replaces it. The purchase has already happened when the hook runs, so it cannot cancel it — keep it short and error-free.
Item Definitions#
Items made in the creator need no code. For lists kept in shared/items.lua (ESX and Qbox) or qb-core/shared/items.lua (QBCore), this is the format, taken from the shipped grilled cheese sandwich:
['tosti'] = {
['name'] = 'tosti',
['label'] = 'Grilled Cheese Sandwich',
['weight'] = 200, -- grams
['type'] = 'item', -- or 'weapon'
['image'] = 'tosti.png',
['unique'] = false, -- true: one per slot
['useable'] = true,
['shouldClose'] = true, -- close the inventory on use
['description'] = 'Nice to eat',
['decay'] = 0.07, -- days from 100% to 0%
['delete'] = false, -- remove it when broken
['object'] = 'prop_sandwich_01', -- prop on the ground and when thrown
['disableThrow'] = true,
['client'] = {
status = { hunger = 200000 },
usetime = 2500,
anim = { dict = 'mp_player_inteat@burger', clip = 'mp_player_int_eat_burger_fp' },
prop = { model = 'prop_cs_burger_01', pos = vec3(0.02, 0.02, -0.02), rot = vec3(0.0, 0.0, 0.0) },
disable = { move = true, car = true, mouse = false, combat = true },
removeAfterUse = true,
},
},Optional field | What it does |
|---|---|
|
|
|
|
| A list of jobs allowed to use it. |
|
|
| The player level needed to use it (with the Missions page on). |
|
|
|
|
A weapon needs an item of type = 'weapon' with its ammotype (AMMO_PISTOL, AMMO_RIFLE…), and an entry in the weapon list:
-- shared/weapons.lua
[`weapon_pistol`] = {
['name'] = 'weapon_pistol',
['label'] = 'Pistol',
['weapontype'] = 'Pistol',
['ammotype'] = 'AMMO_PISTOL',
['damagereason'] = 'Pistoled / Blasted / Plugged / Bust a cap in',
},The event prefix. Events written here as
inventory:…use the default prefix. If a developer changed Event prefix in the advanced settings, theinventory:server:…andinventory:client:…events change with it — which is why it should stayinventory.



