Installation
Install GKSPHONE V2 — files, inventory items, database, framework, server settings, and start order.
Extract the files
Unzip the download into a [phone] folder inside your server's resources directory.
resources/
└── [phone]/
├── gksphone/
│ ├── config/
│ ├── client/
│ ├── server/
│ └── ...
├── gks-tablet/
├── gksphone_prop/
└── gks-sound/All four ship in the same download. One folder, one ensure [phone] line later.
Add the phone items
The phone is item-gated by default. Two items decide which theme a player gets:
| Item | Opens |
|---|---|
phone | Android interface |
iphone | iOS interface |
Rename them in Config.ItemName if yours differ. To skip items entirely: Config.ItemRequire = false plus Config.DefaultPhoneModel.
powerbank is only needed if you enable charging (ChargeOn, off by default). See Charge.
Watch items
Only needed if you set Config.Watch.ItemRequire = true — it is false out of the box and everyone wears Config.Watch.DefaultModel.
Five plain items, one per case. No metadata and no client export, so the same definition works on every inventory:
| Item | Case |
|---|---|
watch_silver | Aluminium Silver |
watch_black | Midnight |
watch_gold | Gold Stainless |
watch_sport | Sport |
watch_ultra | Ultra Titanium |
["watch_black"] = {
label = "Watch",
weight = 90,
stack = false,
consume = 0,
},Ship only the cases you want. Rename them in Config.Watch.ItemName — the left side is your item, the right side is the model.
Add to qb-core/shared/items.lua:
phone = {
name = 'phone',
label = 'Phone',
weight = 700,
type = 'item',
image = 'phone.png',
unique = true,
useable = true,
shouldClose = true,
combinable = nil,
description = 'Neat phone ya got there'
},
iphone = {
name = 'iphone',
label = 'iPhone',
weight = 1000,
type = 'item',
image = 'iphone.png',
unique = true,
useable = true,
shouldClose = true,
combinable = nil,
description = 'Very expensive phone'
},
-- Only needed if the charging system is enabled
powerbank = {
name = 'powerbank',
label = 'Powerbank',
weight = 200,
type = 'item',
image = 'powerbank.png',
unique = true,
useable = true,
shouldClose = true,
combinable = nil,
description = 'To charge the phone'
},Set up the database
Leave Config.DatabaseAutoSetup = true and the phone creates its tables on first start — skip to the next step.
The tablet is not covered: import gks-tablet/install.sql by hand either way.
Doing it manually instead:
- Drop every existing
gksphone_*table. - Import
gksphone/gksphonev2.sql. - Import
gks-tablet/install.sql.
Skipping step 1 is the most common broken v1 upgrade. Old tables are not migrated, they just fail.
Select your framework
Set Config.Framework in both gksphone/config/config.lua and gks-tablet/config/config.lua.
| Value | Framework | Auto-detected by |
|---|---|---|
auto | Detect at startup (default) | — |
esx | ESX | es_extended started |
qbx | QBox | qbx_core started |
qb | QBCore | qb-core started |
standalone | No framework | fallback when none of the above are found |
auto is right for almost every server. Set it explicitly only if you renamed your framework resource or run two side by side.
Config.Inventory works the same way — see Overview for the accepted values.
Configure the server side
In gksphone/config/serverconfig.lua and gks-tablet/config/serverconfig.lua.
Media service
Photos, videos and voice memos upload to an external host. Pick one and paste its tokens:
-- "fivemanage" | "gksmedia" | "customMedia"
Cfg.MediaService = "fivemanage"
Cfg.AuthTokenImage = "API_TOKEN"
Cfg.AuthTokenAudio = "API_TOKEN"
Cfg.AuthTokenVideo = "API_TOKEN"Leaving these as API_TOKEN is why the camera "does nothing" on a fresh install.
| Service | Notes |
|---|---|
fivemanage | Third-party host, default value |
gksmedia | Our own service — see Media Services |
customMedia | Your own endpoint. Fill in the URL, field name and response path under Cfg.MediaServices.customMedia |
Logging
Pick the service, then paste a Discord webhook against each event you want logged. Leave a key empty to skip that event. For fivemanage, also install fmsdk.
Cfg.LogService = "discord" -- "discord" or "fivemanage"
Cfg.DiscordWebHooks = {
['bank'] = "https://discord.com/api/webhooks/...",
['cryptoBuy'] = "",
['dispatchSendReport'] = "",
['squawkPost'] = "",
-- 48 keys in the file; fill in only the ones you want
}Use a private channel here. The public feed webhooks are a different setting — see Webhooks: public vs. admin.
Video calling has its own setup — see WebRTC.
Add it to server.cfg
Everything the phone reads from must start first:
# Database and framework
ensure oxmysql
ensure es_extended # or qb-core / qbx_core
# Voice
ensure pma-voice
# Anything the phone integrates with
ensure your_inventory
ensure your_banking
ensure your_housing
ensure your_garages
ensure your_eyetarget
# The phone last
ensure [phone]oxmysql must start before the phone, or you get SearchPhoneItems errors — see Common Issues.
Voice defaults to pma-voice. For mumble-voip: Config.PMAVoice = false, Config.UseMumbleVoIP = true.
Start and check
Restart the server, then confirm:
- The console shows the phone starting with no red errors.
gksphone_*tables exist in your database.- F1 or
/phoneopens the phone (Config.OpenPhone,Config.RegisterCommandName). - Taking a photo in the Camera app produces an image.
Anything off: Common Issues.
Updating
Back up what you have
Zip your current gksphone folder and keep it. Copy config/config.lua and config/serverconfig.lua somewhere separate too — you will want to diff them.
Delete the old version
Remove the existing gksphone folder from [phone].
Download the latest build
Grab it from the Cfx.re Portal.
Reapply your config
Compare your saved config.lua and serverconfig.lua against the new ones and merge your changes across. Copying the old files over wholesale will drop any settings added since your last update.
Coming from another phone
Already running LB-Phone? Its data can be moved across — see Migration.
If the server won't start it
Three console errors cover nearly every failed install. All three come from FiveM's escrow system, not from the phone.
Error parsing script @gksphone/server/bank.lua in resource gksphone:
@gksphone/server/bank.lua:1: syntax error near '<\1>'The files arrived damaged. The line number is always 1, and the file it names changes between restarts — that is the tell.
- Use WinSCP, not FileZilla. FileZilla corrupts escrowed files in transit. This is the cause in most cases.
- Upload the
.zipand extract it on the server. Dragging the unpacked folders up file by file drops bytes. - Update your server artifacts. Very old builds cannot read current escrow files.
[svadhesive] Failed to verify protected resource gksphoneThe resource is there but its escrow signature does not check out.
- Restart the server — a
refresh+ensureis not enough for an escrowed resource. - Re-upload the
.zipwhole, then extract server-side. - Check
.fxapis present in the resource folder. It is hidden in some FTP clients, and it is what carries the signature. If it is missing, download the script again from Keymaster.
You lack the required entitlement to use gksphoneThe server is running under a licence key that does not own the phone. Nothing is wrong with the files.
Put the key from the same Cfx.re account that bought GKSPHONE in your server.cfg:
sv_licenseKey "your_key_here"Generate it at keymaster.fivem.net.
- Bought on a different account? Keymaster's asset transfer moves it — once per asset, and it cannot be undone.
- ZAP-Hosting ignores
sv_licenseKeyin the file; set the key in their control panel instead.
Work through the fixes above before opening a ticket — and give a key change up to 30 minutes to propagate, then restart the server fully.


