Pulse PhoneDocs
Pulse Phone docs

Pulse Phone: install guide

Installing takes about two minutes. Sections 1 and 2 are all most servers need. The rest of this page is there when you want it: find your framework in section 3, and if something is wrong, go straight to Troubleshooting (section 11).

1. Quick install

Step 1: Copy

Put the phone folder into your server's resources folder. Keep the name phone.

Step 2: Add one line to server.cfg

Put it after your database, framework, inventory and voice scripts:

ensure phone

Step 3: Restart the server

That's it. In game, press F1 (or type /phone).

What is in the folder

Folder What it is
config/ Your settings. Start with config/config.lua: every option has an explanation beside it.
config/items/ Ready-to-paste item entries for your inventory, with pictures in config/items/images/ (section 4).
ownermedia/ Your own ringtones, alert tones and wallpapers (see its README).
bridge/ How the phone talks to your framework and other scripts. Found automatically, so only developers need to open it.
developers/ Add your own apps, or connect your own scripts. Start with CUSTOM_APPS.md and EXPORTS.md.
media/ Photos and videos players take, when you use the built-in store (section 6).
core/, stream/, ui/ The phone itself. Don't edit these.
phone.sql Only for hosts that don't let a resource create tables (section 2).

2. Requirements

What Required? What happens without it
OneSync on Required The start-up check fails with OneSync ... off. Add set onesync on.
Game build 2699 or newer Required The handset model does not stream. Set sv_enforceGameBuild.
oxmysql (or ghmattimysql, mysql-async) Recommended Data is kept in the resource's own key/value store. It persists, but you can't query it, and past about 30 players you should use MySQL.
A voice script: pma-voice, mumble-voip, SaltyChat, TokoVOIP or YACA Recommended Calls connect but carry no audio.
screenshot-basic Recommended The camera frames shots but cannot save photos.
A framework Optional The phone runs standalone: phones keyed to the player's licence, and the phone keeps its own bank.

A complete server.cfg block:

set onesync on
set sv_enforceGameBuild 2699        # or newer

ensure oxmysql
ensure screenshot-basic
ensure pma-voice
# ... your framework, then your inventory, banking, garage and housing scripts ...
ensure phone
# ... scripts that use the phone ...

The database. With oxmysql running, the phone creates its tables on first start and adds new ones by itself after every update. It tests the connection with a real query first and gives a database that is still starting 30 seconds. If the database never answers, the phone stores nothing, says so in the console, and keeps retrying. On a test server you can let it use the key/value store instead with set phone_db_fallback "kvp" (that data is never copied into SQL later).

Another phone's tables. If an old phone left tables with the same names (for example phone_messages), they are renamed to old_<name> at first start. Nothing is deleted.

3. Step by step for your framework

The phone finds your framework by its resource name: es_extended, qb-core, qbx_core, ox_core or vrp. You only need Config.Framework in config/config.lua if more than one is running, or for a custom framework.

Multicharacter works on every framework. Config.IdentityScope = 'character' (the default) gives each character its own phone. 'player' gives one phone per account. Pick once: changing it on a live server leaves every existing phone behind.

Company management (duty, staff, hiring, the company account in the Services app) uses the companies in Config.Services in config/apps.lua. If your job names differ from the defaults (police, ambulance, mechanic, taxi, fire ...), add yours to that company's job list. To choose the boss grades yourself, add bossGrade = <n> to the company.

ESX Legacy

ensure oxmysql
ensure es_extended
# ... your ESX scripts, inventory, banking ...
ensure pma-voice
ensure screenshot-basic
ensure phone

QBCore

ensure oxmysql
ensure qb-core
# ... qb-inventory and your other qb scripts ...
ensure pma-voice
ensure screenshot-basic
ensure phone

Qbox

ensure oxmysql
ensure qbx_core
ensure ox_inventory
# ... your other Qbox scripts, in Qbox's own order ...
ensure pma-voice
ensure screenshot-basic
ensure phone

ox_core

ensure oxmysql
ensure ox_core
ensure ox_inventory
# ... your other scripts ...
ensure pma-voice
ensure screenshot-basic
ensure phone

vRP

Only vRP 2 is supported (not vRP 1 or community forks). The phone loads a small extension into vRP from bridge/frameworks/vrp/. Nothing to copy.

ensure oxmysql
ensure vrp
# ... your other scripts ...
ensure pma-voice
ensure screenshot-basic
ensure phone

Standalone (no framework)

ensure oxmysql
ensure pma-voice
ensure screenshot-basic
ensure phone

Custom or in-house framework

  1. Set Config.Framework = 'custom' in config/config.lua.
  2. Give the phone a bridge table shaped like developers/custom_framework_bridge.lua: either as Config.Providers.custom in config/config.lua, or from your own resource with exports.phone:RegisterFrameworkBridge(MyBridge).
  3. Only GetCharacterId is required. Anything you leave out falls back to standalone (licence identity, the phone's own bank).

bridge/frameworks/custom.lua shows how the phone uses your table. To connect other in-house scripts (a banking or garage script), see developers/custom_provider_template.lua and developers/EXPORTS.md.

4. Items and inventories

Items are only needed on framework servers. The files are in config/items/ and the pictures in config/items/images/.

Item You need it when
phone Only with Config.Item.required = true (players must carry a phone) or unique phones.
pulse_phone_box The store sells phones in a sealed box. On by default (Config.Store.box).
pulse_magpack, pulse_magpack_max, pulse_cable The charging accessories. On by default (Config.Charging).
powerbank Optional. The old power bank item; it works as a MagPack.
pulse_phone_box_<finish> Only with Config.Store.boxPerFinish = true.

If an item is missing, the phone still starts. The store turns boxes off or takes that item off sale, and the console names the item to add.

What to do for your inventory

Inventory Where the items go Where the pictures go
ox_inventory (ESX, Qbox, ox_core) Paste ox_inventory.lua into ox_inventory/data/items.lua ox_inventory/web/images/
qb-inventory Paste qb-core.lua into qb-core/shared/items.lua qb-inventory/html/images/
ps-inventory, lj-inventory Paste qb-core.lua into qb-core/shared/items.lua your inventory's image folder
qs-inventory Paste qb-core.lua into qb-core/shared/items.lua, or into qs-inventory's own item list your inventory's image folder
codem-inventory, core_inventory, tgiann-inventory, origen_inventory Add the items to its item list the usual way, with the names from qb-core.lua your inventory's image folder
ak47_inventory Add the items, plus the onUse lines below your inventory's image folder
ESX default inventory Run esx.sql on your database not needed
vRP 2 See the vRP section above
Standalone Nothing

For the other inventories in this table, the phone makes the items usable by itself. ox_inventory uses the client = { export = 'phone....' } lines already in its file.

ox_inventory: if you used another phone before, also remove its Item('phone', ...) hook from ox_inventory/modules/items/client.lua.

ak47_inventory keeps item use in each item's own entry. Add these:

-- powerbank
server = { onUse = function(source) exports.phone:UsePowerbank(source) end },
-- pulse_magpack and pulse_magpack_max
server = { onUse = function(source, item) exports.phone:UseMagPack(source, item and item.slot, item and item.name) end },
-- pulse_cable
server = { onUse = function(source) exports.phone:UseChargingCable(source) end },
-- pulse_phone_box
server = { onUse = function(source, item) exports.phone:UseBox(source, item and item.slot) end },

Unique phones (Config.Item.unique = true) put the phone number on the item, so handing over the item hands over the phone. They need ox_inventory, qb-inventory, qs-inventory, core_inventory or codem-inventory.

5. Voice and calls

Start one voice script before the phone. It is found by itself:

Voice script Resource name Calls Speakerphone heard nearby
pma-voice pma-voice yes yes
mumble-voip mumble-voip yes yes
SaltyChat saltychat yes yes
TokoVOIP tokovoip_script yes no
YACA yaca-voice yes yes

Video calls go phone to phone. If a video call only shows the caller's picture, the two players' networks can't connect directly. Add a TURN relay in server.cfg:

set phone_turn_urls       "turn:turn.example.com:3478"
set phone_turn_username   "your-username"
set phone_turn_credential "your-password"

6. Photos and videos

The camera needs screenshot-basic running before the phone.

Out of the box, photos are saved in the phone's media/ folder and served by your server. Photo links must be https. With no phone_media_origin set, the phone uses your server's own https://<name>.users.cfx.re address, which is right for almost everyone. If you set phone_media_origin yourself, it must start with https://.

To keep photos on a CDN instead, add one of these to server.cfg:

# Fivemanage (recommended)
set phone_media_provider   "fivemanage"
set phone_fivemanage_token "YOUR_TOKEN"

# or a Discord webhook (free, but Discord links can expire)
set phone_media_provider  "discord"
set phone_discord_webhook "https://discord.com/api/webhooks/..."

# or your own endpoint (multipart POST that answers with a url)
set phone_media_provider    "custom"
set phone_media_endpoint    "https://cdn.example.com/upload"
set phone_media_field       "file"
set phone_media_auth_header "Authorization"
set phone_media_auth_value  "Bearer xxx"

Uploads go through the server, so players never see your token. With the built-in store, back up media/ along with your database.

7. Other scripts it connects to automatically

Nothing to set up. The start-up line lists what was found. phone:diag shows every script the phone considered and why it used or skipped each one. To force one, set Config.Providers.<area> in config/config.lua to the resource name, or 'none' to switch that area off.

Area Supported scripts
Company accounts Renewed-Banking, qb-banking, qb-management, okokBanking, qs-banking, fd_banking, snipe-banking, tgg-banking, tgiann-bank, wasabi_banking, esx_addonaccount
Bank history in Wallet Renewed-Banking, qb-banking, ps-banking, okokBanking, tgiann-bank, esx_banking
Shared accounts in Wallet Renewed-Banking, qb-banking
Bills in Wallet esx_billing, okokBilling, QBCore's phone_invoices table
Garage app jg-advancedgarages, cd_garage, okokGarage, vms_garagesv2, qs-advancedgarages, qbx_garages, qb-garages, esx_garage, esx_advancedgarage, codem-garage, rcore_garage, loaf_garage
Home app qb-houses, qb-apartments, qbx_properties, qs-housing, loaf_housing, vms_housing, rtx_housing, ps-housing, bcs_housing, nolag_properties, esx_property
Dispatch (Smart 911, Services) ps-dispatch, cd_dispatch, core_dispatch, qs-dispatch, rcore_dispatch, linden_outlawalert. Without one, alerts arrive as phone notifications.
Vehicle keys qbx_vehiclekeys, qb-vehiclekeys, qs-vehiclekeys, Renewed-Vehiclekeys, wasabi_carlock, MrNewbVehicleKeys, vehicles_keys, ak47_vehiclekeys, ak47_qb_vehiclekeys, t1ger_keys, cd_garage and okokGarage keys
Fuel ox_fuel, Renewed-Fuel, lc_fuel, qs-fuelstations, cdn-fuel, ps-fuel, BigDaddy-Fuel, okokGasStation, x-fuel, LegacyFuel
Door locks ox_doorlock, qb-doorlock, cd_doorlock
Jobs your framework's jobs; ps-multijob on QBCore
Interaction ox_target or qb-target for the store clerk and payphones, else an E prompt
Weather and time any weather sync script

Scripts written for other phones (police, EMS, job and boss-menu scripts) keep working when they send mail, texts or notifications through events: the phone answers the common event names other phones use. A script that calls another phone's exports needs one change (see "No such export" in section 11).

8. The most useful settings

All in config/config.lua unless another file is named. Restart the phone after a change.

To change Setting
The open key (F1) Config.Keys.open. Players can also rebind it in GTA: Settings > Key Bindings > FiveM.
Make players carry a phone item Config.Item.required = true (section 4)
The store: on/off, prices, places Config.Store.enabled, Config.Store.phonePrice, Config.Store.locations
The sealed box in the store Config.Store.box
The charging accessories Config.Charging.enabled (false = the old power bank only)
Cars and charging spots charge without the cable Config.Charging.requireCable = false
The battery Config.Battery.enabled
Paid phone plans (Carrier) Config.Carrier.enabled, off by default. Or setr phone_carrier 1 in server.cfg to turn it on.
The language Config.Locale ('en', 'de', 'fr' ...: a file name in config/locales/)
The framework, if two are running Config.Framework (auto, esx, qb, qbox, ox, vrp, standalone, custom)
Phone number format Config.Numbers.format
Service companies and their jobs Config.Services in config/apps.lua
Emergency numbers and responder jobs Config.Emergency in config/apps.lua
Voice script Config.Voice.backend in config/voice.lua

The other keys: Left Alt switches between the phone cursor and looking around (Config.Keys.cursor), Y answers a call and Backspace declines it without taking the phone out (Config.Keys.answer, Config.Keys.decline). Changing a default only affects players who have not bound that key yet.

9. Admin and testing commands

Give your admins the ace first:

add_ace group.admin phone.admin allow
add_principal identifier.license:YOUR_LICENSE group.admin

Run these in the server console, or in game (F8 or chat) with the ace. <id|number> is an online server ID or any phone number.

Command What it does
phone:health Prints the start-up check again.
phone:diag Lists every script the phone considered and why it used or skipped each one.
phone:inspect <id\|number> A summary of one phone: number, mail, created, setup, passcode.
phone:resetpin <id\|number> Removes a forgotten passcode and Face Unlock.
phone:number <id\|number> <newnumber> Gives a phone a new, unused number. Everything moves with it.
phone:wipe <id\|number> confirm Erases a phone's own data and resets it. Without confirm it only says what it would erase.
phonefactoryreset [id] Resets a player's phone to setup.
phone:battery <id> <0-100> Sets a player's battery.
phonecarphotos Photographs every car model for the Garage app (needs screenshot-basic).

Testing on a standalone server. These only work with no framework, where the phone keeps its own jobs, money, cars and homes. [id] defaults to yourself.

Command What it does
phonejobs Lists the jobs and grades. The top grade of each is the boss.
phonesetjob <job> <grade> [id] Sets a job. phonesetjob unemployed 0 clears it.
phoneduty [id] Toggles duty.
phonegivemoney <amount> [id] Adds bank money. society:<job> in place of the id funds a company.
phonegivecar <model> [plate] [id] Adds a car to the phone's garage.
phonegivehouse [label] [id] Gives a home where the player stands.

Quick test: phonesetjob police 4, then open Services to see Your Company. Dial 911 from a second player and choose Police: your phone rings.

10. Updating from an older version

  1. Keep a copy of your old phone folder, and back up your database. Move the old folder out of resources: two phone folders start two phones.
  2. Put the new phone folder in its place.
  3. Copy your old settings files (config/*.lua) over the new ones, but not the config/locales/ folder. Don't delete the new config/ folder first: it may have files yours doesn't.
  4. Copy your files in ownermedia/ back, and your media/ folder if you use the built-in photo store.
  5. Don't copy old bridge/ files back (or server/custom/, client/custom/ from older versions). If you changed one, make the same change in the new file.
  6. Add any new items from config/items/ to your inventory (section 4).
  7. Restart. The database updates itself. Read the start-up check in the console.

Settings your older config.lua doesn't have run on their defaults. To change one, copy that section from the new config/config.lua into yours.

11. Troubleshooting

Start here: read the start-up check in the server console. It is the box that starts with PULSE PHONE by ZeroDev. Every [FAIL] or [WARN] line has its fix on the line below it (-> ...). Type phone:health to print it again and phone:diag for the details.

The phone won't open

What you see Why Fix
F1 does nothing, /phone works Another script uses F1 Rebind in Settings > Key Bindings > FiveM, or change Config.Keys.open. The new default only reaches players who never bound the key.
Nothing opens at all The player has no phone item, the battery is empty, a script disabled the phone, or the player is dead, cuffed or in another blocked state Check Config.Item.required, the battery, and Config.Block states.
Won't open over an inventory or menu On purpose (Config.Open.blockWhenNuiFocused) Close the other menu first.
"No phone item": it opens for nobody Config.Item.required = true but the phone item is missing from your inventory, or players don't carry it Add the phone item (section 4) and give it to players, or set Config.Item.required = false.
Screen blank or white The server side isn't running. F8 shows the server never answered bootstrap - is the resource running server-side? Read the server console for a red [phone] line or an escrow error (below).
Screen blank, console says ui/index.html missing The ui/ folder was removed or not uploaded Upload the full phone folder again. Don't remove ui/.
Cursor stuck in the middle of the screen GTA's raw input is off The player turns on raw input in GTA's settings.

Framework, money and jobs

What you see Why Fix
FRAMEWORK NOT SELECTED: more than one framework is started Two cores are running, for example es_extended and qb-core Set Config.Providers.framework (or Config.Framework) to the one you use. Until then, money features are off.
Config.Framework = "esx" but es_extended is not started The setting names a framework that isn't running Fix the setting, or set it back to 'auto'.
Start-up line says Framework: standalone on a framework server The core has a different resource name, or starts after the phone Start the phone after the framework. A renamed core is not found: use its original name, or connect it as a custom framework (section 3).
Bank balance is 0 or wrong The phone runs standalone (its own bank), or the framework was not found Check the Framework: and Banking: parts of the start-up line.
No company account in Services No company-account script is running, or the player is not a boss Run one from section 7. Boss grades: boss (ESX), isboss (QBCore / Qbox), or bossGrade. On ox_core and vRP there is no company management.
Police or EMS don't get 911 calls Their job names are not in the lists, or they are off duty Add your job names to Config.Services and Config.Emergency in config/apps.lua.
<script> found but not connected That script's version has different exports The phone uses the next option. Update the script, or pick another with Config.Providers.

Database

What you see Why Fix
db: could not create table ... check that the database user may CREATE TABLE The database user can't create tables Give the user CREATE and ALTER rights, or import phone.sql by hand.
db: could not add column ... The user can't ALTER tables As above.
is running but the database did not answer oxmysql runs but can't reach the database Fix mysql_connection_string. The phone retries by itself.
no SQL resource running - storing data in the resource key/value store oxmysql isn't started, or starts after the phone Start oxmysql before the phone.
auth_gssapi_client in the oxmysql log The database user is set to Windows sign-in Switch that user to a password: ALTER USER 'fivem'@'localhost' IDENTIFIED VIA mysql_native_password USING PASSWORD('your-password');

Calls, photos and the handset

What you see Why Fix
Calls connect with no sound, no voice resource No voice script is running Start pma-voice (or another from section 5) before the phone.
No sound, 2 voice resources running Two voice scripts fight over the same channels Run exactly one.
Video call shows only the caller's picture The two players can't connect directly Add a TURN relay (section 5).
Photos don't save, screenshot-basic not started screenshot-basic isn't running Start it before the phone.
Photos save but show broken phone_media_origin is plain http:// Use an https:// address, or remove the setting, or use Fivemanage (section 6).
Handset invisible, a stock phone, or a grey box in the hand The phone's model did not stream. F8 shows the handset model "lumen_phone" did not load. Set sv_enforceGameBuild to 2699 or newer. Upload stream/ again, unchanged.

Store and items

What you see Why Fix
No store clerk The clerk only appears within about 60 m. The store may be off, or your map covers Legion Square Check Config.Store.enabled. Move the counter in Config.Store.locations.
store: the item "pulse_phone_box" ... is not registered in your inventory The box item is missing Add it (section 4). Until then phones are handed over without a box.
No MagPack or cable in the store, or store: the item "pulse_cable" ... The charging items are missing from your inventory Add pulse_magpack, pulse_magpack_max and pulse_cable (section 4), and their pictures.
Items show without a picture The pictures were not copied Copy config/items/images/ into your inventory's image folder.

Other scripts, language and service

What you see Why Fix
A script errors with No such export for another phone It calls another phone's exports, for example exports['<old phone>']:SendMail. Pulse Phone does not copy other phones' exports. Change that call to Pulse Phone's own export (developers/EXPORTS.md), or ask the script's author for a Pulse Phone option. Scripts that use events need nothing.
No such export for phone The phone's folder was renamed Rename it back to phone (below).
Wrong language Config.Locale is set to another language, or the player picked one Set Config.Locale. Each player can choose their own in Settings > General > Language.
Text shows as keys like key.answer An old config/locales/ folder was copied over the new one Use the new locale files. Re-apply your own wording by hand.
Everyone has "No Service" The Carrier is on (Config.Carrier.enabled = true or setr phone_carrier 1), so each phone needs a plan Players buy a plan in the Carrier app. Or turn it off: set enabled = false and remove the setr phone_carrier line.
No signal in some places only Dead zones are on (Config.Coverage.enabled) Check your zones with phone:zone show in game. Emergency calls always work.

Install and version problems

What you see Why Fix
You lack the required entitlement, or an escrow error at start The server's key belongs to a different Cfx.re account than the one that bought Pulse Phone The asset must be owned by the same Cfx.re account as your server key (sv_licenseKey). Download the phone from Keymaster (Granted Assets) on that account. A copy from someone else never runs.
Other scripts or items stop working after renaming the folder Other scripts and the item entries reach the phone as phone (exports.phone, phone.useItem) Keep the folder named phone.
Odd behaviour after an update, your config has no Config.Charging section An old config.lua was copied over Sections it lacks run on defaults. Copy the missing sections from the new config/config.lua, or start from the new file.
An old adapter stops scripts connecting after an update Old bridge/ (or server/custom/) files were copied back Use the new files (section 10).
Two phones start The old phone folder is still somewhere under resources Move it out of resources.

12. Still stuck?

Join our Discord: https://discord.gg/RAjfwbXCqe

Please include the version from the first line of the start-up check (PULSE PHONE by ZeroDev v...), every console line that starts with [phone], any red lines, and the output of phone:diag.

Still stuck?

Post in #pulse-issues (we go through it every week), or open a ticket in #open-a-ticket if it's urgent. Paste the start-up check from your server console.

Open the Discord