OrigenNetwork
Docs

Exports · origen_phone

All exports are registered under the resource name origen_phone.

Every server export validates its input and returns something checkable (a boolean, an id, a table with ok) instead of failing silently. A badly written resource cannot break anyone's phone.


Server-side exports

Identity

GetPhoneNumber(source) → string|nil

The number of the phone the player has switched on, if they carry one. The inventory is checked again, since the phone may have been taken in the meantime.

lua
local number = exports['origen_phone']:GetPhoneNumber(source)
ParameterTypeDescription
sourcenumberPlayer server ID

GetSourceByNumber(number) → number|nil

The player carrying that number, if online.

lua
local src = exports['origen_phone']:GetSourceByNumber('551234')
ParameterTypeDescription
numberstringPhone number

HasPhoneOpen(source) → boolean

Whether the player has a phone switched on right now.

lua
local online = exports['origen_phone']:HasPhoneOpen(source)
ParameterTypeDescription
sourcenumberPlayer server ID

GetNumbersByCitizenId(citizenid) → string[]

Every number owned by a character, online or not. Useful to write to someone who is not playing.

lua
local numbers = exports['origen_phone']:GetNumbersByCitizenId(citizenid)
ParameterTypeDescription
citizenidstringCharacter identifier

GetDisplayName(number, viewer) → string

How a number appears for a given phone: the name saved in its contacts, or the formatted number.

lua
local name = exports['origen_phone']:GetDisplayName('551234', '601111')
ParameterTypeDescription
numberstringNumber to resolve
viewerstring|nilNumber whose contacts are used. Without it, returns the formatted number

FormatNumber(number) → string

Formats a number with the server format (Config.PhoneNumber.Format).

lua
local formatted = exports['origen_phone']:FormatNumber('551234') -- '55-1234'

Messages and mail

SendMessage(data) → number|false

Sends a text message to a number. from can be a real number or an invented sender such as '900100' so a bank or a workshop can write; if it does not belong to a phone, the message arrives as an unknown number.

lua
exports['origen_phone']:SendMessage({
    to = number,
    from = '5550100',
    message = 'Hello',
})
FieldTypeDescription
tostringRecipient number
fromstring|nilSender. Defaults to Config.Messages.SystemNumber
messagestringMessage text
attachmentstable|nilAttachments

GetEmailAddress(source) → string|nil

The player's email address, or nil if they have not created a mailbox yet.

lua
local address = exports['origen_phone']:GetEmailAddress(source)

GetEmailByNumber(number) → string|nil

The email address linked to a phone number.

lua
local address = exports['origen_phone']:GetEmailByNumber('551234')

SendMail(data) → table

Sends an email. Unlike a message, the sender can be any address even if it does not belong to a phone.

lua
exports['origen_phone']:SendMail({
    sender = 'dealership@ogn.net',
    senderName = 'Premium Deluxe',
    to = exports['origen_phone']:GetEmailAddress(source),
    subject = 'Your invoice',
    body = 'Thank you for your purchase.',
})
FieldTypeDescription
tostringRecipient address
senderstringSender address
senderNamestringSender display name
subjectstringSubject
bodystringBody
attachmentstable|nilAttachments (links)

Returns { ok, delivered, unknown, error }.


Notifications

The data table shared by the notification exports:

FieldTypeDescription
appstringApp the notification is grouped under. Defaults to 'settings'
titlestringTitle
contentstringBody text
avatarstring|nilAvatar URL
thumbnailstring|nilThumbnail URL
datatable|nilExtra data
silentboolean|nilDo not play a sound
actionstable|nilAction buttons

SendNotification(data) → boolean

Notification to a number. Always stored, even if the player is offline or the phone is off.

lua
exports['origen_phone']:SendNotification({
    to = number,
    app = 'bank',
    title = 'Bank',
    content = 'Payment received',
})
FieldTypeDescription
tostringRecipient number

NotifySource(source, data) → number

Notification to a player instead of a number. Reaches every phone they carry; if they carry none, it is stored on the phone in their name. Returns how many phones it reached (0 means the player has no phone).

lua
exports['origen_phone']:NotifySource(source, {
    app = 'services',
    title = 'Dispatch',
    content = '10-13 in Vinewood',
})

NotifyJob(job, data) → number

Notification to every online player with that job. Returns how many players it reached.

lua
exports['origen_phone']:NotifyJob('police', {
    app = 'services',
    title = 'Dispatch',
    content = 'Alarm at the port',
})

NotifyGang(gang, data) → number

Notification to every online player in that gang. Returns how many players it reached.

lua
exports['origen_phone']:NotifyGang('ballas', {
    app = 'darkchat',
    title = 'Meeting',
    content = 'Usual place',
})

NotifyAll(data) → number

Notification to every online player carrying a phone. Returns how many players it reached.

lua
exports['origen_phone']:NotifyAll({
    app = 'news',
    title = 'City Hall',
    content = 'Power cut downtown',
})

ClearNotifications(number, app) → boolean

Deletes the notifications of an app on a phone. Without app, deletes all of them.

lua
exports['origen_phone']:ClearNotifications(number, 'delivery')
ParameterTypeDescription
numberstringPhone number
appstring|nilApp id

Widgets and apps

SetWidgetData(target, widget, data) → boolean

Fills a widget whose source is 'fuera' (business till, radio frequency, work shift). Data is kept for five minutes; after that the widget shows no data again. Pass nil as data to clear it.

lua
exports['origen_phone']:SetWidgetData(source, 'negocio', {
    name = 'Bennys Motorworks',
    caja = 12400,
    empleados = 3,
    stock = 62,
})
ParameterTypeDescription
targetnumber|stringPlayer source or phone number
widgetstring'negocio', 'radio', 'trabajo'...
datatable|nilWidget data

RegisterApp(data) → boolean

Adds an app from another resource. It appears on the home screen and opens its page full screen. It enters the catalogue like any other app, so the admin panel and SetAppRule can restrict it. It is removed automatically when its resource stops.

lua
exports['origen_phone']:RegisterApp({
    id = 'myworkshop',
    name = 'My Workshop',
    icon = 'lucide:wrench',
    url = 'nui://my_workshop/ui/index.html',
    slot = 30,
})
FieldTypeDescription
idstringLowercase letters, numbers and underscores. Must not exist already
namestringDisplay name (max 40 characters)
iconstring|nilIconify icon. Defaults to 'lucide:app-window'
urlstringMust be nui://<resource>/... or https://...
slotnumber|nilHome-screen position
defaultboolean|nilInstalled by default. Defaults to true

UnregisterApp(id) → boolean

Removes an external app without waiting for its resource to stop.

lua
exports['origen_phone']:UnregisterApp('myworkshop')

App access

CanUseApp(source, appId) → boolean

Whether the player can use that app right now.

lua
if exports['origen_phone']:CanUseApp(source, 'bank') then
    -- ...
end

GetAppRule(appId) → table|nil

The rule set on an app: { mode, list }.

lua
local rule = exports['origen_phone']:GetAppRule('bank')

SetAppRule(appId, mode, list) → boolean

Changes who has an app. It stores exactly what the admin panel stores, so the change is visible there and can be undone by hand. Changes reach open phones immediately.

lua
exports['origen_phone']:SetAppRule('bank', 'menos', {
    { kind = 'negocio', id = 'prisoner' },
})
 
exports['origen_phone']:SetAppRule('bank', 'todos')
ParameterTypeDescription
appIdstringApp id
modestring'todos' (everyone), 'nadie' (nobody), 'solo' (only the list), 'menos' (everyone except the list)
listtable[]|nilEntries, only used by solo and menos
EntryMatches
{ kind = 'civiles' }Players with no job and no gang
{ kind = 'bandas' }Anyone in a gang
{ kind = 'negocios' }Anyone with a job
{ kind = 'banda', id = 'ballas' }A specific gang
{ kind = 'negocio', id = 'mechanic' }A specific job

Contacts and content

AddContact(data) → boolean

Adds a contact to someone's phone. Not duplicated if it already exists.

lua
exports['origen_phone']:AddContact({
    owner = number,
    number = '5550100',
    name = 'Mechanic',
})
FieldTypeDescription
ownerstringPhone number that receives the contact
numberstringContact number
namestringContact name
avatarstring|nilAvatar URL

AddPhoto(data) → number|nil

Stores an already uploaded image in a phone's gallery. Returns the photo id.

lua
exports['origen_phone']:AddPhoto({ owner = number, url = 'https://...' })
FieldTypeDescription
ownerstringPhone number
urlstringImage URL
isVideoboolean|nilMarks it as a video

PublishNews(data) → number|nil

Publishes an article in the News app. Returns the article id.

lua
exports['origen_phone']:PublishNews({
    title = 'Headline',
    content = 'What happened',
})
FieldTypeDescription
titlestringTitle
contentstringBody
authorstring|nilAuthor
imagestring|nilImage URL
categorystring|nilCategory
pinnedboolean|nilPin the article

PublishAd(number, data) → number|nil, string|nil

Publishes an ad on the classifieds board in someone's name. Returns the ad id, or nil and an error.

lua
exports['origen_phone']:PublishAd(number, {
    title = 'Car for sale',
    body = 'Low mileage',
    price = 40000,
})
FieldTypeDescription
titlestringTitle
bodystringBody
pricenumber|nilPrice
categorystring|nilOne of Config.Ads.Categories

AddNote(number, title, content) → number|nil

Leaves a note on someone's phone. Returns the note id.

lua
exports['origen_phone']:AddNote(number, 'Reminder', 'Visit the garage')

AddCalendarEvent(number, data) → number|nil

Adds an event to someone's calendar. Returns the event id.

lua
exports['origen_phone']:AddCalendarEvent(number, {
    title = 'Court',
    date = '2026-09-04',
})
FieldTypeDescription
titlestringTitle
notestring|nilNote
datestringDate (YYYY-MM-DD)
timestring|nilTime

CreateDarkRoom(number, name, burn) → string|nil

Creates a DarkChat room and returns its code. The owner must already have a DarkChat alias; otherwise it returns nil.

lua
local code = exports['origen_phone']:CreateDarkRoom(number, 'Harbour crew', 60)
ParameterTypeDescription
numberstringRoom owner
namestringRoom name
burnnumber|nilMinutes until messages self-destruct. 0 never

Bills and fines

Paid from the phone through the Banking bridge.

CreateInvoice(data) → number|nil, string|nil

Issues an invoice. The player pays or refuses it from the Invoices app.

lua
exports['origen_phone']:CreateInvoice({
    to = number,
    amount = 500,
    reason = 'Repair',
    issuer = 'Mechanic',
    issuerAccount = 'mechanic',
})
FieldTypeDescription
tonumber|stringRecipient source or phone number. With the number, it can be issued to an offline player
amountnumberPositive amount
reasonstringReason
issuerstringIssuer name
issuerAccountstring|nilAccount that receives the money. Without it the player is charged and the money goes nowhere
referenceanyYour own id, returned when the bill is paid
dueAtnumber|nilSeconds from now until it is due

CreateFine(data) → number|nil, string|nil

Like an invoice, but it cannot be refused. The money goes to issuerAccount or, if omitted, to Config.FineAccount. Same fields as CreateInvoice.

lua
exports['origen_phone']:CreateFine({
    to = number,
    amount = 250,
    reason = 'Speeding',
    issuer = 'LSPD',
})

GetBills(number, kind, status) → table[]

Bills of a phone.

lua
local bills = exports['origen_phone']:GetBills(number, 'fine', 'pending')
ParameterTypeDescription
numberstringPhone number
kindstring|nil'invoice', 'fine' or nil for both
statusstring|nil'pending', 'paid', 'refused' or 'cancelled'

GetPendingBills(number, kind) → number, number

How many bills are pending and the total amount owed.

lua
local count, total = exports['origen_phone']:GetPendingBills(number)

CancelBill(id) → boolean

Withdraws a bill. Only works while it is still pending.

lua
exports['origen_phone']:CancelBill(billId)

Calls and device

IsInCall(number) → boolean

Whether that number is in a call right now.

lua
local busy = exports['origen_phone']:IsInCall(number)

GetDeviceState(number) → table|nil

What the server knows about a phone.

lua
local state = exports['origen_phone']:GetDeviceState(number)
-- { airplane, dnd, battery, charging, signal }

SetBattery(number, level) → boolean

Sets the battery level of a phone (0 to 100).

lua
exports['origen_phone']:SetBattery(number, 100)

SetCharging(number, charging) → boolean

Marks a phone as charging or not.

lua
exports['origen_phone']:SetCharging(number, true)

Deliveries

CreateSupplyDelivery(data) → number|nil, string|nil

Creates a supply delivery job in the Mandao app. When the courier confirms arrival, the phone calls DeliverOrder(businessId, orderId) on the Business bridge, which puts the goods where they belong. The courier never carries the goods.

lua
local id, err = exports['origen_phone']:CreateSupplyDelivery({
    businessId = 'burgershot',
    orderId = 42,
    label = 'Burger Shot',
    coords = { x = -1193.0, y = -892.0, z = 14.0 },
    items = { { name = 'bread', count = 20 } },
})
FieldTypeDescription
businessIdstringBusiness that receives the order
orderIdanyOrder id passed back to DeliverOrder
labelstringDestination label
coordstableDestination { x, y, z }. Must be a plain table, not a vector3
itemstableGoods, stored as shown to the courier
requesteranyWho requested it
notestring|nilNote for the courier

The goods are picked up at the nearest depot in Config.Delivery.Depots.

Returns nil, 'err_delivery_off' when Config.Delivery.HandleBusinessOrders is off, and nil, 'err_delivery_no_couriers' when no courier is on duty. In both cases the business should deliver the order on its own.


SupplyActive(id) → boolean

Whether a supply delivery is still alive (pending, taken, picked or arrived). An expired or cancelled delivery will never arrive.

lua
local alive = exports['origen_phone']:SupplyActive(deliveryId)

IsCourierOnDuty(number) → boolean

Whether a number is registered as a courier and on duty.

lua
local onDuty = exports['origen_phone']:IsCourierOnDuty(number)

GetCurrentDelivery(number, asCourier) → table|nil

The delivery someone is handling, if any.

lua
local delivery = exports['origen_phone']:GetCurrentDelivery(number, true)
ParameterTypeDescription
numberstringPhone number
asCourierbooleantrue looks it up as courier, false as customer

Vehicles and properties

Normalized from the active Garage and Housing bridges, so callers do not need to know which resource is behind them.

GetVehicles(citizenid) → table[]

lua
local vehicles = exports['origen_phone']:GetVehicles(citizenid)
-- { { plate, model, garage, state, fuel, engine, body, depotPrice } }

GetProperties(citizenid) → table[]

The character's properties: owned and those they have a key to.

lua
local houses = exports['origen_phone']:GetProperties(citizenid)
-- { { id, name, mine, price, kind, keys, where } }

Client-side exports

UsePhoneItem(data, slot)

Opens the phone from an ox_inventory item. Reads the number from the slot metadata, so with two phones the one used is opened.

lua
-- ox_inventory/data/items.lua
client = { export = 'origen_phone.UsePhoneItem' },

UsePhone(item)

Same as UsePhoneItem, for inventories that pass the whole item instead of the slot.

lua
exports['origen_phone']:UsePhone(item)

Open()

Opens the first phone the player carries.

lua
exports['origen_phone']:Open()

Close()

Closes the phone.

lua
exports['origen_phone']:Close()

IsOpen() → boolean

Whether the phone is open.

lua
local open = exports['origen_phone']:IsOpen()

GetNumber() → string|nil

The number of the phone in use.

lua
local number = exports['origen_phone']:GetNumber()

IsInCall() → boolean

Whether the local player is in a call.

lua
local busy = exports['origen_phone']:IsInCall()

ShowNotification(data) → boolean

Shows a phone notification card without storing it: it does not count as unread and opens no app. Respects Custom.ShowNotification.

lua
exports['origen_phone']:ShowNotification({
    app = 'services',
    title = 'Dispatch',
    content = 'Alert in Vinewood',
})
FieldTypeDescription
appstringApp icon. Defaults to 'settings'
titlestringTitle
contentstringBody
avatarstring|nilAvatar URL
thumbnailstring|nilThumbnail URL
silentboolean|nilDo not play a sound

ShowServerNotification(data) → boolean

Echoes a server notification (origen_notify style) on the phone, when Config.ServerNotifications.Enabled is on and the player carries a phone. Returns true when the phone takes over the notification.

lua
local handled = exports['origen_phone']:ShowServerNotification({
    title = 'Bank',
    description = 'You received $40',
    type = 'success',
})
FieldTypeDescription
descriptionstringText (text and content are also accepted)
titlestring|nilTitle. Defaults to the server title
typestring|nilNotification type, filtered by Config.ServerNotifications.Types
appstring|nilIcon. Defaults to the server icon

openManagement()

Opens the admin panel. Used by origen_admin; the permission is checked on the server.

lua
exports['origen_phone']:openManagement()