Skip to content

Developer API ​

Integrate RedM Reports with your own resources.

Exports use the folder name

The resource folder is pc_report, so exports are exports.pc_report:... — even though the manifest name is pc_reports. If you rename the folder, every export below changes with it.

Server exports ​

lua
-- Read
local ticket   = exports.pc_report:GetReport(id)                  -- ticket table or nil
local open     = exports.pc_report:GetOpenReports()               -- array of tickets
local byPlayer = exports.pc_report:GetReportsByLicense(license)   -- array of tickets
local staff    = exports.pc_report:IsStaff(src)                   -- boolean

-- Reports
exports.pc_report:SetPriority(id, 'urgent')                       -- returns true/false

-- Player notes
exports.pc_report:AddPlayerNote(license, 'Watch this one', 'System')
local notes = exports.pc_report:GetPlayerNotes(license)           -- array

-- Blocks
exports.pc_report:BlockPlayer(license, 3600, 'Report abuse', 'System')  -- 0 seconds = permanent
exports.pc_report:UnblockPlayer(license)
local blocked = exports.pc_report:IsPlayerBlocked(license)        -- boolean

-- Stats
local one = exports.pc_report:GetStaffStats(staffLicense)         -- { avgRating, reviews }
local all = exports.pc_report:GetStaffStats()                     -- array by staff_name

Client exports ​

lua
exports.pc_report:OpenReports()          -- open the menu (if the player is registered)
local open = exports.pc_report:IsOpen()  -- boolean
exports.pc_report:OpenReport(id)         -- open the menu and jump to a report

Server events ​

Listen with AddEventHandler in any server script.

EventArgs
pcr:reportCreated(ticket)
pcr:reportClaimed(ticket, staffLicense)
pcr:reportUnclaimed(ticket, staffLicense)
pcr:reportClosed(ticket)
pcr:reportReopened(ticket)
pcr:reportDeleted(reportId)
pcr:reportPriorityChanged(ticket, priority)
pcr:playerBlocked(license, expiresAt)
pcr:playerUnblocked(license)
pcr:reviewSubmitted(review)
pcr:mediaUploaded(reportId, mediaItem)
lua
AddEventHandler('pcr:reportCreated', function(ticket)
    print(('New report #%s: %s'):format(ticket.id, ticket.title))
end)

The ticket table ​

Fields available on a ticket:

id, title, description, category, status, priority,
player_info { id, name, license },
reported_player, admin_info,
created_at, closed_at,
tags, anonymous, escalated, resolution,
locationCreated { x, y, z },
nearby_players

Anonymous tickets

On an anonymous report, player_info.name and player_info.id are masked — but license is retained server-side so your own tooling still works. Do not echo the license anywhere a player can see it.

Integration hooks ​

Wire kick and ban into your existing admin or ban system without editing the core:

lua
Config.Integrations.Ban = function(targetSrc, reason, staffSrc)
    exports['your_ban_system']:BanPlayer(targetSrc, reason, staffSrc)
end

Custom report actions ​

Add a tool button that runs your own server-side logic:

lua
Config.ReportActions[#Config.ReportActions + 1] = {
    id = 'jailtime', label = 'Jail 30m', icon = 'fa-clock',
    targets = { 'reported' }, permission = 'punish',
    handler = function(staffSrc, targetSrc, ticket)
        exports['your_jail']:Send(targetSrc, 30)
    end,
}

targets controls which party the button can act on — 'reporter', 'reported', or both. permission is a capability key; pick an existing one rather than inventing a new string, or the gate will never pass.

Handlers run on the server

handler executes server-side, and targetSrc is resolved by the resource — never by the client. Do not add a client-supplied ID into a handler and trust it.

Documentation for RedMorrow. Scripts are licensed per server — redistribution is not permitted.