Skip to content

How to add license keys to a FiveM script ​

Short answer: put the one-file SunLicense Lua SDK in your resource, read the server owner's key from a convar in server.cfg, check it server-side when the resource starts, and start your features only when SunLicense says yes. A network error is not a no: keep running and check again later. Ship it through Tebex's asset escrow.

lua
-- server/license.lua (server_scripts in fxmanifest.lua)
local resource = GetCurrentResourceName()
local SunLicense = load(LoadResourceFile(resource, 'lib/sunlicense.lua'), '@lib/sunlicense.lua')()
local client = SunLicense.new({ baseUrl = 'https://api.sunlicense.com', token = SunLicenseSettings.apiKey })

client:validate(GetConvar('my_resource_license', ''), { host = serverId() }, function(ok, status, body)
    if status == 400 then -- EXPIRED, REVOKED, TOO_MANY_MACHINES...: body has the code
        print(('^1[%s] License rejected: %s^7'):format(resource, body))
        return
    end
    if not ok then print(('^3[%s] SunLicense unreachable, starting anyway^7'):format(resource)) end
    StartMyFeatures()
end)

The SDK uses FiveM's PerformHttpRequest, so the server never waits for the answer.

Start from the template instead: example-fivem-resource (Lua 5.4, RedM too) has this plus a stable server id, masked keys, re-checks every 6 hours, a sealed server/core.lua that only runs with a valid license, a packaging script for Tebex escrow, tests and CI. All templates.

Or let your AI agent do it: paste the setup prompt into your coding agent.

Free plan: 3 products, 100 licenses, no credit card. Create a free account.

Step by step ​

  1. In the dashboard: a product, a policy (a machine is a server) and an API key, which can only validate. Integrations → Tebex issues a key per package sale and revokes it on a chargeback.
  2. The SDK is one file: copy sunlicense.lua from sunlicense-com/sunlicense-lua to lib/sunlicense.lua. FiveM has no require, so load it with LoadResourceFile as above, server-side only.
  3. The server owner's key goes in server.cfg: set my_resource_license "AX8P-…". Use set, not setr, so it isn't replicated to clients.
  4. Your API key goes into settings.lua at packaging time (the template's scripts/package.sh fills it from your environment), never in git.
  5. Server id: a FiveM resource can only write inside its own folder, so keep one random id there with SaveResourceFile(resource, '.machine-id', id, -1) and reuse it (the template's serverId()).
  6. Results: 200 starts your features, 400 leaves them off with the reason (mask the key in the console), anything else starts them and retries in about 10 minutes (SetTimeout(600000, …)). Re-check every few hours so a revoked key reaches running servers.
  7. Escrow. Upload the resource through Tebex's asset escrow (Cfx.re keymaster) so buyers can't read or edit the check, settings.lua or your code; keep config files you want buyers to edit in escrow_ignore.

Cfx.re and Tebex rules ​

FiveM and RedM run under Rockstar's Creator Platform License Agreement (last updated 10 September 2026). It lets Rockstar name authorized or exclusive e-commerce, payment and marketplace providers and require you to use them; for FiveM that is Tebex, with asset escrow for paid resources, and the list is on fivem.net. Selling your own resources is fine; running a store that resells other creators' resources is one of the prohibited methods (section 3.1). A license check only decides whether your own resource runs on a server, and changes none of this. The agreement and the list of authorized services change from time to time: read both before you list.

Going further ​

Send feedback

Found something broken, or have an idea? It goes straight to our board.

The first line becomes the title.
Images (optional, up to 5: paste, drop or capture)
Check each image before sending, and remove any that show something private.

We also receive this page's address and your browser version.

Ctrl Enter to send