Browse docs

Server Exports

Server Exports for the Free Phone custom-app, billing and CrewLink integrations.

All exports

This page documents the supported public integration calls. Client exports must run in a client script and server exports must run in a server script. Internal NUI callbacks and net events are not public APIs.

Keep the resource folder named sky_phone. Validate every returned success value and keep money, permissions, ownership, and other authoritative changes on the server.

Server Exports

Server exports handle custom-app policies, billing, and CrewLink integrations. Do not proxy these exports through an unvalidated RegisterNetEvent.

Custom-app policies

Client definitions and server policies are separate. A client definition cannot grant itself server-side permissions.

AddCustomAppPolicy(definition)

  • Purpose: Registers a server policy owned by the calling resource.
  • Arguments:
    • definition (table): Policy definition.
      • id (string): Matching custom-app ID. Required.
      • permissions (table): Server-approved permissions.
  • Returns: boolean, string?.
server.lua
local registered, error_code = exports["sky_phone"]:AddCustomAppPolicy({
    id = "dispatch-board",
    permissions = {
        "device.storage",
        "notifications",
    },
})

if not registered then
    error(("[my_dispatch] Policy registration failed: %s"):format(error_code))
end

UpdateCustomAppPolicy(definition)

  • Purpose: Replaces the complete policy owned by the calling resource.
  • Arguments:
    • definition (table): Full policy including id and every allowed permission.
  • Returns: boolean, string?.
server.lua
local updated, error_code = exports["sky_phone"]:UpdateCustomAppPolicy({
    id = "dispatch-board",
    permissions = {
        "device.storage",
        "notifications",
        "notifications.critical",
    },
})

if not updated then
    print(("[my_dispatch] Policy update failed: %s"):format(error_code))
end

RemoveCustomAppPolicy(appId)

  • Purpose: Removes a policy owned by the calling resource.
  • Arguments:
    • appId (string): Registered app ID.
  • Returns: boolean, string?.
server.lua
local removed, error_code = exports["sky_phone"]:RemoveCustomAppPolicy("dispatch-board")

if not removed then
    print(("[my_dispatch] Policy removal failed: %s"):format(error_code))
end

GetCustomAppPolicy(appId)

  • Purpose: Reads the normalized server policy for an app.
  • Arguments:
    • appId (string): App ID.
  • Returns: table | nil.
server.lua
local policy = exports["sky_phone"]:GetCustomAppPolicy("dispatch-board")

if policy then
    print("Owner", policy.ownerResource)
    for _, permission in ipairs(policy.permissions or {}) do
        print("Permission", permission)
    end
end

Treat the returned table as a snapshot. Mutating it does not update the registered policy.

HasCustomAppPermission(appId, permission)

  • Purpose: Checks whether a registered policy contains one permission.
  • Arguments:
    • appId (string): App ID.
    • permission (string): Supported permission name.
  • Returns: boolean.
server.lua
local can_store = exports["sky_phone"]:HasCustomAppPermission(
    "dispatch-board",
    "device.storage"
)

if not can_store then
    print("Dispatch Board has no storage permission")
end

GetCustomAppCapabilities()

  • Purpose: Reads the server-side custom-app ABI and policy capabilities.
  • Returns: table.
server.lua
local capabilities = exports["sky_phone"]:GetCustomAppCapabilities()

print("External apps enabled", capabilities.enabled)
print("ABI", capabilities.abiVersion)