Commands#
Officer commands only work for jobs listed under Admin → Dispatch → Jobs, and most of them only on duty. Command names marked as configurable change in the file shown.
Command | Who | Description |
|---|---|---|
| Police jobs | Opens or closes the MDT tablet (also the |
| Admins | Opens the admin panel. Anyone else sees their identifiers with ready-made |
| Admins | Teleports through every configured station point. |
| On duty | The quick menu (default |
| On duty | Assigns yourself — or, as a dispatcher, another unit — to a call. |
| Units on the call | Adds a note to the call. |
| Anyone | Creates a priority-1 call for police and sheriff at your position, with a screenshot. |
| Anyone | Citizen calls to emergency services. Configurable in |
| Officers | Join or leave a callsign. |
| Officers | Choose your map blip, or hide it. |
| On duty | A department radio message, also posted to game chat. |
| Officers | Allows or blocks other officers from watching your bodycam. |
| K9 officers, on duty | Deploys or stores your dog. Renamed in Admin → K9 Unit. |
| The object's jobs | Places a cone, barrier, speed radar, spike strip or light — e.g. |
| Holder of a | Repairs the broken camera within 5 m. Configurable in |
| Admins | Repairs the nearest broken camera, or every one. |
| Handcuff permission | Puts the cuffed suspect into, or takes them out of, the nearest vehicle. |
| Downed players | Officer Down / Citizen Down distress call (qs-police-alerts, key |
| Evidence jobs, on duty | DNA samples and scene cleaning (qs-police-evidence). See Companion Resources. |
| Server console | Which banking adapter and account a job uses, its balance, and — with an amount — a real test deposit. |
Keybinds#
Every key can be rebound by each player in Settings → Key Bindings → FiveM. Server defaults are in config/shared/keys_commands.lua (radar keys in config/shared/rpol.lua).
Key | Action |
|---|---|
| Radio push-to-talk. In a vehicle with a light bar the same key also sounds the air horn — rebind one of the two if your officers prefer. |
| Quick menu. |
| Previous / next call in the widget. |
| Respond to the selected call. |
| Small / full widget. |
| Handcuff · escort. |
| K9 follow · K9 in/out of the vehicle (only with the dog deployed). |
| Show the speed radar · reset its fast lock. |
| Light groups · siren · siren tone (qs-police-veh-creator). |
Officers can also create their own radio keys from the radio page — each one appears in the FiveM key bindings as "Radio Keybind: <name>".
Sending a Dispatch Call#
The export every robbery, heist or alarm script needs. It works from the client — the easy way, when a player is right there — or from the server.
-- CLIENT: a player is robbing a store
local info = exports['qs-police-creator']:GetPlayerInfo() -- coords, sex, street, vehicle, plate…
local result = exports['qs-police-creator']:CreateDispatchCall({
title = 'Store Robbery', -- required
description = ('A %s is robbing the store on %s'):format(info.sex, info.street_1), -- required
location = { coords = { x = info.coords.x, y = info.coords.y, z = info.coords.z } }, -- required
jobNames = { 'police', 'sheriff' }, -- required
caller = { name = true, phone = true }, -- optional: filled in from the player; leave out for anonymous
priority = 1, -- optional: 1 = most urgent
blip = { sprite = 60, color = 1, scale = 1.0, label = 'Store Robbery' }, -- optional
image = exports['qs-police-creator']:GetScreenshotUrl(), -- optional: needs an image host
})
if result and result.success then
-- the call is on every officer's MDT
end-- SERVER: a silent alarm
local result = exports['qs-police-creator']:CreateDispatchCall({
title = 'Silent Alarm',
description = 'A bank alarm was triggered',
location = { coords = { x = 150.0, y = -1040.0, z = 29.4 } },
jobNames = { 'police' },
priority = 1,
blip = { sprite = 60, color = 5, scale = 1.0, label = 'Silent Alarm' },
}, source) -- optional: the player the call is aboutIt returns { success = true, data = call }, or { success = false, message = … } when a required field is missing. GetScreenshotUrl returns nil when no image host is configured — leave image out in that case.
Client Exports#
Called from a client script as exports['qs-police-creator']:Name(...).
Tablet and duty
exports['qs-police-creator']:IsTabletOpen() -- true / false
exports['qs-police-creator']:SetDutyStatus(true) -- put the local officer on (true) or off (false) duty
-- React when the tablet opens or closes
AddEventHandler('qs-police-creator:client:tabletToggled', function(isOpen)
print('MDT ' .. (isOpen and 'opened' or 'closed'))
end)Player, vehicle and screenshot info
local info = exports['qs-police-creator']:GetPlayerInfo()
-- info.coords, info.street_1, info.street_2, info.sex,
-- info.vehicle, info.vehicle_label, info.vehicle_colour, info.vehicle_plate,
-- info.speed, info.doorCount
exports['qs-police-creator']:GetVehicleLabel(vehicle) -- display name
exports['qs-police-creator']:GetVehicleColour(vehicle) -- primary colour name
exports['qs-police-creator']:GetScreenshotUrl() -- uploads a screenshot, returns its URL or nil
exports['qs-police-creator']:GetRadarTargetInfo() -- { plate, speed, units, dir, antenna, model } or nilHandcuffs
Block your own actions — a phone, an inventory, an emote — while the player is cuffed:
exports['qs-police-creator']:IsHandcuffed() -- true / false
exports['qs-police-creator']:IsEscorted() -- being escorted
exports['qs-police-creator']:IsEscorting() -- escorting someone
exports['qs-police-creator']:GetHandcuffState() -- { isHandcuffed, isEscorted, isEscorting, escorter, escortTarget, escapeAttempts }
exports['qs-police-creator']:RemoveHandcuffs() -- uncuff the local player
if exports['qs-police-creator']:IsHandcuffed() then return endStations and the interface
exports['qs-police-creator']:GetShops() -- configured equipment shops
exports['qs-police-creator']:GetStashes() -- configured item storage
exports['qs-police-creator']:GetBillingLocations() -- fine payment points
exports['qs-police-creator']:GetCurrentTheme() -- the officer's MDT theme name
exports['qs-police-creator']:SetRadioAnimationIndex(2) -- pick the radio talking animationServer Exports#
Called from a server script. playerId is the player's server id.
Player job
Read straight from your framework (QBCore, Qbox or ESX):
exports['qs-police-creator']:GetJobName(playerId) -- 'police'
exports['qs-police-creator']:GetJobGrade(playerId) -- 3
exports['qs-police-creator']:GetPlayerIdentifier(playerId) -- citizenid (QB/Qbox) or identifier (ESX)Society money
The department's bank account, through whichever banking script is detected:
exports['qs-police-creator']:DepositToSociety('police', 500, 'Towing fee') -- true if it landed
exports['qs-police-creator']:WithdrawFromSociety('police', 500, 'New radios') -- false if the account cannot cover it
exports['qs-police-creator']:GetSocietyBalance('police') -- a number, or nilHandcuffs
exports['qs-police-creator']:IsPlayerHandcuffed(playerId) -- true / false
exports['qs-police-creator']:IsPlayerEscorted(playerId) -- true / false
exports['qs-police-creator']:GetPlayerHandcuffState(playerId) -- { isHandcuffed, isEscorted, escortedBy }Logs
Write to the Action Logs — and to the category's Discord webhook if one is set:
exports['qs-police-creator']:CreateLog('system', 'evidence_sold', { item = 'filled_evidence_bag', price = 200 }, source)Shops, storage and fine points
exports['qs-police-creator']:GetShops()
exports['qs-police-creator']:GetStashes()
exports['qs-police-creator']:GetBillingLocations()
-- Add / Set / Delete variants exist for each: AddShop(shop), SetShop(shop), DeleteShop(id), …Screenshots
-- Screenshot a player and upload it to the configured host
exports['qs-police-creator']:GetScreenshotUrl(playerId, function(url)
print(url) -- nil when no image host is set
end)Events#
Every fine written from the MDT, by any department, fires a server event once it is saved — use it to send a phone message, an email or a bill of your own:
AddEventHandler('qs-police-creator:server:penaltyCreated', function(penalty)
-- penalty.id row id
-- penalty.identifier the fined citizen
-- penalty.target their server id if online, otherwise nil
-- penalty.job / jobLabel the department that wrote it
-- penalty.totalFine amount
-- penalty.totalMonths sentence months
-- penalty.charges { type, id, title | description, fine_amount, sentence_months }
-- penalty.appliedBy officer name, penalty.appliedBySource their server id
-- penalty.appliedAt unix time
-- penalty.paid true when the total is 0
end)Sending your own notice? Turn off the built-in one with Config.Penalties.NotifyOnCreate = false in config/server/penalties.lua.
Event | Side | When |
|---|---|---|
| Client | The MDT opens or closes ( |
| Client | The officer goes on or off duty ( |
| Client | The player's job or grade changes ( |
| Server | A fine is saved (above). |
| Server | A vehicle is impounded ( |
State bags: Player(id).state.bodycamEnabled says whether an officer's bodycam can be watched, and fleet vehicles carry Entity(vehicle).state.qsFleet (plate and garage) — check it in your own garage or chop-shop script to leave police units alone.
Evidence Events#
From the client of the player who leaves the trace, in your own robbery or injury scripts:
TriggerServerEvent('qs-police-evidence:server:CreateFingerPrintDrop') -- a fingerprint where the player stands
TriggerServerEvent('qs-police-evidence:server:CreateBloodDrop') -- a blood drop with the player's DNA


