Analytics runs only if you accept. No names, codes or payment details are sent, and shopping works the same either way. Details: privacy and cookies.

  • Necessary Keeps your cart and this choice in your browser so the store works. We ask again after 12 months.
    Always on
  • Analytics (PostHog) Counts pages, clicks and store actions with your device type and rough location, and may record your visit with typed text hidden. Its cookie lasts 365 days. Data is stored in the EU.
    Off
  • Videos Product videos load from YouTube (Google) only when you press Play. YouTube may store data on your device. If you reject, Play opens the video on youtube.com in a new tab instead.
    When you press Play

With analytics on, the site keeps this visit's campaign source in this tab until you close it.

Change your choice any time with Cookie settings at the bottom of the page.

FiveM vehicle keys, dispatch and billing fixes

When officers or medics get no vehicle keys, no dispatch alert or no bill, our script is not yet pointed at the key, dispatch or billing resource your server runs. The fix is one value in config.lua, or a few lines in client/main_editable.lua or server/main_editable.lua. Escrow leaves these files open in Advanced Police Job, Advanced Ambulance Job, All-in-one MDT V2 and Advanced Boss Menu V2 on ESX, QBCore and Qbox.

All four are our scripts. Each hook already calls some resources by name, and you add any other resource to the same function.

Before you start

  • Editable files. Each script’s fxmanifest.lua leaves these out of escrow: config.lua, locales/*.lua, client/frameworks/*.lua, server/frameworks/*.lua, client/main_editable.lua and server/main_editable.lua. All-in-one MDT V2 also leaves config_sv.lua open.
  • Resource names. The MDT V2 folder is tk_mdt; the others are tk_policejob, tk_ambulancejob and tk_bossmenu. The other vendor’s resource must be started under its exact folder name, because our code checks it by that name, as in GetResourceState('qb-vehiclekeys') == 'started'.
  • Rollback. Copy a file before you edit it. If the resource stops starting, put the copy back and run ensure on it.
  • Updates. Each release of our scripts ships its own copies of these files. Compare them with your edited copies before you overwrite anything.

Our docs explain how integrations are maintained under 3rd party integrations not working correctly.

No keys for garage or impound vehicles

In Advanced Police Job, SpawnedGarageVehicle and SpawnedImpoundVehicle in server/main_editable.lua already give keys through qb-vehiclekeys and qbx_vehiclekeys when either is started. In Advanced Ambulance Job, SpawnedGarageVehicle in server/main_editable.lua calls qb-vehiclekeys only. Both scripts also have an empty client-side SpawnedGarageVehicle(vehicle) in client/main_editable.lua; edit the client or the server function, not both.

Worked example: Ambulance Job on Qbox with qbx_vehiclekeys. The qbx_vehiclekeys README recommends its own exports over the qb-vehiclekeys names it also provides. Its server export is GiveKeys(source, vehicle, skipNotification) and takes the vehicle entity; qb-vehiclekeys takes the plate.

  1. In tk_ambulancejob/server/main_editable.lua, replace the SpawnedGarageVehicle function with this. It keeps the shipped qb-vehiclekeys call and adds the qbx_vehiclekeys call Advanced Police Job ships:

    function SpawnedGarageVehicle(playerId, vehicle, plate)
        if GetResourceState('qb-vehiclekeys') == 'started' then
            exports['qb-vehiclekeys']:GiveKeys(playerId, Utils.Trim(plate))
        end
        if GetResourceState('qbx_vehiclekeys') == 'started' and vehicle and DoesEntityExist(vehicle) then
            exports.qbx_vehiclekeys:GiveKeys(playerId, vehicle)
        end
    end
    
  2. In the server console, run ensure tk_ambulancejob. The script restarts with the edited function.

For another key script, add its server export to the same function, with the arguments its own documentation gives.

No dispatch alert, or no call on the MDT map

In Advanced Ambulance Job, Config.Dispatch in config.lua accepts 'none', 'tk' or 'cd'. With 'none', a dead player who presses G sends the built-in distress signal straight to online EMS, at most once every 60 seconds (Config.DistressSignal.cooldown). Every other dispatch goes into SendDistressSignal(coords) in client/main_editable.lua.

All-in-one MDT V2 shows calls on its map from the dispatch named in its own Config.Dispatch: tk, cd, qs, ps, core, rcore or loverp. It copies each call to the MDT whose jobs list holds one of the call’s jobs.

Worked example: QBCore with ps-dispatch 3.0.0. Its InjuriedPerson export sends a 10-69 alert from the player’s position to every on-duty player whose job name or job type is ems, and QBCore’s ambulance job has the type ems.

  1. In tk_ambulancejob/client/main_editable.lua, inside SendDistressSignal, add these two lines directly before the final else:

        elseif Config.Dispatch == 'ps' then
            exports['ps-dispatch']:InjuriedPerson()
    
  2. In tk_ambulancejob/config.lua, set Config.Dispatch = 'ps'. Pressing G now sends the ps-dispatch alert instead of the built-in signal.

  3. In tk_mdt/config.lua, set Config.Dispatch = 'ps'. The MDT now copies every ps-dispatch alert to its map.

  4. In the same file, add ems = 0, to the jobs list of the ambulance MDT. ps-dispatch addresses EMS by the job type ems, while the MDT matches job names; the police MDT already lists leo = 0. A job named ems can then also open the ambulance MDT.

  5. Run ensure tk_ambulancejob and ensure tk_mdt.

For moving every alert to another dispatch script, see Switch FiveM dispatch without rewriting alerts.

The MDT shows no phone number

All-in-one MDT V2 reads phone numbers through Config.Phone in config.lua. The values it handles are lb, qs, gks, gks2, high, yseries and okok. With an empty value, it reads the framework instead: charinfo.phone in the players table on QBCore, or the phone_number column of users on ESX when that column exists. Any other phone goes into GetPhoneNumber(identifier) in server/main_editable.lua.

Worked example: QBCore with qb-phone. Leave Config.Phone = ''. QBCore creates charinfo.phone for each character, and qb-phone reads the same charinfo.phone, so the MDT shows the number players see on their phone with no code change.

Fines and bills never reach the player

In Advanced Police Job and Advanced Ambulance Job, Config.Billing in config.lua takes one of three values:

Value What a bill or fine does
'esx' SendBill in client/main_editable.lua sends an esx_billing:sendBill bill for society_police or society_ambulance
'qb' The sendBill event in server/main_editable.lua takes the amount from the player’s bank and adds it to the job account through qb-banking; Ambulance Job uses Renewed-Banking instead when it is started
'okok' Opens the okokBilling invoice menu

In All-in-one MDT V2, FinePlayer(data) in client/main_editable.lua is empty, so a fine from the MDT charges nothing until you add your billing call. data holds targetIdentifier, amount and charges.

Worked example: ESX with esx_billing from ESX-Legacy-Addons. Its esx_billing:sendBill event takes a server ID, so the example asks the MDT’s own tk_mdt:getIdFromIdentifier callback for it first.

  1. In tk_mdt/client/main_editable.lua, replace FinePlayer with:

    function FinePlayer(data)
        TriggerCallback('tk_mdt:getIdFromIdentifier', function(targetId)
            if not targetId then return end
            TriggerServerEvent('esx_billing:sendBill', targetId, 'society_police', 'MDT fine', data.amount)
        end, data.targetIdentifier)
    end
    
  2. Run ensure tk_mdt. A fine from the MDT now creates an esx_billing bill to society_police.

With its default config, esx_billing sends the bill only when the officer’s job is police at grade 1 or higher (Config.MinimumBillingGrade), the suspect is online within 10 metres (Config.BillingDistance), and the fine is at most 100,000 (Config.MaxBillAmount). Fines of 50,000 or more (Config.HighBillConfirmationAmount) wait for the suspect to confirm.

Company money shows 0 in the boss menu

Advanced Boss Menu V2 reads and moves company money through Config.Banking in config.lua:

Value Resource
'esx' esx_addonaccount, account society_<job>
'qb_old' qb-management
'qb_new' qb-banking
'okok' okokBanking
'renewed' Renewed-Banking
'fd' fd_banking

Worked example: QBCore with a qb-banking that exports GetAccountBalance. Set Config.Banking = 'qb_new' and run ensure tk_bossmenu. The menu then reads the job account with GetAccountBalance and moves money with AddMoney and RemoveMoney, all three exported by qb-banking. Any other banking script goes into GetSocietyMoney, RemoveSocietyMoney and AddSocietyMoney in server/main_editable.lua.

Check it works

  • Keys: as a medic, take a vehicle from the hospital garage, then lock and unlock it with your key script’s control.
  • Dispatch: with a second player on duty as EMS, let your character die and press G. The EMS player gets the ps-dispatch alert, and the call appears on the ambulance MDT map.
  • Phone: open a citizen’s profile in the MDT. It shows the number the player sees on their phone.
  • Fines: fine an online player standing beside you from the MDT. The bill appears in their esx_billing bills.
  • Company money: open /bossmenu as a boss. The balance matches the job account in qb-banking.

If it still fails

  • No such export GiveKeys in resource qbx_vehiclekeys: the named resource is running but exports no function of that name. Check the export name against that resource’s own repository and version.
  • Keys, alerts or bills still missing with no error: the other resource’s folder name differs from the name in the GetResourceState check or the export call. Rename the folder or change the name in the editable file.
  • [WARNING] Billing not set correctly in config! in the F8 console: Config.Billing holds a value SendBill does not handle. Set 'esx', 'qb' or 'okok', or add a branch for your billing script to SendBill.
  • Calls reach ps-dispatch but not the MDT map: the call’s jobs match no MDT jobs list. Add the job type the alert uses, such as ems = 0, as in step 4 of the dispatch fix.
  • Still no phone number on ESX: the users table has no phone_number column. Set Config.Phone to your phone script, or add a branch to GetPhoneNumber.

Scripts in this guide

  • Arrests, patrol gear, vehicle radar, live bodycams and as many stations as you need.

    Supports ESX, QBCore and Qbox

    Top 5 paid police job script on FiveM

    450+ servers (5Metrics, checked 11 October 2026)

    €24.99+ VAT at checkout, one-off

  • Skeletal injury system with 13 treatment items, last stand revival and hospitals.

    Supports ESX, QBCore and Qbox

    300+ servers (5Metrics, checked 11 October 2026)

    €24.99+ VAT at checkout, one-off

  • All-in-one MDT V2

    • In Essential

    Unlimited department MDTs with records, incidents, warrants and in-game permissions.

    Supports ESX, QBCore and Qbox

    Top 3 MDT script on FiveM

    650+ servers (5Metrics, checked 11 October 2026)

    €24.99+ VAT at checkout, one-off

  • Staff records, company money, statistics, a job shop and permissions for every grade.

    Supports ESX, QBCore and Qbox

    150+ servers (5Metrics, checked 11 October 2026)

    €14.99+ VAT at checkout, one-off

Server counts: 5Metrics, checked 11 October 2026. Detected servers running each script, rounded down.