---
url: https://docs.sunlicense.com/how-to/gmod-addon.md
description: >-
  How to add license keys to a Garry's Mod addon you sell - drop in the one-file
  SunLicense Lua SDK, check the server owner's key from a protected convar once
  the server has loaded, gate your hooks, keep running offline, and follow
  gmodstore's DRM rules.
---

# How to add license keys to a Garry's Mod addon

**Short answer:** copy `sunlicense.lua` into your addon, read the server owner's key from a protected convar, check it
server-side once the server has finished loading (`InitPostEntity`), and only add your hooks when SunLicense says yes.
A network error is not a no: keep running and check again later.

```lua
-- lua/autorun/server/myaddon_license.lua
local SunLicense = include("myaddon/sunlicense.lua")
local licenseCvar = CreateConVar("myaddon_license", "", { FCVAR_ARCHIVE, FCVAR_PROTECTED }, "MyAddon license key")
local client = SunLicense.new({ baseUrl = "https://api.sunlicense.com", token = MYADDON_API_KEY }) -- from your build

hook.Add("InitPostEntity", "MyAddon.License", function()
  client:validate(licenseCvar:GetString(), { host = MyAddon.ServerId() }, function(ok, status, body)
    if status == 400 then -- EXPIRED, REVOKED, TOO_MANY_MACHINES...: body has the code
      MsgC(Color(255, 80, 80), "[MyAddon] License rejected: ", body, "\n")
      return
    end
    if not ok then MsgC(Color(255, 200, 0), "[MyAddon] SunLicense unreachable, starting anyway\n") end
    MyAddon.Start() -- adds your hooks, net receivers and commands
  end)
end)
```

On Garry's Mod the SDK uses the game's `HTTP` function, so the callback runs later and the server never waits for it.

**Or let your AI agent do it:** paste the [setup prompt](https://sunlicense.com/prompt) into Claude Code, Cursor or
Codex in your addon's folder.

Free plan: 3 products, 100 licenses, no credit card. [Create a free account](https://sunlicense.com/start?ref=docs-howto-gmod).

## Step by step

1. **In the dashboard:** a product, a policy (a machine is a game server) and an **API key**, which can only validate.

2. **The SDK is one file:** copy `sunlicense.lua` from [sunlicense-com/sunlicense-lua](https://github.com/sunlicense-com/sunlicense-lua)
   to `lua/myaddon/sunlicense.lua`. Load it server-side only and never `AddCSLuaFile` it, so it isn't sent to players.

3. **Wait for the server.** `HTTP` requests made while the map is still loading can fail; `InitPostEntity` (or a
   `timer.Simple` after it) is the first safe point.

4. **The server owner's key** goes in `server.cfg` (`myaddon_license "AX8P-…"`). `FCVAR_PROTECTED` keeps its value
   from being sent to clients.

5. **Your API key** is written into a generated file by your release script (`MYADDON_API_KEY`), never in git.

6. **Server id:** generate one once and keep it in the data folder, so restarts count as the same machine:

   ```lua
   function MyAddon.ServerId()
     local id = file.Read("myaddon/server_id.txt", "DATA")
     if not id or id == "" then
       id = ("gmod-%08x%08x"):format(math.random(0, 0x7fffffff), os.time())
       file.CreateDir("myaddon")
       file.Write("myaddon/server_id.txt", id)
     end
     return id
   end
   ```

7. **Results:** 200 starts the addon, 400 leaves it off with the [reason](/guide/concepts#validation-result-codes) in
   the console (mask the key), anything else starts it and retries (`timer.Create("MyAddon.Recheck", 600, 1, …)`).
   Re-check every few hours with a repeating timer so a revoked key reaches running servers.

## gmodstore's rules

gmodstore allows DRM and license checks, with conditions in its
[development guidelines](https://gmodstore.com/help/script-submissions/topics/development-guidelines): the submission
reviewers see must contain all the code the addon runs locally (a private, readable version is fine, with the protected
build on the stable branch), obfuscated code needs that readable copy too, and products that depend on an external
service must follow gmodstore's sunsetting policy when you end support. Say in the listing that the addon checks its
license online. Free Workshop addons are free downloads: don't put a license check in those.

## Going further

* [Obfuscation](/guide/obfuscation) for Lua (Prometheus) and [protection](/guide/protection): seal the core of the
  addon so a copy with the check removed has nothing to run.
* Selling on Tebex for FiveM too? See the [FiveM guide](/how-to/fivem-script). More on
  [licensing GMod addons](https://sunlicense.com/for/gmod-addons/).
