This guide walks you through the complete process of installing and configuring Agency Phone on your FiveM server. Whether you are running QBCore, ESX, or a fully custom framework, you will find everything you need here — from prerequisites to first boot to fine-tuning the config. For the full technical reference, see the official documentation at docs.agencyg.de/phone.
Prerequisites
Before installing Agency Phone, make sure your server environment meets the following requirements:
- FiveM server artifact: version 6633 or newer (recommended: always keep artifacts up to date)
- Database: MySQL 5.7+ or MariaDB 10.3+, with
oxmysql(recommended) ormysql-asyncinstalled and configured - CFX Keymaster: your server's license key must be registered and active on keymaster.fivem.net
- Framework (optional): QBCore or ESX if you want the deeper framework integration. Not required for standalone operation.
- Active Agency Phone purchase: the resource is delivered via the CFX asset portal after purchase
Step 1 — Purchase and Download
After completing your purchase at the Agency Scripts shop, your license is automatically registered in your CFX account. To download:
- Log into keymaster.fivem.net with the CFX account linked to your purchase.
- Go to Granted Assets and locate agency-phone.
- Click Download to get the latest release zip.
- If you purchased the QBCore or ESX bridge, also download agency-phone-bridge-qb or agency-phone-bridge-esx from the same list.
Step 2 — Folder Structure
Extract the zip file(s). Your resources directory should look like this after extraction:
resources/
[agency]/
agency-phone/
client/
server/
html/
config.lua
fxmanifest.lua
agency-phone-bridge-qb/ (QBCore only)
client/
server/
fxmanifest.lua
The [agency] folder is a category folder (the square brackets tell FiveM it is a resource group). It is not strictly required — you can place agency-phone directly in resources/ — but using category folders keeps things tidy.
Step 3 — Database Setup
Agency Phone creates its own database tables on first launch using the auto-migration system built into oxmysql. You do not need to manually import any SQL files. Simply ensure your database connection is configured in server.cfg:
# server.cfg — database connection string (oxmysql example)
set mysql_connection_string "mysql://user:password@localhost/fivem_db?charset=utf8mb4"
On first server start, Agency Phone will create the following tables: phone_contacts, phone_messages, phone_calls, phone_gallery, phone_social_posts, and phone_settings. If you are using a fresh database, the tables will be created automatically. If migrating from another phone script, ensure there are no name conflicts in your existing schema.
Step 4 — server.cfg Entries
Add the following ensure lines to your server.cfg. Order matters — oxmysql must load before Agency Phone:
# Dependencies
ensure oxmysql
# Agency Phone (standalone or with framework bridge)
ensure agency-phone
# Only add if using QBCore bridge:
# ensure qb-core
# ensure agency-phone-bridge-qb
# Only add if using ESX bridge:
# ensure es_extended
# ensure agency-phone-bridge-esx
If you are running QBCore or ESX, ensure the framework itself loads before the bridge resource, as shown in the comments above. The standalone core (agency-phone) should always be ensured before any bridge resource.
Step 5 — Configuration (config.lua)
Open agency-phone/config.lua in a text editor. This is the primary configuration file and controls almost every aspect of the phone's behavior. Here is a detailed walkthrough of the most important settings:
Config = {}
-- ============================================================
-- FRAMEWORK
-- "standalone" | "qbcore" | "esx"
-- ============================================================
Config.Framework = "standalone"
-- ============================================================
-- PHONE NUMBERS
-- ============================================================
-- Format string for auto-generated numbers. X = random digit.
Config.PhoneNumberFormat = "555-XXXX"
-- Allow players to pay in-game currency to change their number
Config.AllowNumberChange = true
Config.NumberChangeCost = 500 -- default currency (adjust per framework)
-- ============================================================
-- APPS: enable/disable individual apps
-- ============================================================
Config.EnableBankingApp = true
Config.EnableSocialApp = true
Config.EnableGPSApp = true
Config.EnableCameraApp = true
Config.EnableMDT = false -- set true only for LEO servers
Config.EnableNotesApp = true
-- ============================================================
-- MDT (only relevant when Config.EnableMDT = true)
-- ============================================================
-- Jobs that can access the MDT app
Config.MDTJobs = { "police", "sheriff", "highway_patrol" }
-- ============================================================
-- SOCIAL MEDIA
-- ============================================================
-- Rename the social app to match your server's lore
Config.SocialAppName = "Chirper"
-- Max post length in characters
Config.SocialPostMaxLength = 280
-- ============================================================
-- ENCRYPTED MESSAGING
-- Requires players to hold a specific inventory item
-- ============================================================
Config.EncryptedChat = false
Config.EncryptedChatItem = "burner_phone"
-- ============================================================
-- UI
-- ============================================================
-- Default theme: "dark" or "light"
Config.DefaultTheme = "dark"
-- Notification display duration in milliseconds
Config.NotificationDuration = 5000
-- Phone open keybind (FiveM key name)
Config.PhoneKey = "F1"
QBCore-Specific Notes
When using the QBCore bridge (Config.Framework = "qbcore"), the banking app automatically pulls balance and transaction data from the QBCore economy. Job-based app permissions (such as MDT access) use QBCore's native job system — no extra configuration is needed beyond adding the job names to Config.MDTJobs. Phone numbers are stored per-character and tied to the QBCore character identifier.
ESX-Specific Notes
With the ESX bridge (Config.Framework = "esx"), the banking app connects to ESX accounts (default: bank). If your ESX setup uses custom account names, configure them in the bridge's own config.lua. ESX job ranks are respected for MDT access — only the job names need to be listed; all grades within that job gain access automatically unless you configure grade restrictions in the bridge config.
Step 6 — First Boot Verification
Start your server and watch the console output. A successful Agency Phone load looks like this:
[agency-phone] Database tables verified/created — OK
[agency-phone] Framework: standalone
[agency-phone] Loaded 0 contacts, 0 messages (fresh install)
[agency-phone] Resource started successfully — v2.x.x
If you see errors at this stage, check the troubleshooting section below. Once the server is running, connect with a client and press F1 (or your configured phone key) to open the phone. On first use, the phone will prompt the player to set their number if they do not yet have one assigned.
Common Errors and Fixes
Error: "oxmysql is not started"
This means oxmysql is not ensured before agency-phone in your server.cfg. Move the ensure oxmysql line above ensure agency-phone and restart the server.
Error: "Failed to create table phone_contacts — Table already exists"
This is a warning, not a fatal error — it means you are reinstalling over an existing database. The existing data is preserved. You can safely ignore this warning. If you want a clean install, manually drop the phone_* tables in your database first.
Phone UI does not open on keypress
First, check that the resource started without errors in the server console. Second, verify that no other resource is using the same keybind (default: F1). You can change the keybind in config.lua under Config.PhoneKey. Third, check for NUI focus conflicts — if another resource is capturing NUI focus at the same time, the phone may not receive the keypress correctly.
Banking app shows $0 / empty balance
If you are running standalone mode, the banking app uses an internal wallet by default. To connect it to QBCore or ESX economy, you must use the corresponding bridge resource and set Config.Framework correctly. If the bridge is ensured but balance still shows zero, verify that the player's character is fully loaded in the framework before the phone initializes (framework load order in server.cfg).
MDT app not visible for police officers
Confirm that Config.EnableMDT = true in config.lua and that the player's current job name exactly matches one of the entries in Config.MDTJobs. Job name matching is case-sensitive. Use the exact job name string as defined in your framework's job config.
Additional Configuration Options
Agency Phone has many more configuration options beyond what is covered in this guide. Some of the most useful advanced settings include:
Config.MaxContactsPerPlayer— limit the number of contacts a player can store (default: unlimited)Config.GPSUpdateInterval— how frequently the player's location blip updates on shared GPS (milliseconds)Config.SocialPostCooldown— minimum time between social media posts to prevent spam (seconds)Config.AllowAnonCalls— whether players can make calls that hide their number from the recipientConfig.CameraPhotoQuality— NUI screenshot quality level (1–10, affects in-game gallery image size)
The full annotated config file with all options is available in the official documentation at docs.agencyg.de/phone. The documentation is updated with each release and includes version-specific migration notes when settings change.
Keeping Agency Phone Updated
When a new version is released, you will receive a notification in your CFX keymaster account. To update, download the new zip from the Granted Assets page, extract it, and replace the existing agency-phone folder on your server. Always read the update changelog before updating on a live server — it lists any changes to config.lua keys that require your attention. Your database and existing player data are never deleted by an update.

