For the complete documentation index, see llms.txt. This page is also available as Markdown.

API and Exports

This is the supported integration surface for resources that need to control or read src-phone. Client exports are called from a client script; server exports are called from a server script. Internal src-phone:client:* and src-phone:server:* transport events are not public API.

Result conventions

Commands normally return true on success or false, errorCode when validation fails. Read-only exports return the requested value or nil when it is unavailable. Database-backed client reads use a callback because FiveM client exports cannot synchronously wait for a server callback.

local ok, reason = exports['src-phone']:openApp('messages', { number = '555-1234' })
if not ok then
    print(('phone request failed: %s'):format(reason))
end

Client exports

Phone and application control

Export
Parameters
Return
Purpose

openPhone

options?

boolean, error?

Opens the phone. options.appId and options.params can launch an app.

closePhone

none

boolean, error?

Closes the phone and releases its normal focus flow.

togglePhone

none

boolean, error?

Toggles the phone; the boolean is the resulting open state.

isPhoneOpen

none

boolean

Returns current visibility.

getPhoneState

none

table

Returns open, locked, active app, call, airplane and online state.

openApp

appId, params?

boolean, error?

Opens an installed built-in or registered external app.

closeApp

none

boolean

Returns to the phone home screen.

getActiveApp

none

string?

Returns the active app ID.

refreshApp

appId

boolean, error?

Increments that app's refresh key.

isAppInstalled

appId

boolean

Checks the player's installed-app list.

getInstalledApps

none

string[]

Returns installed app IDs.

External application registry

Export
Parameters
Return
Purpose

registerApp

manifest

boolean, error?

Registers an external app owned by the calling resource.

unregisterApp

appId

boolean

Removes an app owned by the calling resource.

isAppRegistered

appId

boolean

Checks the runtime registry.

getRegisteredApps

none

manifest[]

Returns accepted, sanitized runtime manifests.

sendAppEvent

appId, action, payload?

boolean, error?

Delivers a typed event to an external app iframe.

Registration takes metadata from the external resource's root config.lua. See Custom applications for the complete manifest and resource lifecycle.

The owner is always GetInvokingResource(). Re-registering the same ID from the same resource updates it atomically; another resource cannot claim that ID. Registrations are removed automatically when their owner stops.

Registration errors:

Error
Meaning

manifest_must_be_a_table

The manifest is not a Lua table.

unsupported_api_version

apiVersion is missing or unsupported.

invalid_id

The ID fails the length or kebab-case rules.

reserved_id

The ID belongs to a built-in application.

id_already_registered

A different resource already owns the ID.

invalid_name

The display name is empty or longer than 18 Unicode characters.

invalid_ui_page / invalid_icon

An asset is not a safe relative resource path.

invalid_accent_color

The accent is not a six-digit hex color.

invalid_permissions / unsupported_permission

The permissions table is invalid or requests an unsupported capability.

invalid_icon_class

The fallback class contains unsupported characters or is too long.

external_resource_required

The call did not originate from another resource.

resource_not_started

The owner resource is not starting or started.

The external TypeScript app receives the event through the vendored SDK:

Notifications and badges

Export
Parameters
Return

sendNotification

notification

id?, error?

removeNotification

id

boolean, error?

clearNotifications

appId?

boolean, error?

getUnreadNotificationCount

appId?

number

setAppBadge

appId, count

boolean, error?

clearAppBadge

appId

boolean, error?

Notification limits are 80 characters for title, 500 for body, and 1-15 seconds for duration. Pressing a public notification opens appId with params and emits src-phone:client:notificationPressed.

Identity and connectivity

Export
Parameters
Return

getPhoneProfile

callback

boolean, error?

getPhoneNumber

callback

boolean, error?

getMailAddress

callback

boolean, error?

isPhoneAvailable

none

boolean

getConnectivity

none

{ online, airplaneMode }

isOnline

none

boolean

hasInternetAccess

none

boolean

getAirplaneMode

none

boolean

Calls

Export
Parameters
Return

startCall

number, options?

boolean, error?

answerCall

number?

boolean, error?

declineCall

number?

boolean, error?

endCall

number?

boolean, error?

getCallState

none

table?

isInCall

none

boolean

setSpeakerEnabled

enabled

boolean, error?

options.video = true requests a video call. Call state is server-authoritative; a successful request does not guarantee that the receiver is online or accepts the call.

Messages and mail

Export
Parameters
Return

sendMessage

number, message, options?

boolean, error?

openConversation

number

boolean, error?

markConversationRead

number

boolean, error?

getUnreadMessageCount

none

number

sendMail

address, { subject?, body }

boolean, error?

openMail

mailId?

boolean, error?

getUnreadMailCount

none

number

Contacts, pickers, media and location

Export
Parameters
Return

getContacts

callback

boolean, error?

getContactByNumber

number, callback

boolean, error?

addContact

{ name, number, avatar? }

boolean, error?

editContact

id, { name, number }

boolean, error?

deleteContact

id

boolean, error?

openContactPicker

options, callback

boolean, requestId?

openPhotoPicker

options, callback

boolean, requestId?

openLocationPicker

options, callback

boolean, requestId?

openShareSheet

options, callback

boolean, requestId?

openConfirmDialog

options, callback

boolean, requestId?

openCamera

options?

boolean, error?

openGallery

params?

boolean, error?

saveSharedMedia

{ url, mediaType? }, callback

boolean, error?

getCurrentLocation

none

{ street, x, y, z }

setPhoneWaypoint

{ x, y }

boolean, error?

openMap

params?

boolean, error?

shareLocation

number, options?

boolean, error?

stopLocationShare

none

boolean

Pickers are asynchronous. Cancellation and the 60-second timeout both return nil to the callback.

Client lifecycle events

These are local client events. Listen with AddEventHandler; do not send them over the network.

Event
Arguments

src-phone:client:phoneOpened

none

src-phone:client:phoneClosed

none

src-phone:client:appOpened

appId

src-phone:client:appClosed

appId

src-phone:client:connectivityChanged

online

src-phone:client:callStateChanged

callState?

src-phone:client:notificationPressed

{ id, appId, params }

Server exports

Server exports always take an explicit player source when the operation acts on a player. This makes ownership visible at the call site and prevents accidental access through the event sender global.

Identity and state

Export
Parameters
Return

getPhoneNumber

source

string?

getMailAddress

source

string?

getPhoneIdentity

source

table?, error?

getSourceByPhoneNumber

number

number?

getIdentifierByPhoneNumber

number

string?

isPhoneNumberOnline

number

boolean

isPhoneAvailable

source

boolean

getConnectivity

source

table?, error?

getPlayerPhoneState

source

table?

Player UI, notifications and app events

Export
Parameters
Return

openApp

source, appId, params?

boolean, error?

sendNotification

source, notification

boolean, error?

removeNotification

source, id

boolean, error?

clearNotifications

source, appId?

boolean, error?

setAppBadge

source, appId, count

boolean, error?

clearAppBadge

source, appId

boolean, error?

sendAppEvent

source, appId, action, payload?

boolean, error?

Calls, messages and mail

Export
Parameters
Return

requestCall

source, number, options?

boolean, error?

endPlayerCall

source

boolean, error?

getPlayerCallState

source

table?

isNumberBusy

number

boolean

sendMessage

source, number, message, options?

boolean, error?

sendSystemMessage

number, message, options?

boolean, id/error?

getUnreadMessageCount

source

number

sendMail

source, address, data

boolean, error?

sendSystemMail

address, data

boolean, id/error?

sendMailToPlayer

source, data

boolean, id/error?

getUnreadMailCount

source

number

sendMessage and sendMail act as the player and follow the normal player-owned validation path. sendSystemMessage and sendSystemMail create server-authored records and should only be called after the integrating resource has completed its own authorization checks.

Server contact access

Export
Parameters
Return

getContacts

source

contacts, error?

addContact

source, contact

boolean, id/error?

editContact

source, id, contact

boolean, error?

deleteContact

source, id

boolean, error?

Contacts are scoped to the player's active MyCloud account. The exports do not accept an arbitrary account or owner key.

Validation and security boundary

The public API validates IDs, phone numbers, text lengths, URLs, badge ranges, player sources and external manifest ownership. It deliberately does not expose:

  • Bank balance mutations or transfers.

  • Another player's message history, mailbox contents or contacts without an explicit player source.

  • Raw SQL, KV storage or MyCloud owner keys.

  • RTC channels, call routing tables or raw internal network events.

  • Shell DOM access or unrestricted overlay creation.

An export confirms that a request was accepted; it does not replace authorization in the calling resource. Job checks, permissions, prices, inventory changes and rate limits remain the caller's server-side responsibility.

Start order

For an external application, also declare dependency 'src-phone' in its fxmanifest.lua. Registration is client-side and the boilerplate automatically re-registers when src-phone restarts.

Last updated