Store
Open navigation

FiveM script documentation

Advanced IDs

Permanent employee-issued ID cards and licenses with real photos, an ox_inventory wallet container, a visual card designer, Records Office NPC, and 25 configurable card types.

QBCoreQboxESX LegacyStandalone
Version1.1.1
Dependenciesox_lib, oxmysql, screenshot-basic, ox_inventory (recommended)
SupportDocumentation + Discord

Overview

Authorized employees issue permanent ID cards with a real photo of the recipient. Cards live in a 6-slot wallet container (ox_inventory), persist in MySQL with a unique serial, and are shown to nearby players with a 3D card prop — including through vehicle windows. Includes 25 built-in card types, a visual card designer, a Records Office NPC for self-service purchases and reissues, and a separate forged-documents flow.

Installation

Install the dependencies first, keep the resource folder named exactly iconix-advancedids, and start everything in the right order.

  1. Install and start ox_lib, oxmysql and screenshot-basic, plus your framework and inventory. All three are hard dependencies.
  2. Keep the folder name exactly iconix-advancedids — the supplied item definitions call exports under that name.
  3. Register the inventory items from the install/ folder (see the next section) — these files are merge templates, do not ensure them.
  4. Import install.sql once, or leave AutoCreate enabled and grant the oxmysql account CREATE TABLE for first start. Manual import is preferred on production databases.
  5. Grant issuer access: the government job (grade 0+) or the ACE iconix-advancedids.issue (see Permissions).
  6. Order your server.cfg as shown below, then run the two-player test checklist before going live.
cfg
ensure oxmysql
ensure ox_lib
ensure screenshot-basic
ensure your_framework
ensure your_inventory
ensure iconix-advancedids

Note

Framework and inventory are auto-detected by default (Config.Framework / Config.Inventory = 'auto'). Set them explicitly if compatibility shims confuse detection.

Note

Native ESX inventory and Qbox without ox_inventory cannot receive permanent employee-issued cards — use ox_inventory with those frameworks.

Inventory items

Merge the supplied item definitions into your inventory before first start — the wallet and every card type are items.

  1. ox_inventory: merge install/ox_inventory_items.lua into ox_inventory/data/items.lua (wallet + card types, stack = false).
  2. qb-inventory: merge install/qbcore_items.lua into QBShared.Items (unique = true) and copy the item images into your inventory image folder.
  3. Restart the FULL server after changing ox_inventory items — restarting only this resource does not rebuild the item registry.

Note

If cards stack or the wallet is never created, the item definitions were not merged correctly.

Permissions

Issuing is granted by job name + minimum grade or by ACE; the card designer and unrestricted checks are admin-gated.

cfg
add_ace group.idissuer iconix-advancedids.issue allow
add_principal identifier.license:YOUR_LICENSE group.idissuer
add_ace group.admin iconix-advancedids.admin allow
add_ace group.admin iconix-advancedids.design allow

Note

Defaults: the government job (grade 0+) can issue; QBCore/Qbox god + admin and ESX superadmin + admin get unrestricted /checkid and the designer.

Note

Police, sheriff and ambulance jobs can /checkid nearby players.

Commands

All actions are command- or item-driven; every command name is configurable via Config.Commands.

  • /issueid [player id] [card type]
    issue a permanent card as an authorized employee; photographs the recipient.
  • /idcard [type] [serial]
    view one of your own cards.
  • /showid [type] [serial]
    present a card to nearby players with the 3D prop.
  • /checkid [player id]
    inspect a nearby player's card (authorized jobs; admins unrestricted).
  • /idcards
    open the owned-cards menu.
  • /idadmin
    open the visual card designer (admin/ACE only).

Key configuration

config.lua stays editable (escrow-ignored). The options server owners most often change:

  • Config.IssuerName
    the issuing authority printed on cards.
  • Config.CardTypes
    25 built-in types (identity, license and badge templates); add new types with a config entry plus an item definition.
  • Config.EmployeeIssuing
    issuer jobs/ACEs, 3 m proximity, 30 s photo token, per-type allowlist.
  • Config.Wallet
    wallet item, 6 slots; issuance fails and rolls back rather than dropping cards loose (FallbackToPlayer = false).
  • Config.Issuing
    the Records Office NPC: location, prices, payment account, blip and targeting.
  • Config.Locale
    en, es, fr, de, pt, nl or tr.

Developer API

Server and client exports for integrating your own resources — issue, remove and check cards, read records, and react to issuance events. Server exports must be called server-side.

Note

Card types are the keys of Config.CardTypes: id_card, driver_license, weapon_license, police_badge, ems_badge, and the other built-in or custom entries.

Issuing cards

  • issueCardToPlayer(source, cardType, options)
    give a card item. options: metadata (identity overrides), count, show / showNearby (present the card right after issuing). Returns { ok, cardType, itemName, count, metadata } on success or { ok = false, code, message }. Alias: giveCardToPlayer.
  • giveCardItem(source, cardType, metadata, count)
    positional variant of the same operation. Aliases: giveCard, issueCard.
  • issueOfficialCard(source, cardType, { issuerSource })
    run the full employee flow including the recipient photo; returns { ok, pending = true, token }. Alias: issueOfficialCardToPlayer.
  • startEmployeeIssuance(issuer, recipient, cardType)
    the lower-level equivalent of the employee flow.
  • getCardMetadata(source, cardType, metadata)
    build inventory item metadata for custom flows. getOfficialCardMetadata(source, cardType, metadata) is the official (non-forged) variant.

Checks and removal

  • hasCard(source, cardType)
    true when the player carries the card item. Alias: hasCardItem.
  • hasLicense(source, licenseName)
    check one entry of the player's framework license list.
  • getLicenses(source)
    the full license list as { list, map }.
  • removeCardFromPlayer(source, cardType, count)
    remove cards and fire the removal event. Lower-level: removeCardItem / removeCard.

Card records

  • getCardRecord(serial)
    one persisted card row by serial.
  • getPlayerCardRecords(source)
    all persisted cards owned by the player.
  • setCardStatus(serial, status)
    set 'active', 'revoked' or 'replaced'.
  • validateCardMetadata(metadata)
    hydrate and validate card metadata against the database.

Important

Records are server-only and include the portrait photo — never forward them to clients.

Introspection

  • getCardTypes()
    every configured card type with label, item name and feature flags.
  • getCardConfig(cardType)
    the resolved config entry for one card type.
  • isCardTypeConfigured(cardType)
    whether a card type exists. Alias: isCardConfigured.
  • getCardItemName(cardType)
    the inventory item name behind a card type. Alias: getItemName.
  • getBridgeStatus()
    reports the detected framework, inventory and card access mode.

Presenting cards

  • viewCard(source, cardType, serial)
    show a player their own card. Server-side.
  • showCardToNearby(source, cardType, serial)
    present a card to nearby players with the 3D prop. Aliases: showCard, showNearbyId.
  • showIdCard(cardType, serial)
    client export: show your own card.
  • showNearbyId(cardType, serial)
    client export: present to nearby players.
  • openIdCardMenu()
    client export: open the owned-cards menu. Alias: openMenu.

Events

  • iconix-advancedids:cardIssued
    fires server-side with the result table ({ source, cardType, itemName, count, ... }) for every issuance, including the built-in commands.
  • iconix-advancedids:cardRemoved
    fires server-side with the same shape for every removal.

Example

A minimal server-side integration: issue a card, check possession, and listen for issuance.

lua
-- server-side
local ids = exports['iconix-advancedids']

local result = ids:issueCardToPlayer(source, 'driver_license', {
    show = true -- present the card right after issuing
})
if not result.ok then
    print(result.code, result.message)
end

if ids:hasCard(source, 'weapon_license') then
    -- player carries a weapon license card
end

AddEventHandler('iconix-advancedids:cardIssued', function(card)
    print(('card %s issued to %s'):format(card.cardType, card.source))
end)

Testing checklist

Run the two-player verification from the bundled installation guide before production.

  1. As an authorized employee, run /issueid on a second player — only the recipient should enter the portrait scene.
  2. Confirm the card lands in the wallet (ox_inventory) or personal inventory (qb-inventory) and the hover shows exactly seven fields.
  3. Check /idcard shows the recipient's photo and a row exists in iconix_advancedids_cards.
  4. Reconnect and restart the server — the photo and card must survive both.
  5. Confirm an unauthorized player's /issueid is rejected.

Important

The cards table stores identifiers, identity data and facial photos — treat it as sensitive personal data: restrict database access and protect backups.

FAQ

Common questions

Why did the card go to personal inventory instead of the wallet?

Expected on qb-inventory, which has no nested wallet container. On ox_inventory, make sure the wallet item is registered and has free slot space — issuance fails and rolls back rather than dropping cards loose.

Why is issuance rejected on native ESX or Qbox without ox_inventory?

Intentional: those inventories cannot guarantee the unique card serial stays attached to the delivered item. Use ox_inventory with ESX or Qbox for permanent employee issuance.

Why do my cards stack?

The item definitions were not merged correctly: ox_inventory needs stack = false and qb-inventory needs unique = true. Restart the full server after editing ox_inventory items.

Why does /issueid say I'm not authorized?

Authorization is an exact job name + minimum grade, or one of the configured ACEs. There is no built-in on-duty check — the job name must match exactly.

Why does the photo request expire or fail?

screenshot-basic must be started and named exactly as configured. Keep the JPEG under 1 MB and raise the 30-second token TTL for slow clients.

Why does a transferred card still show the original owner's photo?

By design: a card permanently keeps the photo, name and ID captured at issuance — possession never rewrites the subject. Reissue at the Records Office to update a portrait for future cards.

Ready to install Advanced IDs?

Review the installation checklist, test on staging, then purchase or open a support ticket if your framework stack needs confirmation.

On this page