Server
Server exports
Call from server-side scripts only. Always pass a valid player server id (source).
OpenPlayerPanel
Opens the full player sportsbook (matches, bet slip, history, wallet).
Parameters
source
number
Yes
Player server id
Returns: boolean , true if the event was sent, false if source is invalid.
exports['cdev_bet']:OpenPlayerPanel(source)Example command wrapper
RegisterCommand('sportsbook', function(source)exports['cdev_bet']:OpenPlayerPanel(source)end, false)Example ox_target (server)
exports.ox_target:addBoxZone({coords = vec3(-1193.0, -892.0, 13.0),size = vec3(2, 2, 2),options = {{name = 'cdev_bet_open',label = 'Open sportsbook',onSelect = function(data)exports['cdev_bet']:OpenPlayerPanel(data.source or source)end,},},})OpenAdminPanel
Opens the admin management panel (categories, matches, settle, treasury).
Parameters
source
number
Yes
Player server id
Returns: boolean
Permission: The player still needs the ACE permission configured in BetConfig.ACE.Admin (default: cdev_bet.admin). Without it, the panel opens but bootstrap returns an access error.
ClosePanel
Closes the betting NUI and releases focus for that player.
Parameters
source
number
Yes
Player server id
Returns: boolean
Example close on death
IsPlayerPanelOpen
Checks if the player currently has the betting panel open. Uses the synced state bag cdevBetTablet.
Parameters
source
number
Yes
Player server id
Returns: boolean
Automation Exports
success
boolean
true if the operation completed
message
string
Human-readable English summary (for logs, Discord, your bridge)
code
string
Stable machine code (e.g. match.created, validation.score_not_enabled)
data
table | nil
Payload on success, or extra context on failure (match_id, status, …)
debug
table | nil
Only when BetConfig.Debug = true in config.lua (invoking_resource, timestamp)
Call from server only (another resource’s server script, not from client):
Images: external URL vs local folder
Team logos and banners accept two formats (same as the admin panel):
External URL
https://i.imgur.com/AbCd123.png
Direct HTTPS image link. Prefer i.imgur.com over gallery pages.
Local file
local:eagles.png
File must exist in cdev_bet/images/ (flat folder, no subfolders). Restart cdev_bet after adding files.
Supported extensions: .png, .jpg, .jpeg, .gif, .webp, .avif, .svg, .ico
If logo fields are omitted, BetConfig.DefaultTeamLogoUrl from config.lua is used.
Match lifecycle (automation)
Matches move automatically: scheduled → open → live → waiting_settled → end.
Your bridge only needs to:
Create matches with correct datetimes.
Optionally update score while
live(ifscore_tracking = true).Settle when status is
waiting_settled(afterevent_ends_at).
CreateMatch
Creates a sportsbook card with the same validation as the admin UI.
Parameters
payload
table
Yes
Match fields (see below)
Payload fields
main_category_id
number
Yes
Main category id
sub_category_id
number
Yes
Sub category (must belong to main)
team_home_label
string
Yes
Home team name
team_away_label
string
Yes
Away team name
betting_opens_at
string
Yes
When betting opens (ISO UTC …Z recommended)
event_starts_at
string
Yes
Kickoff / match start
event_ends_at
string
Yes
Real end of competition
team_home_logo_url
string
No
Direct image URL or local:filename.png
team_away_logo_url
string
No
Same as home logo
banner_bg_url
string
No
Card banner
is_featured
boolean
No
Large featured card on player feed
allow_draw
boolean
No
Default true (1-X-2). false = home/away only
score_tracking
boolean
No
Default false. true enables live score exports
Returns: result table — code match.created, data.match_id
Example 1 — Minimal match (default logos, 1-X-2, no live score)
Use when you only care about team names and schedule. Logos fall back to BetConfig.DefaultTeamLogoUrl.
Example 2 — External image URLs (HTTPS)
Use Imgur direct links, your CDN, or any allowed HTTPS host. Good for logos hosted on the web.
Example 3 — Local images from cdev_bet/images/
Copy files into
cdev_bet/images/(e.g.eagles.png,hawks.png,stadium.jpg)Run
restart cdev_beton the serverReference them with the
local:prefix (filename only, no path)
Example 4 — Mixed: one local logo, one URL, no draw (moneyline only)
CreateMatchesBulk
Creates up to 50 matches in one call. Useful for weekly league imports.
Parameters
payloads
table[]
Yes
Array of CreateMatch payloads
Example 1 — Weekly sheet import (mixed payloads)
Example 2 — All local crests (server-owned assets)
Example 3 — Safe re-import (skip if teams already exist)
GetMatch
Returns one decorated match (odds, UI-friendly datetimes, wager counts).
Parameters
matchId
number
Yes
Match id
Example 1 — Read status and odds before placing automation logic
Example 2 — Poll until match is live (then push score)
Example 3 — Invalid id / not found handling
FindMatchByTeams
Finds the latest match(es) by exact team labels (optional sub category filter).
Parameters
homeLabel
string
Yes
Home team name (exact match)
awayLabel
string
Yes
Away team name (exact match)
subCategoryId
number
No
Filter by sub category
limit
number
No
Default 5, max 25
Example 1 — Latest match in a sub category
Example 2 — Search any sub category (broader)
Example 3 — Resolve id from simulator row before settle
ListActiveMatches
Lists matches in scheduled, open, or live.
Example 1 — All active matches on the book
Example 2 — Only one league (sub category)
Example 3 — Discord webhook summary of open games
ListMatchesAwaitingSettlement
Lists matches in waiting_settled (event ended, ready to settle).
Example 1 — Settle every pending match as home win (demo)
Example 2 — Filter by sub category
Example 3 — Build settle queue for external simulator
UpdateMatchScore
Adds or subtracts goals while live + score_tracking enabled at creation.
Parameters
matchId
number
Yes
Match id
side
string
Yes
'home' or 'away'
delta
number
Yes
Integer change (1, -1, …)
Example 1 — Home team scores (+1)
Example 2 — VAR correction (-1 away goal)
Example 3 — Goal-by-goal feed from simulator events
SetMatchScore
Sets absolute score (e.g. simulator sends full time 2-1).
Example 1 — Set full-time score from API
Example 2 — Sync score every 30s while live
Example 3 — Failure when score tracking was not enabled
SettleMatch
Settles the pool and pays winners. Match must be waiting_settled.
Parameters
matchId
number
Yes
Match id
outcome
string
Yes
home, draw, away — also 1, x, 2, w1, w2
Example 1 — Home win
Example 2 — Draw (1-X-2 match)
Example 3 — Away win + map simulator result string
DeleteMatch
Deletes only if open and no bets / pool.
Example 1 — Successful delete (bad import)
Example 2 — Cannot delete (players already bet)
Example 3 — Wrong lifecycle status
CreateMainCategory
Creates a main category and auto-adds a General sub category.
Example 1 — New league
Example 2 — Duplicate name
Example 3 — Setup + create sub in one flow
CreateSubCategory
Creates a sub category under a main category.
Example 1 — Sub with external icon URL
Example 2 — Sub with local icon from images/
Example 3 — Sub without icon (optional)
GetCategoryTree
Returns full tree for mapping simulator → ids.
Example 1 — Print all categories
Example 2 — Resolve sub id by name
Example 3 — Cache tree on resource start
Full league bridge example
End-to-end: categories → create (local images) → live score → settle.
Datetime format
Prefer ISO-8601 UTC with Z suffix:
2026-06-01T20:00:00.000Z
Local YYYY-MM-DDTHH:MM is also accepted.
Order rules
betting_opens_at<event_starts_atevent_starts_at<event_ends_at
Debug mode
In public/shared/config.lua:
Automation exports add debug.invoking_resource and debug.timestamp.
Security note
Exports are server-side only. Any server resource can call them. Restrict in production with a future whitelist if needed.
Last updated