Exports & API Reference
Complete API documentation for Oxide Chat.
Overview
Oxide Chat provides full compatibility with the standard FiveM chat API, plus additional functionality.
Dual Export Names
Both export names work identically:
-- These are equivalent:
exports['oxide-chat']:addMessage(...)
exports['chat']:addMessage(...)The chat export works because Oxide Chat uses provide 'chat' in its manifest.
Client-Side Exports
addMessage(message)
Display a message in chat.
exports['oxide-chat']:addMessage(message)Parameters
| Name | Type | Description |
|---|---|---|
| message | table/string | Message data or simple string |
Message Table Properties
| Property | Type | Description |
|---|---|---|
| args | table | { author, message } or { message } |
| color | table/string | RGB array {r, g, b} or hex string #RRGGBB |
| templateId | string | Chat type for styling |
| chatType | string | Alternative to templateId |
Examples
-- Simple message
exports['oxide-chat']:addMessage('Hello world!')
-- With author
exports['oxide-chat']:addMessage({
args = { 'System', 'Welcome to the server!' }
})
-- With color (RGB)
exports['oxide-chat']:addMessage({
args = { 'Alert', 'Low health!' },
color = { 255, 0, 0 }
})
-- With color (hex)
exports['oxide-chat']:addMessage({
args = { 'Success', 'Transaction complete' },
color = '#00FF00'
})
-- With chat type styling
exports['oxide-chat']:addMessage({
args = { '', 'Server restarting...' },
chatType = 'announcement'
})addSuggestion(name, help, params)
Add a command suggestion to autocomplete.
exports['oxide-chat']:addSuggestion(name, help, params)Parameters
| Name | Type | Description |
|---|---|---|
| name | string | Command name with / prefix |
| help | string | Description text |
| params | table | Array of parameter definitions |
Param Properties
| Property | Type | Description |
|---|---|---|
| name | string | Parameter name |
| help | string | Parameter description |
Example
exports['oxide-chat']:addSuggestion('/pay', 'Pay a player money', {
{ name = 'id', help = 'Player server ID' },
{ name = 'amount', help = 'Amount to pay' }
})addSuggestions(suggestions)
Add multiple suggestions at once.
exports['oxide-chat']:addSuggestions(suggestions)Parameters
| Name | Type | Description |
|---|---|---|
| suggestions | table | Array of suggestion objects |
Example
exports['oxide-chat']:addSuggestions({
{ name = '/job', help = 'Check your current job' },
{ name = '/money', help = 'Check your balance' },
{ name = '/inventory', help = 'Open inventory', params = {} },
})removeSuggestion(name)
Remove a command suggestion.
exports['oxide-chat']:removeSuggestion(name)Parameters
| Name | Type | Description |
|---|---|---|
| name | string | Command name with / prefix |
Example
exports['oxide-chat']:removeSuggestion('/secretcommand')clearChat()
Clear all messages from chat.
exports['oxide-chat']:clearChat()isEnabled()
Check if chat is enabled.
local enabled = exports['oxide-chat']:isEnabled()Returns
| Type | Description |
|---|---|
| boolean | Whether chat is enabled |
setEnabled(enabled)
Enable or disable chat.
exports['oxide-chat']:setEnabled(enabled)Parameters
| Name | Type | Description |
|---|---|---|
| enabled | boolean | Enable/disable chat |
Example
-- Disable chat during cutscene
exports['oxide-chat']:setEnabled(false)
-- Re-enable after cutscene
exports['oxide-chat']:setEnabled(true)getSuggestions()
Get all registered suggestions.
local suggestions = exports['oxide-chat']:getSuggestions()Returns
| Type | Description |
|---|---|
| table | Map of command name to suggestion data |
Server-Side Exports
addMessage(target, message)
Send a message to one or all players.
exports['oxide-chat']:addMessage(target, message)
-- or
exports['oxide-chat']:addMessage(message) -- Broadcasts to allParameters
| Name | Type | Description |
|---|---|---|
| target | number | Player server ID or -1 for all |
| message | table | Message data |
Examples
-- Send to specific player
exports['oxide-chat']:addMessage(source, {
args = { 'Bank', 'You deposited $1,000' },
color = { 0, 255, 0 }
})
-- Broadcast to all players
exports['oxide-chat']:addMessage({
args = { 'Server', 'Maintenance in 5 minutes' },
chatType = 'announcement'
})
-- Using -1 for all
exports['oxide-chat']:addMessage(-1, {
args = { 'Event', 'Double XP is now active!' }
})addSuggestion(target, name, help, params)
Send a command suggestion to a player.
exports['oxide-chat']:addSuggestion(target, name, help, params)Parameters
| Name | Type | Description |
|---|---|---|
| target | number | Player server ID or -1 for all |
| name | string | Command name with / prefix |
| help | string | Description text |
| params | table | Parameter definitions |
removeSuggestion(target, name)
Remove a suggestion for a player.
exports['oxide-chat']:removeSuggestion(target, name)clearChat(target)
Clear chat for one or all players.
exports['oxide-chat']:clearChat(target)Parameters
| Name | Type | Description |
|---|---|---|
| target | number | Player server ID, -1 for all, or nil for all |
addTemplate(id, template)
Register a message template.
exports['oxide-chat']:addTemplate(id, template)Parameters
| Name | Type | Description |
|---|---|---|
| id | string | Template identifier |
| template | string | Template format string |
registerMessageHook(callback)
Register a hook that fires for unregistered slash-command input — text a player types with a leading / that no resource has registered as a command. It runs from the command-fallback path and lets you observe that input and cancel the default "unknown command" handling. It does not run for regular chat messages, /me, /do, PMs, or any registered command.
local hookId = exports['oxide-chat']:registerMessageHook(callback)Parameters
| Name | Type | Description |
|---|---|---|
| callback | function | Hook function |
Returns
| Type | Description |
|---|---|
| number | Hook ID for reference |
See Message Hooks for detailed usage.
GetSetting(key)
Read the current value of a chat setting (a Config key) at runtime. Returns whatever value is live in the server's config table for that key — including any change applied through SetSetting since the server started.
local value = exports['oxide-chat']:GetSetting(key)Parameters
| Name | Type | Description |
|---|---|---|
| key | string | The config key to read (e.g. 'ProximityDistance') |
Returns
| Type | Description |
|---|---|
| any | The current value of Config[key], or nil if the key is not set |
SetSetting(key, value)
Change a chat setting at runtime. The new value is written to Config, saved to the database so it survives a restart, published to connected clients, and any runtime tables that depend on the key are rebuilt immediately.
exports['oxide-chat']:SetSetting(key, value)Parameters
| Name | Type | Description |
|---|---|---|
| key | string | The config key to change (e.g. 'ProximityDistance') |
| value | any | The new value to store for that key |
Returns
| Type | Description |
|---|---|
| boolean | Always true once the change is applied |
Friends & Blocks Exports
Oxide Chat owns a character-based social graph (friends, friend requests, and a personal block list) and exposes it through plain server-side exports so other resources can read and manage it. These are server-side only.
Character IDs
Every function below is keyed by the character identifier — the stable o-link state_id string, not a server ID. To get the character identifier for an online player, use the o-link bridge:
local charId = olink.character.GetIdentifier(src)The tables backing these exports (chat_friends, chat_blocks) are created automatically on first start, and the schema also ships in sql/install.sql.
GetFriends(charId)
Return a character's accepted friends.
local friends = exports['oxide-chat']:GetFriends(charId)| Name | Type | Description |
|---|---|---|
| charId | string | Character identifier |
Returns: table — array of friend character identifiers.
ListRequests(charId)
Return the incoming (pending) friend requests for a character.
local requests = exports['oxide-chat']:ListRequests(charId)Returns: table — array of character identifiers who have requested this character.
ListBlocks(charId)
Return the characters this character has blocked.
local blocks = exports['oxide-chat']:ListBlocks(charId)Returns: table — array of blocked character identifiers.
IsFriend(a, b)
Check whether two characters are friends.
local ok = exports['oxide-chat']:IsFriend(a, b)| Name | Type | Description |
|---|---|---|
| a | string | Character identifier |
| b | string | Character identifier |
Returns: boolean — true if a has b as an accepted friend.
IsBlocked(a, b)
Check whether one character has blocked another.
local ok = exports['oxide-chat']:IsBlocked(a, b)Returns: boolean — true if a has blocked b.
IsBlockedBetween(a, b)
Check whether either character has blocked the other. Useful before delivering a private message.
local blocked = exports['oxide-chat']:IsBlockedBetween(a, b)Returns: boolean — true if a blocked b or b blocked a.
RequestFriend(a, b)
Send a friend request from a to b. If b has already requested a, the friendship is accepted automatically.
local ok = exports['oxide-chat']:RequestFriend(a, b)Returns: boolean — true if the request was sent or auto-accepted, false otherwise (for example if they are already friends or a == b).
AddFriend(a, b)
Force an accepted, mutual friendship between two characters, skipping the request step.
local ok = exports['oxide-chat']:AddFriend(a, b)Returns: boolean — true on success, false if a == b or a value is missing.
AcceptRequest(me, requester)
Accept a pending request that requester sent to me.
local ok = exports['oxide-chat']:AcceptRequest(me, requester)| Name | Type | Description |
|---|---|---|
| me | string | Character accepting the request |
| requester | string | Character who sent the request |
Returns: boolean — true if a matching pending request was accepted.
DenyRequest(me, requester)
Deny/remove a pending request that requester sent to me.
exports['oxide-chat']:DenyRequest(me, requester)Returns: boolean — always true.
RemoveFriend(a, b)
Remove a friendship between two characters (in both directions).
exports['oxide-chat']:RemoveFriend(a, b)Returns: boolean — always true.
BlockChar(a, b)
Have a block b. Blocking also drops any existing friendship between them.
local ok = exports['oxide-chat']:BlockChar(a, b)Returns: boolean — true on success, false if a == b or a value is missing.
UnblockChar(a, b)
Have a unblock b.
exports['oxide-chat']:UnblockChar(a, b)Returns: boolean — always true.
Client Events
chat:addMessage
Display a message.
TriggerEvent('chat:addMessage', {
args = { 'Author', 'Message' },
color = { 255, 255, 255 }
})chat:addSuggestion
Add a suggestion.
TriggerEvent('chat:addSuggestion', '/command', 'Help text', {
{ name = 'param', help = 'Parameter help' }
})chat:addSuggestions
Add multiple suggestions.
TriggerEvent('chat:addSuggestions', {
{ name = '/cmd1', help = 'Command 1' },
{ name = '/cmd2', help = 'Command 2' },
})chat:removeSuggestion
Remove a suggestion.
TriggerEvent('chat:removeSuggestion', '/command')chat:clear
Clear all messages.
TriggerEvent('chat:clear')chatMessage (Legacy)
Legacy event for simple messages.
TriggerEvent('chatMessage', 'Author', { 255, 0, 0 }, 'Message text')Server Events
chat:addMessage
Send from server to client.
TriggerClientEvent('chat:addMessage', source, {
args = { 'Server', 'Welcome!' }
})chat:addSuggestion
Send suggestion to client.
TriggerClientEvent('chat:addSuggestion', source, '/help', 'Show help')chat:addSuggestions
Send multiple suggestions.
TriggerClientEvent('chat:addSuggestions', source, suggestions)chat:removeSuggestion
Remove a suggestion.
TriggerClientEvent('chat:removeSuggestion', source, '/command')chat:clear
Clear client's chat.
TriggerClientEvent('chat:clear', source)
TriggerClientEvent('chat:clear', -1) -- All playersMessage Format
args Array
The args array determines the message format:
-- Two elements: author and message
args = { 'John', 'Hello everyone!' }
-- Output: "John: Hello everyone!"
-- One element: message only
args = { 'System message' }
-- Output: "System message"
-- Empty author
args = { '', 'Pre-formatted message' }
-- Output: "Pre-formatted message"Color Formats
Colors can be specified as RGB arrays or hex strings:
-- RGB array
color = { 255, 128, 0 }
-- Hex string
color = '#FF8000'
-- Nested array (legacy support)
color = {{ 255, 128, 0 }}Chat Types
Apply styling from a chat type defined in Config.ChatChannels:
-- Using templateId
{ templateId = 'announcement' }
-- Using chatType
{ chatType = 'police' }Chat type styling includes:
- Color
- Prefix (e.g., "[LSPD]")
- Italic formatting
Message Hooks
Observe unregistered slash-command input — text a player sends with a leading / that does not match any registered command. These hooks run from the command-fallback path only. They do not fire for regular chat messages, proximity commands (/me, /do), private messages, or any registered command, so they cannot be used to filter or modify ordinary chat.
Registering a Hook
-- Server-side
local hookId = exports['oxide-chat']:registerMessageHook(function(source, author, command)
-- `command` is the raw unregistered input, prefixed with '/'
-- e.g. a player typing "/foobar hello" -> command == "/foobar hello"
return { cancel = true } -- suppress default unknown-command handling
end)Hook Callback Parameters
| Parameter | Type | Description |
|---|---|---|
| source | number | Player server ID |
| author | string | Sender's character name |
| command | string | The unregistered slash-command input, including the leading / |
Hook Return Values
| Return | Effect |
|---|---|
false | Cancel — stop remaining hooks and suppress default handling |
{ cancel = true } | Cancel — stop remaining hooks and suppress default handling |
nil | Take no action; continue to the next hook |
Hook Examples
-- Log unrecognized slash-command attempts for review
exports['oxide-chat']:registerMessageHook(function(source, author, command)
print(('[%s] typed an unknown command: %s'):format(author, command))
end)
-- Silently swallow unregistered commands from muted players
local mutedPlayers = {}
exports['oxide-chat']:registerMessageHook(function(source, author, command)
if mutedPlayers[source] then
return { cancel = true }
end
end)Hook Cleanup
Hooks are automatically removed when their registering resource stops.
Integration Examples
Shop Purchase Notification
-- Server-side
RegisterNetEvent('shop:purchase', function(itemName, price)
local src = source
exports['oxide-chat']:addMessage(src, {
args = { 'Shop', 'Purchased ' .. itemName .. ' for $' .. price },
color = '#00FF00'
})
end)Job-Specific Announcement
-- Server-side (framework-agnostic via o-link)
function AnnounceToJob(jobName, message)
for _, playerId in ipairs(olink.framework.GetPlayers()) do
local job = olink.job.Get(playerId)
if job and job.name == jobName then
exports['oxide-chat']:addMessage(playerId, {
args = { '', message },
chatType = jobName
})
end
end
end
-- Usage
AnnounceToJob('police', '[DISPATCH] 10-90 at Legion Square')Dynamic Suggestion Updates
-- Client-side: Update suggestions based on job (framework-agnostic via o-link)
RegisterNetEvent('olink:client:jobChanged', function(job)
-- Remove old job suggestions
exports['oxide-chat']:removeSuggestion('/oldcommand')
-- Add new job suggestions
if job.name == 'police' then
exports['oxide-chat']:addSuggestion('/cuff', 'Handcuff a player')
exports['oxide-chat']:addSuggestion('/escort', 'Escort a player')
end
end)Temporary Chat Disable
-- Client-side: Disable during cutscene
function StartCutscene()
exports['oxide-chat']:setEnabled(false)
-- ... cutscene code ...
end
function EndCutscene()
exports['oxide-chat']:setEnabled(true)
endCustom Chat Type
Add a custom row to the chat types list — in /chat settings → Messaging → Chat Types, or as a factory default in config/main.lua:
-- Config addition (config/main.lua) — a custom row in Config.ChatChannels
{
command = 'gang', label = 'Gang Radio',
id = 'gang', prefix = 'GANG', color = '#9B59B6',
scope = 'global', restrict = 'none',
}
-- Server-side usage
exports['oxide-chat']:addMessage(source, {
args = { '', gangName .. ' Radio: ' .. message },
chatType = 'gang'
})