919PHONE
The Lightest FiveM Phone
The Lightest Price
Product Details
Feature Highlights
22 Built-In Apps — calls, texts, mail, bank, maps, camera, social, marketplace & more
Pay For What You Use — core phone + optional game packs + SDK apps; disable any app in config
Services Dispatch — job calls & texts, worker inbox, call log, ring-like-normal incoming calls
Banking That RP’s — transfers, payment requests, job invoices, balance widget
Live Home Screen — drag-and-drop icons, folders, dock, scroll/swipe pages, live widgets
pma-voice Calling — dialer, history, voicemail, block list, hide caller ID
Messages Done Right — groups by number, read receipts, typing, gallery attachments
Social Stack — Tweeder, Cloutgram stories/posts, Hagglr classifieds, Snitch reviews
Maps & GPS — Atlas / satellite / standard layers, POIs, pins, waypoints, offline-aware
Camera & Gallery — photo + video, landscape mode, FiveManage-backed media everywhere
Lock Screen + Control Center — flashlight, DND, connectivity toggles, music, quick share
Notification Deep Links — tap a banner, land in the exact thread, invoice, or voicemail
Verified Badges — configurable per app for official city accounts & creators
Walk While Open — stay in the world; phone size, frame color, themes, wallpapers
Moderation Built In — reports, blocked words, admin tools, Discord / FiveManage logs
Full Developer SDK — register external apps, iframe isolation, 50 slots, App Store ready
Tech Specs
Truly Drop-In — import SQL, ensure resource, add phone item; framework auto-detects
Framework-Agnostic — QBox, QBCore, ESX, standalone fallback
6+ Inventory Bridges — ox, qs, origen, codem, tgiann, ps + framework default
Svelte 5 + TypeScript — compiled, lean NUI; not a bloated React phone clone
Open Bridge & Locale — customize money, jobs, stats, strings without recompiling
Per-App Toggles — hide apps from home & App Store from config.lua alone
OneSync Ready — built for modern FiveM stacks (ox_lib + oxmysql)
Optional Game Packs — Snake, Flappy, 2048, Block Stack, Brick Breaker, Mine Sweep
Config
---919PHONE shared configuration.
---Loaded on both client and server. Restart the resource after making changes.
---For server-only secrets, see config_s.lua.
Config = {}
-- ── General ───────────────────────────────────────────────────────────────────
---FiveM keybind used to open and close the phone.
---Uses standard FiveM key names (https://docs.fivem.net/docs/game-references/input-mapper-parameter-ids/keyboard/).
Config.OpenKey = 'M'
---When true, players can walk and move while the phone NUI is open.
---When false, movement input is blocked while the phone is open.
Config.AllowWalkingWhileOpen = true
---Phone item requirement. When Enabled is true, the player must carry the configured
---inventory item to open the phone (keybind and usable item both respect this).
Config.PhoneItem = {
---Set to false to allow opening the phone without an inventory item.
Enabled = true,
---Inventory item name. Must match your framework/inventory item definition exactly.
Item = 'phone',
}
---World prop shown in the player's hand during open and call animations.
Config.PhoneProp = {
---Set to false to disable the hand prop entirely.
Enabled = true,
---GTA prop model name.
Model = 'prop_npc_phone_02',
---Ped bone index the prop attaches to (28422 = right hand).
Bone = 28422,
---Local offset from the attachment bone.
Offset = { x = 0.0, y = 0.0, z = 0.0 },
---Local rotation applied after attachment.
Rotation = { x = 0.0, y = 0.0, z = 0.0 },
}
---Phone holding animation profile. Valid values: 'oneHanded', 'twoHanded'.
Config.PhoneAnimation = 'twoHanded'
---When true, the flashlight turns off automatically when the phone is put away.
Config.FlashlightOffOnClose = true
---Maximum distance in meters for sharing a contact with nearby players.
Config.ContactShareRange = 8.0
---Number of consecutive wrong passcode attempts before the lock screen temporarily blocks input.
Config.PasscodeMaxAttempts = 5
---How long the passcode lockout lasts in seconds after too many failed attempts.
Config.PasscodeLockoutDuration = 30
-- ── Admin ─────────────────────────────────────────────────────────────────────
---ACE permission required for admin chat commands (/resetphonepasscode, /resetphonedata).
Config.Admin = {
Ace = 'admin',
}
-- ── Voicemail ─────────────────────────────────────────────────────────────────
Config.Voicemail = {
MaxRecordingSeconds = 60,
MaxMessagesPerPhone = 50,
RetainDays = 30,
}
-- ── Default player settings ───────────────────────────────────────────────────
---Applied when a character's phone row is first created or fully reset by an admin.
---Players can change most of these in the in-game Settings app after setup.
Config.DefaultSettings = {
---UI color scheme. Valid values: 'dark', 'light'.
theme = 'dark',
---When false, the first-run setup wizard is shown on first phone open.
setupCompleted = false,
---Display brightness percentage (0–100).
brightness = 100,
---Master volume percentage (0–100).
volume = 75,
---Default notification sound. Must match a name from Config.Texttones.
texttone = 'Tone 1',
---When true, mutes ringtones and notification sounds.
silentMode = false,
---When true, suppresses most notifications while the phone is locked.
doNotDisturb = false,
---Phone frame size on screen. Valid values: 'small', 'medium', 'large', 'extraLarge'.
phoneSize = 'large',
---Phone bezel color. Valid values: 'black', 'white', 'natural', 'blue', 'pink', 'teal',
---'desert', 'purple', 'neonBlue', 'neonGreen', 'neonPink', 'neonYellow'.
frameColor = 'black',
---Home screen icon entry animation when unlocking or closing an app.
---Valid values: 'bounce', 'drop', 'flip', 'focus', 'none'.
homeIconAnimation = 'bounce',
---Default home/lock screen wallpaper. Use url("./path") for bundled images under web/build/.
wallpaper = 'url("./wallpapers/wallpaper1.jpg")',
---Phone numbers blocked from calling or messaging this character.
blockedNumbers = {},
---When false, outgoing calls appear as "No Caller ID" to recipients.
showCallerID = true,
---Custom voicemail greeting URL on FiveManage. Empty string uses the bundled default.
voicemailGreetingUrl = '',
---FiveManage file id for the custom greeting (used when replacing or resetting).
voicemailGreetingFileId = '',
---Low-stat notification thresholds shown in the Health app and home widget.
healthAlerts = {
---When true, fire a notification when hunger drops below hungerThreshold.
hungerEnabled = true,
---Hunger percentage (0–100) that triggers a low-hunger alert.
hungerThreshold = 25,
---When true, fire a notification when thirst drops below thirstThreshold.
thirstEnabled = true,
---Thirst percentage (0–100) that triggers a low-thirst alert.
thirstThreshold = 25,
---When true, fire a notification when stress rises above stressThreshold.
stressEnabled = true,
---Stress percentage (0–100) that triggers a high-stress alert.
stressThreshold = 75,
},
}
-- ── Services app ──────────────────────────────────────────────────────────────
---Services app UI and behaviour (separate from the job entries in Config.Services).
Config.ServicesApp = {
---When false, the Services list hides how many workers are online (no count in the status badge).
---Call and text actions still require at least one available worker.
ShowOnlineWorkers = false,
}
---Job-linked service entries shown in the Services app. Players can call or text
---workers who are on duty for the matching job and have not disabled that service.
---@type { id: string, label: string, icon: string, color: string, job: string, numbers: string[] }[]
Config.Services = {
---id: unique service identifier used internally.
---label: display name shown in the Services app.
---icon: Font Awesome solid icon name (include the fa- prefix).
---color: hex color used for the service card accent.
---job: framework job name that counts as an on-duty worker for this service.
---numbers: phone numbers displayed to customers for this service.
{ id = 'mechanic', label = 'Mechanic', icon = 'fa-wrench', color = '#ff9f0a', job = 'mechanic', numbers = { '555-MECH' } },
{ id = 'taxi', label = 'Taxi', icon = 'fa-taxi', color = '#ffd60a', job = 'taxi', numbers = { '555-TAXI' } },
{ id = 'ems', label = 'EMS', icon = 'fa-star-of-life', color = '#ff453a', job = 'ambulance', numbers = { '911' } },
{ id = 'police', label = 'Police', icon = 'fa-shield-halved', color = '#0a84ff', job = 'police', numbers = { '911' } },
{ id = 'tow', label = 'Tow Truck', icon = 'fa-truck-pickup', color = '#30d158', job = 'towtruck', numbers = { '555-TOW' } },
}
-- ── App visibility ────────────────────────────────────────────────────────────
---Set any app to false to remove it from all players' phones.
---Disabled apps are hidden from the home screen and cannot be opened.
---App Store apps (tweeder, hagglr, cloutgram, snitch) are also removed from the
---App Store catalog when disabled. Changes apply after a resource restart.
---@type table<string, boolean>
Config.Apps = {
phone = true,
messages = true,
contacts = true,
settings = true,
clock = true,
calendar = true,
camera = true,
photos = true,
notes = true,
appstore = true,
health = true,
weather = true,
calculator = true,
music = true,
maps = true,
banking = true,
mail = true,
tweeder = true,
hagglr = true,
cloutgram = true,
services = true,
snitch = true,
}
-- ── External App SDK ──────────────────────────────────────────────────────────
---Settings for third-party apps registered via exports['amzn_smartphone']:registerApp().
Config.Sdk = {
---Set to false to block all external app registration.
Enabled = true,
---Maximum number of external apps registered at once.
MaxExternalApps = 50,
---Maximum encoded JSON payload size in bytes for fetchNui requests/responses.
MaxFetchPayload = 65536,
---If true, sendAppMessage deliveries are held until the target app is opened.
QueueMessagesWhenClosed = false,
}
---External app ids allowed to register with category = 'default' (always on home screen).
---@type table<string, boolean>
Config.AllowedDefaultApps = {}
-- ── Media ─────────────────────────────────────────────────────────────────────
---Audio and image files must live under web/public/ in the source tree so they are
---copied into web/build/ when you run the release build. Paths below are relative
---to web/build/ as served to the phone NUI.
---Ringtones selectable in Settings and used for incoming calls.
---name: label shown in the Settings picker.
---file: path relative to web/build/.
---@type { name: string, file: string }[]
Config.Ringtones = {
{ name = 'Default', file = 'ringtones/midnight.mp3' },
{ name = 'Classic', file = 'ringtones/oldphone.mp3' },
{ name = 'Office', file = 'ringtones/office.mp3' },
}
---Notification sounds selectable in Settings for texts and app alerts.
---@type { name: string, file: string }[]
Config.Texttones = {
{ name = 'Tone 1', file = 'texttones/texttone1.mp3' },
{ name = 'Tone 2', file = 'texttones/texttone2.mp3' },
{ name = 'Tone 3', file = 'texttones/texttone3.mp3' },
}
---Tracks available in the Music app.
---art is optional; omit it to show the generic music-note placeholder.
---@type { name: string, artist: string, file: string, art?: string }[]
Config.MusicTracks = {
{ name = 'Test Track', artist = '919DESIGN', file = 'music/TestTrack.mp3', art = 'music/TestTrack.png' },
}
---Wallpaper images selectable in Settings.
---@type { name: string, file: string }[]
Config.Wallpapers = {
{ name = 'Colorful I', file = 'wallpapers/wallpaper1.jpg' },
{ name = 'Nature', file = 'wallpapers/wallpaper2.jpg' },
{ name = 'Flowers', file = 'wallpapers/wallpaper3.jpg' },
{ name = 'Colorful II', file = 'wallpapers/wallpaper4.jpg' },
{ name = 'Rain', file = 'wallpapers/wallpaper5.jpg' },
}
-- ── Maps app ──────────────────────────────────────────────────────────────────
---Permanent map pins shown to all players in the Maps app.
---Players can also save personal pins; those persist per character in the database.
---@type { label: string, x: number, y: number, icon?: string, color?: string }[]
Config.MapPins = {
---label: pin name shown in the Maps UI.
---x/y: GTA V world coordinates.
---icon: Font Awesome solid icon name (optional).
---color: hex color for the pin marker (optional).
{ label = 'Hospital', x = 295.9, y = -1446.7, icon = 'fa-hospital', color = '#ff3b30' },
{ label = 'Police HQ', x = 440.4, y = -980.8, icon = 'fa-shield-halved', color = '#0a84ff' },
{ label = 'Airport', x = -1037.0, y = -2738.0, icon = 'fa-plane', color = '#5ac8fa' },
{ label = 'Car Dealer', x = -39.4, y = -1100.0, icon = 'fa-car', color = '#ff9f0a' },
}
-- ── Health app ────────────────────────────────────────────────────────────────
---Controls how often the client checks hunger/thirst/stress and when alerts fire.
---Stat values are read from your framework via modules_editable/bridge/bridge_c.lua.
Config.Health = {
---Milliseconds between background stat checks while the phone is in use.
PollInterval = 5000,
---Seconds before the same alert type can fire again for one player.
AlertCooldown = 120,
---Percentage the stat must recover past its threshold before the alert can re-arm.
RecoveryMargin = 5,
}
-- ── Notes app ─────────────────────────────────────────────────────────────────
---Server-side limits for notes saved per character. Payloads that exceed these are rejected.
Config.Notes = {
---Maximum number of notes stored per character.
MaxCount = 100,
---Maximum characters allowed in a note id or ISO lastModified timestamp.
IdLimit = 64,
---Maximum characters allowed in a note title.
TitleLimit = 120,
---Maximum characters allowed in a note body.
ContentLimit = 10000,
---Maximum characters allowed in the generated preview string.
PreviewLimit = 120,
---Maximum encoded JSON size in bytes for the full notes array.
MaxPayloadSize = 256000,
}
-- ── Calendar app ──────────────────────────────────────────────────────────────
---Server-side limits for calendar events saved per character.
Config.Calendar = {
---Maximum number of events stored per character.
MaxCount = 200,
---Maximum characters allowed in an event id.
IdLimit = 64,
---Maximum characters allowed in an event title.
TitleLimit = 120,
---Maximum characters allowed in the ISO date string.
DateLimit = 40,
---Maximum characters allowed in the formatted time label.
TimeLimit = 40,
---Maximum characters allowed in the hex color string (#RRGGBB).
ColorLimit = 7,
---Maximum encoded JSON size in bytes for the full events array.
MaxPayloadSize = 128000,
}
-- ── Mail app ──────────────────────────────────────────────────────────────────
Config.Mail = {
---Suffix appended to a player's chosen username to form their mail address.
EmailSuffix = '@celltowa.com',
---Maximum characters allowed in a mail subject line.
SubjectLimit = 80,
---Maximum characters allowed in a mail body.
BodyLimit = 2000,
---Minimum seconds between outbound mails sent by the same player.
SendCooldown = 10,
---Number of messages loaded per inbox/sent page in the Mail app.
PageSize = 25,
---Local-part used for system/no-reply senders (e.g. noreply@celltowa.com).
NoReplyName = 'noreply',
---Character identifiers that show a verified badge on inbound mail from their address.
---@type table<string, boolean>
VerifiedIdentifiers = {
['18K5B061'] = true,
},
}
-- ── Hagglr app (classifieds) ──────────────────────────────────────────────────
Config.Hagglr = {
---Minimum seconds between new listings posted by the same player.
PostCooldown = 60,
---Maximum characters allowed in a listing title.
TitleLimit = 80,
---Maximum characters allowed in a listing description.
BodyLimit = 500,
---Maximum characters allowed in the price field text.
PriceLimit = 30,
---When false, players cannot attach photos to listings.
AllowImages = true,
---Number of listings loaded per feed page.
PageSize = 20,
---Minimum seconds before the same player can report the same listing again.
ReportCooldown = 300,
---Character identifiers that show a verified badge on Hagglr listings.
---@type table<string, boolean>
VerifiedIdentifiers = {
['18K5B061'] = true,
},
}
-- ── Banking app ───────────────────────────────────────────────────────────────
Config.Banking = {
---Minimum whole-dollar amount for transfers and payment requests.
TransferMinAmount = 1,
---Maximum open incoming payment requests a character can have at once.
MaxPendingIncoming = 50,
---Maximum open outgoing payment requests a character can have at once.
MaxPendingOutgoing = 20,
---Days after which unpaid payment requests expire automatically.
RequestExpireDays = 30,
---Jobs allowed to send invoices from the Banking app.
---Key = framework job name, value = label shown on the invoice.
---@type table<string, string>
InvoiceJobs = {
mechanic = 'Mechanic',
police = 'Police',
ambulance = 'EMS',
taxi = 'Taxi',
towtruck = 'Tow Truck',
},
}
-- ── Tweeder app (social feed) ─────────────────────────────────────────────────
Config.Tweeder = {
---Minimum seconds between new posts by the same player.
PostCooldown = 30,
---Minimum seconds between replies by the same player.
ReplyCooldown = 15,
---Minimum seconds between like toggles by the same player on the same post.
LikeCooldown = 2,
---Minimum seconds before the same player can report the same post again.
ReportCooldown = 300,
---Maximum characters allowed in a post body.
CharLimit = 280,
---Maximum characters allowed in a reply body.
ReplyCharLimit = 280,
---Number of posts loaded per feed page.
PageSize = 30,
---ACE permission required for in-game post deletion/moderation actions.
ModerateAce = 'admin',
---Lower-case substrings blocked from post and reply text, e.g. { 'badword' }.
BlockedWords = {},
---When false, players cannot attach photos to posts.
AllowImages = true,
---When true, all online players with Tweeder set up get a phone notification for every new post.
NotifyNewPosts = true,
---Character identifiers (framework citizenid / ESX char id) that show a verified badge on Tweeder.
---@type table<string, boolean>
VerifiedIdentifiers = {
['18K5B061'] = true,
},
}
-- ── Cloutgram app (photo social) ─────────────────────────────────────────────
Config.Cloutgram = {
---Minimum seconds between new posts by the same player.
PostCooldown = 30,
---Minimum seconds between comments by the same player.
CommentCooldown = 10,
---Minimum seconds between new stories by the same player.
StoryCooldown = 60,
---Minimum seconds between like toggles by the same player on the same post.
LikeCooldown = 2,
---Minimum seconds before the same player can report the same post again.
ReportCooldown = 300,
---Maximum characters allowed in a post caption.
CaptionLimit = 2200,
---Maximum characters allowed in a profile bio.
BioLimit = 150,
---Maximum characters allowed in a profile website field.
WebsiteLimit = 100,
---Maximum photos/videos attached to a single post.
MaxMediaPerPost = 10,
---Number of posts loaded per feed page.
PageSize = 20,
---How long stories remain visible, in seconds (86400 = 24 hours).
StoryDuration = 86400,
---ACE permission required for in-game moderation actions.
ModerateAce = 'admin',
---Lower-case substrings blocked from captions, bios, and comments.
BlockedWords = {},
---When false, players cannot upload or attach images and videos.
AllowImages = true,
---Character identifiers that show a verified badge on Cloutgram.
---@type table<string, boolean>
VerifiedIdentifiers = {
['18K5B061'] = true,
},
}
-- ── Snitch app (business reviews) ─────────────────────────────────────────────
Config.Snitch = {
---Minimum seconds between reviews posted by the same player.
ReviewCooldown = 60,
---Maximum characters allowed in a review body.
BodyLimit = 1000,
---Number of reviews loaded per page.
PageSize = 20,
---When false, players cannot attach photos to reviews.
AllowImages = true,
---Minimum seconds before the same player can report the same review again.
ReportCooldown = 300,
---Character identifiers that show a verified badge on Snitch reviews.
---@type table<string, boolean>
VerifiedIdentifiers = {
['18K5B061'] = true,
},
---Static business catalog reviewed in the Snitch app. These are config-driven,
---not stored in the database.
---@type { id: string, name: string, category: string, description: string, address?: string, phone?: string, x?: number, y?: number, imageUrl?: string }[]
Businesses = {
---id: unique business identifier used for reviews.
---name: business display name.
---category: grouping label shown in browse filters.
---description: short summary shown on the business detail page.
---address: optional street/area label.
---phone: optional contact number shown in the UI.
---x/y: optional GTA V coordinates for map display.
---imageUrl: optional header image URL.
{ id = 'bennys', name = "Benny's Original Motor Works", category = 'Automotive', description = 'Custom upgrades and repairs in Strawberry.', address = 'Strawberry', phone = '555-BENNY', x = -205.0, y = -1310.0 },
{ id = 'ls_customs', name = 'Los Santos Customs', category = 'Automotive', description = 'Full-service mod shop and paint.', address = 'Burton', phone = '555-MODS', x = -339.0, y = -136.0 },
{ id = 'pillbox', name = 'Pillbox Hill Medical', category = 'Medical', description = 'Emergency care and routine treatment.', address = 'Pillbox Hill', phone = '911', x = 295.9, y = -1446.7 },
{ id = 'mrpd', name = 'Mission Row PD', category = 'Government', description = 'City police headquarters and front desk.', address = 'Mission Row', phone = '911', x = 440.4, y = -980.8 },
{ id = 'upnatom', name = 'Up-n-Atom Burger', category = 'Food', description = 'Classic burgers, shakes, and late-night bites.', address = 'Vinewood Blvd', phone = '555-ATOM', x = 81.0, y = 275.0 },
{ id = 'bean_machine', name = 'Bean Machine', category = 'Food', description = 'Coffee, pastries, and a quiet place to sit.', address = 'Legion Square', phone = '555-BEAN', x = 120.0, y = -1036.0 },
{ id = 'tequi_la', name = 'Tequi-la-la', category = 'Nightlife', description = 'Live music, strong drinks, questionable decisions.', address = 'Vinewood', phone = '555-TEQUI', x = -565.0, y = 276.0 },
{ id = 'vanilla', name = 'Vanilla Unicorn', category = 'Nightlife', description = 'Upscale lounge with nightly entertainment.', address = 'Strawberry', phone = '555-VU', x = 127.0, y = -1298.0 },
{ id = 'pdm', name = 'Premium Deluxe Motorsport', category = 'Retail', description = 'New and used vehicles with financing options.', address = 'Power St', phone = '555-PDM', x = -39.4, y = -1100.0 },
{ id = 'ammunation', name = 'Ammu-Nation Legion', category = 'Retail', description = 'Licensed firearms and accessories.', address = 'Legion Square', phone = '555-AMMO', x = 22.0, y = -1105.0 },
{ id = '247_grove', name = '24/7 Supermarket', category = 'Retail', description = 'Groceries, snacks, and essentials open around the clock.', address = 'Grove St', phone = '555-247', x = -47.0, y = -1758.0 },
{ id = 'airport', name = 'Los Santos International', category = 'Travel', description = 'Flights in and out of the city.', address = 'LSIA', phone = '555-LSIA', x = -1037.0, y = -2738.0 },
},
}
-- ── Camera app ────────────────────────────────────────────────────────────────
Config.Camera = {
---Maximum video recording length in seconds.
MaxVideoDuration = 30,
---Target video encoder bitrate in bits per second for in-game recordings.
VideoBitsPerSecond = 2500000,
}

































