Skip to Content
OpsKeys

Keys

Configure various keys and API credentials for your FiveM server. Proper key management is essential for security and functionality.

License Key

The FiveM license key is required to run a server. It’s obtained from the Cfx.re Keymaster and identifies your server instance.

Step-by-Step Setup

1. Obtain License Key

  1. Visit keymaster.fivem.net 
  2. Log in with your Cfx.re account
  3. Click “New Server” or select an existing server
  4. Copy the license key (format: xxxxx-xxxxx-xxxxx-xxxxx-xxxxx)

2. Configure License Key

Method 1: Environment Variable (Recommended)

# Set environment variable export sv_licenseKey="your-license-key-here" # Or add to ~/.bashrc or ~/.zshrc for persistence echo 'export sv_licenseKey="your-license-key-here"' >> ~/.bashrc source ~/.bashrc

Method 2: server.cfg

# server.cfg set sv_licenseKey "your-license-key-here"

Method 3: Systemd Service (Production)

# /etc/systemd/system/fivem.service [Unit] Description=FiveM Server After=network.target [Service] Type=simple User=fivem WorkingDirectory=/opt/fivem Environment="sv_licenseKey=your-license-key-here" ExecStart=/opt/fivem/run.sh Restart=always [Install] WantedBy=multi-user.target

3. Verify License Key

Check server console for license validation:

[INFO] License key validated successfully

Troubleshooting Invalid/Expired Keys

Error: “Invalid license key”

Causes:

  • Typo in license key
  • Key revoked or expired
  • Key belongs to different server

Solutions:

  1. Verify Key Format:

    # Check key format (should be 5 groups of 5 characters) echo $sv_licenseKey # Should output: xxxxx-xxxxx-xxxxx-xxxxx-xxxxx
  2. Check Key Status:

    • Visit keymaster.fivem.net 
    • Verify key is active and not revoked
    • Check if key is assigned to correct server IP
  3. Regenerate Key:

    • Delete old key in Keymaster
    • Create new key
    • Update server configuration

Error: “License key expired”

Solution:

  • Keys don’t expire, but can be revoked
  • Check Keymaster for key status
  • Contact Cfx.re support if key was revoked incorrectly

Error: “License key not found”

Causes:

  • Environment variable not set
  • Key not in server.cfg
  • Wrong configuration file

Solution:

# Verify environment variable is set echo $sv_licenseKey # Check server.cfg grep -i "license" /opt/fivem/server.cfg # Test with explicit key ./fxserver +set sv_licenseKey "your-key-here"

Steam API Key

Steam API keys enable Steam authentication and player verification on your server.

Step-by-Step Setup

1. Obtain Steam API Key

  1. Visit Steam Web API Key 
  2. Log in with your Steam account
  3. Enter a domain name (can be any valid domain, e.g., example.com)
  4. Click “Register”
  5. Copy the API key (format: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX)

2. Configure Steam API Key

Method 1: server.cfg

# server.cfg set steam_webApiKey "your-steam-api-key-here"

Method 2: Environment Variable

export steam_webApiKey="your-steam-api-key-here"

3. Enable Steam Authentication

# server.cfg set steam_webApiKey "your-steam-api-key-here" # Require Steam authentication (optional) set sv_enforceGameBuild 2699

Integration Examples

Example 1: Verify Steam ID

-- server.lua AddEventHandler('playerConnecting', function(name, setKickReason, deferrals) local source = source local identifiers = GetPlayerIdentifiers(source) local steamId = nil for _, identifier in ipairs(identifiers) do if string.match(identifier, 'steam:') then steamId = identifier break end end if not steamId then setKickReason('Steam authentication required') CancelEvent() return end -- Use Steam ID for player identification print('Player connecting with Steam ID: ' .. steamId) end)

Example 2: Steam Profile Integration

-- server.lua local function GetSteamProfile(steamId) local apiKey = GetConvar('steam_webApiKey', '') if apiKey == '' then return nil end -- Extract Steam64 ID from identifier local steam64 = string.gsub(steamId, 'steam:', '') steam64 = tonumber(steam64, 16) -- Convert hex to decimal -- Make API request (requires HTTP library) -- This is a simplified example return { steamId = steam64, profileUrl = 'https://steamcommunity.com/profiles/' .. steam64 } end

Troubleshooting Steam Keys

Error: “Invalid Steam API key”

Solutions:

  1. Verify Key Format:

    # Check key is 32 characters echo ${#steam_webApiKey} # Should output: 32
  2. Check Key Status:

  3. Regenerate Key:

    • Delete old key
    • Create new key with same domain
    • Update server configuration

Error: “Steam authentication failed”

Causes:

  • Invalid API key
  • Network issues
  • Steam API downtime

Solutions:

-- Add fallback for Steam authentication AddEventHandler('playerConnecting', function(name, setKickReason, deferrals) local source = source local identifiers = GetPlayerIdentifiers(source) local hasSteam = false for _, identifier in ipairs(identifiers) do if string.match(identifier, 'steam:') then hasSteam = true break end end if not hasSteam then -- Optional: Allow non-Steam players -- Or require Steam setKickReason('Steam authentication required') CancelEvent() end end)

Discord Bot Token

Discord bot tokens enable Discord integration for your server, including player verification, chat bridges, and admin notifications.

Step-by-Step Setup

1. Create Discord Application

  1. Visit Discord Developer Portal 
  2. Click “New Application”
  3. Enter application name (e.g., “My FiveM Server”)
  4. Click “Create”

2. Create Bot

  1. In your application, go to “Bot” section
  2. Click “Add Bot”
  3. Click “Yes, do it!”
  4. Under “Token”, click “Reset Token” or “Copy”
  5. Save the token securely (format: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX)

3. Configure Bot Permissions

  1. Go to “OAuth2” → “URL Generator”
  2. Select scopes: bot
  3. Select bot permissions:
    • Send Messages
    • Read Message History
    • Manage Messages (optional)
    • Embed Links
  4. Copy the generated URL
  5. Open URL in browser to invite bot to your server

4. Configure Bot Token

Method 1: Resource Configuration

Most Discord resources use their own config files:

-- discord-bot/config.lua Config = { token = "your-discord-bot-token-here", guildId = "your-discord-server-id", channelId = "your-channel-id" }

Method 2: Environment Variable

export DISCORD_BOT_TOKEN="your-discord-bot-token-here"

Method 3: server.cfg (if resource supports it)

# Some resources may support this set discord_botToken "your-discord-bot-token-here"

Integration Examples

Example 1: Basic Discord Bot (discord.js)

// discord-bot/index.js const { Client, GatewayIntentBits } = require('discord.js'); const client = new Client({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent ] }); client.once('ready', () => { console.log('Discord bot is ready!'); }); client.on('messageCreate', (message) => { if (message.content === '!serverstatus') { // Query FiveM server status message.reply('Server is online!'); } }); client.login(process.env.DISCORD_BOT_TOKEN);

Example 2: FiveM to Discord Chat Bridge

-- server.lua local discordWebhook = "https://discord.com/api/webhooks/your-webhook-url" -- Send chat message to Discord RegisterCommand('discord', function(source, args, rawCommand) local message = table.concat(args, ' ') local playerName = GetPlayerName(source) -- Send to Discord webhook PerformHttpRequest(discordWebhook, function(err, text, headers) -- Handle response end, 'POST', json.encode({ content = string.format('%s: %s', playerName, message) }), { ['Content-Type'] = 'application/json' }) end, false)

Example 3: Player Join/Leave Notifications

-- server.lua local discordWebhook = "https://discord.com/api/webhooks/your-webhook-url" AddEventHandler('playerConnecting', function(name, setKickReason, deferrals) local source = source local identifiers = GetPlayerIdentifiers(source) -- Send join notification to Discord PerformHttpRequest(discordWebhook, nil, 'POST', json.encode({ embeds = {{ title = "Player Joining", description = string.format("**%s** is connecting to the server", name), color = 3066993 -- Green }} }), { ['Content-Type'] = 'application/json' }) end) AddEventHandler('playerDropped', function(reason) local source = source local name = GetPlayerName(source) -- Send leave notification to Discord PerformHttpRequest(discordWebhook, nil, 'POST', json.encode({ embeds = {{ title = "Player Left", description = string.format("**%s** left the server\nReason: %s", name, reason), color = 15158332 -- Red }} }), { ['Content-Type'] = 'application/json' }) end)

Troubleshooting Discord Keys

Error: “Invalid token”

Solutions:

  1. Verify Token Format:

    # Discord bot tokens are 59+ characters echo ${#DISCORD_BOT_TOKEN} # Should output: 59 or more
  2. Check Token Status:

    • Visit Discord Developer Portal 
    • Go to your application → Bot
    • Verify token is visible (if not, reset it)
    • Check if bot is enabled
  3. Reset Token:

    • In Discord Developer Portal → Bot
    • Click “Reset Token”
    • Copy new token
    • Update all configurations

Error: “Missing permissions”

Solution:

  1. Re-invite bot with correct permissions:

    • Use OAuth2 URL Generator
    • Select required permissions
    • Use new invite URL
  2. Check bot role in Discord server:

    • Ensure bot has necessary permissions
    • Bot role should be above roles it needs to manage

Error: “Webhook expired”

Solution:

  1. Create new webhook:
    • Discord Server → Settings → Integrations → Webhooks
    • Create new webhook
    • Copy webhook URL
    • Update resource configuration

Security Practices

Environment Variables

Best Practice: Always use environment variables for sensitive keys.

Setup

# Create .env file (never commit this!) cat > /opt/fivem/.env << EOF sv_licenseKey=your-license-key steam_webApiKey=your-steam-key DISCORD_BOT_TOKEN=your-discord-token EOF # Secure the file chmod 600 /opt/fivem/.env chown fivem:fivem /opt/fivem/.env

Load Environment Variables

# Load .env in your startup script #!/bin/bash set -a source /opt/fivem/.env set +a ./fxserver

Systemd Service with Environment File

# /etc/systemd/system/fivem.service [Unit] Description=FiveM Server After=network.target [Service] Type=simple User=fivem WorkingDirectory=/opt/fivem EnvironmentFile=/opt/fivem/.env ExecStart=/opt/fivem/run.sh Restart=always [Install] WantedBy=multi-user.target

Key Rotation

Regularly rotate keys to maintain security:

Rotation Schedule

  • License Key: Only if compromised or revoked
  • Steam API Key: Every 6-12 months
  • Discord Bot Token: Every 3-6 months or if compromised

Rotation Process

  1. Generate New Key:

    • Create new key in respective service
    • Copy new key securely
  2. Update Configuration:

    # Update .env file nano /opt/fivem/.env # Or update server.cfg nano /opt/fivem/server.cfg
  3. Test New Key:

    # Restart server systemctl restart fivem # Check logs for errors journalctl -u fivem -f
  4. Revoke Old Key:

    • After confirming new key works
    • Revoke old key in service dashboard

Access Control

File Permissions

# Secure server.cfg chmod 600 /opt/fivem/server.cfg chown fivem:fivem /opt/fivem/server.cfg # Secure .env file chmod 600 /opt/fivem/.env chown fivem:fivem /opt/fivem/.env

Git Ignore

# .gitignore server.cfg .env *.key *.token config.lua

Key Validation Script

Create a script to validate all keys:

#!/bin/bash # validate-keys.sh echo "Validating FiveM keys..." # Check license key if [ -z "$sv_licenseKey" ]; then echo "❌ License key not set" else echo "✅ License key is set" fi # Check Steam API key if [ -z "$steam_webApiKey" ]; then echo "❌ Steam API key not set" else echo "✅ Steam API key is set" fi # Check Discord token if [ -z "$DISCORD_BOT_TOKEN" ]; then echo "❌ Discord bot token not set" else echo "✅ Discord bot token is set" fi

Summary

  • License Key: Required for server operation, set via environment variable or server.cfg
  • Steam API Key: Enables Steam authentication, obtained from Steam Web API
  • Discord Bot Token: Enables Discord integration, created in Discord Developer Portal
  • Security: Always use environment variables, rotate keys regularly, secure file permissions
  • Troubleshooting: Verify key format, check service status, regenerate if needed
Last updated on