Skip to content

Exports ​

All money, item and ownership checks happen on the server. Server exports are trusted callers, so they skip checks like the image host allow-list.

Core ​

server

ExportReturnsDescription
notify(src, n)booleanNotification for one player: { app, title, body, icon?, data?, sound? }
notifyNumber(number, n)booleanSame, for whoever holds that number. false if nobody online has it
notifyAll(n)countEvery player with a loaded phone
push(src, event, data)booleanRaw push to a player's NUI. event = '<area>:<event>'
pushAll(event, data)booleanBroadcast push
getNumber(src)'555-0142' | nil
getNumberByIdentifier(identifier)numberCreated on first use
getSourceByNumber(number)src | nil
getIdentifierByNumber(number)identifier | nil
close(src)Close a player's phone (for example, when a script cuffs them)
registerStoreApp(entry)booleanAdd or replace an App Store entry (see below)

Notification fields ​

FieldNotes
appApp id (≤ 32), default 'system'. Tapping the notification opens this app
title / body≤ 120 / ≤ 600 characters
iconOptional Font Awesome class
dataTable passed to the app as deep-link params when the notification is tapped
soundDefault true
lua
exports.np_phone:notify(src, { app = 'mail', title = 'Bank', body = 'Your loan was approved.' })
exports.np_phone:notifyNumber('555-0142', { app = 'messages', title = 'Tony C.', body = 'Where are you?' })

App Store ​

lua
exports.np_phone:registerStoreApp({
  id = 'racing', name = 'Racing', icon = 'fa-solid fa-flag-checkered', tint = 'violet',
  description = 'Street races', url = 'https://cfx-nui-myracing/web/index.html',
  category = 'app', featured = true,
  -- optional gate
  item = 'racing_tablet', job = 'police', grade = 2, onduty = true,
})

Apps without a web manifest in np_phone (third-party apps) open url in an iframe.

Apps ​

server

ExportAreaDescription
sendMail(srcOrIdentifier, mail)CityMail with optional waypoint or event action buttons
createInvoice(srcOrIdentifier, data)CityBusiness invoice or fine → id
logTransaction(srcOrIdentifier, amount, title, meta)CityAdd a line to the wallet history (signed amount)
groupGetByPlayer(src)City→ groupId, info
groupGetMembers(groupId)→ { src, … }
groupStartJob(groupId, job)Starts a staged job with a Live Activity
groupSetStage(groupId, stage, patch?)
groupSetProgress(groupId, done, total)
groupUpdateJob(groupId, patch)
groupFinishJob(groupId, { payoutEach })Pays every member to bank, plus a transaction log entry
groupNotify(groupId, n)Notifies every member
sendSystemMessage(fromLabel, toNumber, text)CommsRead-only business thread in Messages
addPhoto(srcOrIdentifier, url, meta?)MediaSkips the host allow-list
addNote(srcOrIdentifier, body)Media
addFile(srcOrIdentifier, file)MediaDocument, contract, image, licence or receipt
createContract(src, targetSrc, data)Two-party contract → id. The target gets a "Sign" button
getContract(id)
addCalendarEvent(srcOrIdentifier, event)Social→ event id
lua
exports.np_phone:sendMail(src, {
  sender = 'Lester', subject = 'Job', body = 'Meet me here.',
  actions = { { label = 'Set waypoint', type = 'waypoint', data = { x = 1275.0, y = -1710.0 } } },
})

exports.np_phone:createInvoice(src, { sender = 'LSPD', senderJob = 'police', amount = 350,
  reason = 'Citation #4412 · Speeding', dueAt = os.time() + 3 * 86400 })

exports.np_phone:addFile(src, { type = 'document', title = 'Property Deed — 3671 Whispymound Dr',
  body = 'This deed certifies ...', issuer = 'Dynasty 8 Real Estate' })

Client ​

client

ExportReturnsDescription
open()Open the phone
close()Close the phone
isOpen()boolean
setPose(pose)'text' or 'call' holding animation
ring(opts)booleanRing / peek mode: the phone slides up without focus. false while the phone is open
stopRing(id?)boolean
isRinging()id | nil
isCameraActive()booleanThe camera app is in use
lua
exports.np_phone:ring({ id = 'dispatch', app = 'phone', title = 'Dispatch', subtitle = 'Incoming call',
  openOnAccept = true, timeout = 30000 })

ring callbacks through the export

Phone.ring only accepts onAccept / onDecline when they are Lua functions. Functions passed through an export arrive as callable function-reference tables, so they're currently ignored. The key press is forwarded to the NUI as the push phone:ringKey { id, action } instead.

Internal Lua API ​

Inside np_phone (new apps, bridges), use the Phone.* API directly: Phone.rpc.register, Phone.push, Phone.getPlayer, Phone.fw, Phone.schema, … See Architecture §2–3.

np_* FiveM resources