Browse docs
Exports
This page documents the supported public integration calls. Client values are never authoritative for police permissions, review decisions, evidence, offences, or billing.
Server Exports
Dispatch
Create a dispatch for the MDT Tablet.
exports["sky_jobs_base"]:createDispatch(
"Suspicious activity", -- title
"Caller reports suspicious behavior near Legion Square.", -- description
GetEntityCoords(PlayerPedId()), -- coords (vector3)
{ "police", "sheriff" } -- jobs
)
exports["sky_jobs_base"]:createDispatch(
"Suspicious activity", -- title
"Caller reports suspicious behavior near Legion Square.", -- description
vector3(215.9, -810.2, 30.7), -- coords (vector3)
{ "police", "sheriff" } -- jobs
)
Restraints
These are compatibility forwards to the shared sky_jobs_base interaction system. Police jobs from
Config.Jobs are registered automatically. For any other job resource, call
registerInteractionJobs from a server script before using these exports. The acting player's job,
duty policy, target distance/state, and configured item requirements are validated server-side;
calling a Police Job export does not bypass them.
See the Sky Jobs Base server exports for registration, permissions, and the preferred shared exports.
Police keeps compatibility forwards for cuffs, zipties, and escort. Leg restraints and head bags are owned exclusively by Jobs Base; call the corresponding sky_jobs_base exports directly.
cuffPlayer(sourceId, targetId, cuffType?, options?)
- Purpose: Applies cuffs or zipties to a target player from another resource.
- Arguments:
sourceId(number): The server ID of the acting player.targetId(number): The server ID of the target player.cuffType(string?):"cuffs"(default) or"zipties".options(table?):ignoreItemCheck(boolean?) — skip the restraint item requirement and consumption.allowSelf(boolean?) — allowsourceId == targetId.
- Returns:
boolean, string?—trueon success, otherwisefalseand a reason key.
local success, reason = exports["sky_policejob"]:cuffPlayer(sourceId, targetId, "cuffs", {
ignoreItemCheck = false,
allowSelf = false
})
uncuffPlayer(sourceId, targetId, options?)
- Purpose: Removes cuffs or zipties from a target player.
- Returns:
boolean, string?.
local success, reason = exports["sky_policejob"]:uncuffPlayer(sourceId, targetId)
cutZipties(sourceId, targetId, options?)
- Purpose: Cuts zipties from a target player.
- Returns:
boolean, string?.
local success, reason = exports["sky_policejob"]:cutZipties(sourceId, targetId)
isPlayerCuffed(targetId)
- Purpose: Reports whether the target player is currently restrained.
- Returns:
boolean.
local cuffed = exports["sky_policejob"]:isPlayerCuffed(targetId)
Escort
escortToggle(sourceId, targetId)
- Purpose: Starts or stops escorting the target player.
- Returns:
boolean, string?.
local success, reason = exports["sky_policejob"]:escortToggle(sourceId, targetId)
escortPutInVehicle(sourceId, targetId, netId?, seat?)
- Purpose: Places the escorted player into a vehicle. Without
netIdthe closest valid vehicle is used. - Returns:
boolean, string?.
local success, reason = exports["sky_policejob"]:escortPutInVehicle(sourceId, targetId)
escortTakeOutVehicle(sourceId, targetId)
- Purpose: Takes the escorted player out of a vehicle.
- Returns:
boolean, string?.
local success, reason = exports["sky_policejob"]:escortTakeOutVehicle(sourceId, targetId)
Jail
isPlayerInPrison(playerId)
- Purpose: Reports whether the player is currently serving a jail sentence.
- Returns:
boolean.
local imprisoned = exports["sky_policejob"]:isPlayerInPrison(playerId)
Devices and tracking
GetCctvCameras(jobName?)
- Purpose: Returns the deployed CCTV cameras, optionally filtered to one police job.
- Returns:
table— camera records.
local cameras = exports["sky_policejob"]:GetCctvCameras("police")
GetSpeedcamCameras()
- Purpose: Returns the deployed speed cameras.
- Returns:
table— camera records.
local speedcams = exports["sky_policejob"]:GetSpeedcamCameras()
GetMapTrackers()
- Purpose: Returns the currently broadcast GPS trackers and ankle monitors (the data shown on the police map).
- Returns:
table— tracker records.
local trackers = exports["sky_policejob"]:GetMapTrackers()
GetWheelClampOnVehicle(vehicleOrNetId, plate?)
- Purpose: Returns the wheel clamp attached to a vehicle, resolved by entity/net ID or plate.
- Returns:
table | nil—{ attached = true, netId, plate, wheelBone }ornilwhen no clamp is attached.
local clamp = exports["sky_policejob"]:GetWheelClampOnVehicle(netId)
if clamp then
print(clamp.plate, clamp.wheelBone)
end
Usable items
useItem(source, itemName, payload?)
- Purpose: Triggers a registered Police-specific usable-item handler for a player. Use this when your inventory or another resource wants to run a Police item such as
gps_trackerwithout going throughRegisterUsableItem. Shared restraint items belong tosky_jobs_base. - Returns:
boolean—truewhen a handler ran successfully; prints an English debug message when no handler is registered for the item.
exports["sky_policejob"]:useItem(source, "gps_tracker")
Manual tablet registry exports
When Config.PoliceTablet.autoFillFromDatabase.citizens = false and/or Config.PoliceTablet.autoFillFromDatabase.vehicles = false, other scripts can manage the manual tablet registry entries through server exports.
If the matching autofill setting is still enabled, these exports return:
{
success = false,
error = "auto_fill_enabled"
}
Citizens
Create a manual citizen profile entry.
local result = exports["sky_policejob"]:RegisterCitizen({
identifier = "char1:abcd",
name = "Max Mustermann",
gender = "male",
dob = "1999-04-15",
job = "Unemployed",
tags = { "Wanted" },
notes = {
{ title = "Note", text = "Manual record" }
},
fingerprint = "FP-12345",
dna = "DNA-12345"
})
Update an existing manual citizen profile entry.
local result = exports["sky_policejob"]:UpdateCitizen({
identifier = "char1:abcd",
name = "Max Mustermann",
image_url = "https://example.com/citizen.png",
tags = { "Wanted", "VIP" }
})
Read or delete a manual citizen profile entry.
local citizen = exports["sky_policejob"]:GetCitizen("char1:abcd")
local deleted = exports["sky_policejob"]:DeleteCitizen("char1:abcd")
Supported citizen payload fields:
identifiernamegenderdobjobimage_urlorurlimage_idtagsnotesfingerprintdna
Vehicles
Create a manual vehicle profile entry.
local result = exports["sky_policejob"]:RegisterVehicle({
plate = "B-EMS-12",
model = "ambulance",
owner_name = "Sky Medical",
owner_identifier = "society:ambulance",
color = {
primary = "white",
secondary = "red"
}
})
Update an existing manual vehicle profile entry.
local result = exports["sky_policejob"]:UpdateVehicle({
plate = "B-EMS-12",
tags = { "Fleet" },
cases = { "CASE-1024" },
notes = {
{ title = "Storage", text = "Assigned to EMS fleet" }
}
})
Read or delete a manual vehicle profile entry.
local vehicle = exports["sky_policejob"]:GetVehicle("B-EMS-12")
local deleted = exports["sky_policejob"]:DeleteVehicle("B-EMS-12")
Supported vehicle payload fields:
platemodelownerNameorowner_nameownerIdentifierorowner_identifiercolorimage_urlorurlimage_idtagsnotescases
Weapons
Create or update a weapon entry in the weapon registry used by the tablet and the weapon checks.
local result = exports["sky_policejob"]:RegisterWeapon({
serialNumber = "SN-4815-1623",
model = "WEAPON_PISTOL",
weaponType = "Pistol",
manufacturer = "Hawk & Little",
caliber = "9mm",
ownerIdentifier = "char1:abcd",
ownerName = "Max Mustermann",
registrationStatus = "valid",
expiresAt = "2027-01-01"
})
if result.success then
print(result.data.weapon.serial_number)
end
Supported weapon payload fields:
serialNumberorserial_number(required)model(required)weaponTypeorweapon_typemanufacturercaliberownerIdentifierorowner_identifierownerNameorowner_nameregistrationStatusorregistration_status—valid,expired,revoked,lost_stolen, orevidence_holdregisteredAtorregistered_at(YYYY-MM-DD)expiresAtorexpires_at(YYYY-MM-DD)
Salary
Pause or resume salary payouts for police employees. These exports are provided by sky_jobs_base and work for all job types.
pausePlayerSalary(playerId)
- Purpose: Pauses salary payouts for the given player.
- Returns:
boolean—trueon success.
resumePlayerSalary(playerId)
- Purpose: Resumes salary payouts for the given player.
- Returns:
boolean—trueon success.
isPlayerSalaryPaused(playerId)
- Purpose: Checks whether salary payouts are currently paused.
- Returns:
boolean—trueif paused.
exports["sky_jobs_base"]:pausePlayerSalary(playerId)
exports["sky_jobs_base"]:resumePlayerSalary(playerId)
local paused = exports["sky_jobs_base"]:isPlayerSalaryPaused(playerId)
Advanced Speed Camera
Read deployed speed cameras
GetSpeedcamCameras()
Returns the current server-owned camera catalogue. This is a server export and cannot be called directly by a FiveM client.
local cameras = exports["sky_policejob"]:GetSpeedcamCameras()
for _, camera in ipairs(cameras) do
print(camera.id, camera.label, camera.status, camera.limit)
end
Each entry contains:
| Field | Type | Description |
|---|---|---|
id | string | Display ID such as SP-004 |
label | string | Configured camera name |
type | string | Always speedcam |
status | string | online, maintenance, or offline |
durability | number | Current server-owned durability |
limit | number | Configured speed limit |
tolerance | number | Configured tolerance |
target | number | Internal numeric camera ID used by supported camera views |
coords | table | Server-stored world coordinates |
heading | number | Server-stored camera heading |
Treat the returned table as a snapshot. Changing it does not change the server cache or database.
Review mutations are intentionally private
Advanced review approval and discard are not public exports. The built-in path validates the acting officer's current police job, duty, Boss Menu permission, review ownership, evidence, offence, fine, billing adapter, target player, and review status immediately before mutation.
See Advanced Speed Camera for the complete review and exploit-protection workflow.
Client Exports
Restraints
These exports use the shared sky_jobs_base interaction system. The local player's job must be
registered on the server and have the required capability. Police jobs from Config.Jobs are
registered automatically; other job resources must use the server-side registerInteractionJobs
export first. Calling a client export alone does not whitelist a job.
See the Sky Jobs Base client exports and server whitelist documentation for the preferred shared API.
Police keeps compatibility forwards for cuffs, zipties, and escort. Use the direct Jobs Base exports for leg restraints and head bags.
cuffPlayer(cuffType?)
- Purpose: Applies cuffs or zipties to the nearest valid player as an officer.
- Arguments:
cuffType(string?):"cuffs"(default) or"zipties".
- Returns:
boolean, string?.
exports["sky_policejob"]:cuffPlayer()
uncuffPlayer()
- Purpose: Removes cuffs from the nearest player as an officer.
- Returns:
boolean, string?.
exports["sky_policejob"]:uncuffPlayer()
cutZipties()
- Purpose: Cuts zipties on the nearest player as an officer.
- Returns:
boolean, string?.
exports["sky_policejob"]:cutZipties()
useCuffPlayer(cuffType?) / useUncuffPlayer() / useCutZipties()
- Purpose: Compatibility aliases for
cuffPlayer,uncuffPlayer, andcutZipties. They use the same server-side job whitelist and do not bypass access or item checks. - Returns:
boolean, string?.
exports["sky_policejob"]:useCuffPlayer("cuffs") -- or "zipties"
exports["sky_policejob"]:useUncuffPlayer()
exports["sky_policejob"]:useCutZipties()
useHandcuffsItem() / useZiptiesItem()
- Purpose: Runs the full handcuffs/zipties item flow (the same path as using the inventory item), including the item checks.
- Returns:
boolean.
exports["sky_policejob"]:useHandcuffsItem()
exports["sky_policejob"]:useZiptiesItem()
isPlayerCuffed(serverId)
- Purpose: Checks the locally known cuff state for a player.
- Returns:
boolean.
local cuffed = exports["sky_policejob"]:isPlayerCuffed(serverId)
Escort
escortToggle()
- Purpose: Starts or stops escorting the nearest player.
- Returns:
boolean, string?.
exports["sky_policejob"]:escortToggle()
escortPutInVehicle()
- Purpose: Puts the escorted player into the closest vehicle.
- Returns:
boolean, string?.
exports["sky_policejob"]:escortPutInVehicle()
escortTakeOutVehicle()
- Purpose: Takes the escorted player out of a vehicle.
- Returns:
boolean, string?.
exports["sky_policejob"]:escortTakeOutVehicle()
Jail
openJailMenu()
- Purpose: Opens the menu to put someone in jail.
exports["sky_policejob"]:openJailMenu()
Radial menu actions
Other resources (e.g. a custom radial menu or keybind resource) can read and trigger the police radial actions instead of using the built-in radial menu. In the built-in menu, currently available actions are grouped into localized person and vehicle submenus.
Available action IDs: handcuff, unhandcuff, ziptie, cut_zipties, leg_restraints, ankle_monitor, head_bag, escort, escort_vehicle, escort_take_out, tackle, tackle_cuff, tackle_release, player_search, carry_patient, impound, park_vehicle, wheel_clamp, wheel_clamp_remove, camera_disassemble, billing, tablet.
getRadialActions()
- Purpose: Returns every radial action currently offered to the local player, including its availability state.
- Returns:
table— array of action records (id,label,disabled, …). Empty when the radial system is disabled.
local actions = exports["sky_policejob"]:getRadialActions()
getRadialAction(actionId)
- Purpose: Returns a single radial action record by ID.
- Returns:
table | nil.
local action = exports["sky_policejob"]:getRadialAction("handcuff")
getRadialActionReport()
- Purpose: Returns all actions plus a per-ID availability map — useful to build an external menu in one call.
- Returns:
table—{ actions = { ... }, availability = { [actionId] = { available, disabledReasonKey, disabledReason } } }.
local report = exports["sky_policejob"]:getRadialActionReport()
if report.availability["handcuff"] and report.availability["handcuff"].available then
-- show the handcuff option
end
isRadialMenuActionAvailable(actionId)
- Purpose: Checks whether one radial action is currently available.
- Returns:
boolean.
local available = exports["sky_policejob"]:isRadialMenuActionAvailable("impound")
triggerRadialMenuAction(actionId)
- Purpose: Executes a radial action for the local player.
- Returns:
boolean, table?—trueon success, otherwisefalseand a reason ({ key, fallback }).
local success, reason = exports["sky_policejob"]:triggerRadialMenuAction("player_search")
Usable items
useItem(itemName, payload?)
- Purpose: Triggers a registered client-side police usable-item handler for the local player.
- Returns:
boolean—truewhen a handler ran successfully; prints an English debug message when no handler is registered for the item.
exports["sky_policejob"]:useItem("bodycam")
Advanced Speed Camera boundary
No client-side review mutation export
Sky Police Job intentionally does not export client functions for approving or discarding reviews, changing measured speed, replacing a plate, attaching arbitrary evidence, or issuing an invoice. Those actions require server-owned context and remain inside the authenticated tablet workflow.
Detect the open review app
An integration that only needs presentation state can use the shared Jobs Base tablet export.
local tablet = exports["sky_jobs_base"]:GetTabletState()
if tablet.open and tablet.appKey == "speedcam_reviews" then
print("Speed Camera Reviews is open")
end
For deployed camera state, use the read-only
client events. For authoritative
camera data, call GetSpeedcamCameras() from a server script.
Support
Need help? Our support team is always ready to assist.
Join Discord