FiveM Integration

Connect your FiveM server to CDE CAD for 911 calls, panic alerts, live map tracking, and character synchronization.

Base URL: https://cdecad.com/api/fivem — All FiveM-specific endpoints are prefixed with /api/fivem. LiveMap and character sync endpoints use their own prefixes as documented below.

Getting Started with FiveM Integration

Generating an API Key

To connect your FiveM server to CDE CAD, you need an API key. Generate one from the Admin Panel:

  1. Navigate to Admin Panel in your community dashboard.
  2. Open FiveM Settings.
  3. Click Generate API Key.
  4. Copy the key immediately — it is only shown once.

API Key Format

All FiveM API keys follow the format:

fvm_<64 hex characters>

Example: fvm_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2

Authentication

All authenticated FiveM requests must include the API key in the x-api-key header:

x-api-key: fvm_your_api_key_here
Alternative Authentication: Some legacy scripts may use the livemap key combined with a communityId (your Discord guild ID). While this method is still supported, new integrations should use the fvm_ API key format.

Server Registration

POST /api/fivem/register

Auto-register your FiveM server with CDE CAD. No authentication required — the server is matched to an existing community automatically.

No Auth Required

Request Body

FieldTypeRequiredDescription
serverNamestringYesYour FiveM server name
licensestringYesFiveM server license key
discordIdstringYesDiscord guild ID for community matching
ipstringYesServer IP address
portnumberYesServer port
maxPlayersnumberYesMaximum player slots

Community Matching Priority

The server is matched to a community using the following priority order:

  1. discordId — Matches against the community's Discord guild ID (most reliable).
  2. license — Matches against a previously registered FiveM license.
  3. serverName — Matches against a known server name.

Response

{
  "success": true,
  "communityId": "abc123def456",
  "communityName": "My RP Community",
  "apiKey": "fvm_a1b2c3d4..."
}

Lua Example

PerformHttpRequest('https://cdecad.com/api/fivem/register', function(statusCode, response, headers)
    if statusCode == 200 then
        local data = json.decode(response)
        if data.success then
            print('[CDE CAD] Registered! Community: ' .. data.communityName)
            print('[CDE CAD] API Key: ' .. data.apiKey)
            -- Store the API key for future requests
            Config.ApiKey = data.apiKey
            Config.CommunityID = data.communityId
        end
    else
        print('[CDE CAD] Registration failed: ' .. tostring(statusCode))
    end
end, 'POST', json.encode({
    serverName  = GetConvar('sv_hostname', 'Unknown'),
    license     = GetConvar('sv_licenseKey', ''),
    discordId   = '1200664516858495056',
    ip          = GetConvar('web_baseUrl', '127.0.0.1'),
    port        = GetConvarInt('sv_port', 30120),
    maxPlayers  = GetConvarInt('sv_maxClients', 32)
}), {
    ['Content-Type'] = 'application/json'
})

Server Heartbeat

POST /api/fivem/heartbeat

Send periodic heartbeats to keep your server marked as online in CDE CAD.

Requires x-api-key

Request Body

FieldTypeRequiredDescription
playerCountnumberYesCurrent number of players on the server
serverInfoobjectYesServer metadata
serverInfo.licensestringYesFiveM server license key

Response

{
  "success": true
}

Lua Example

-- Send heartbeat every 60 seconds
Citizen.CreateThread(function()
    while true do
        Citizen.Wait(60000)

        PerformHttpRequest(Config.CadUrl .. '/api/fivem/heartbeat', function(statusCode, response, headers)
            if statusCode == 200 then
                print('[CDE CAD] Heartbeat sent successfully')
            else
                print('[CDE CAD] Heartbeat failed: ' .. tostring(statusCode))
            end
        end, 'POST', json.encode({
            playerCount = #GetPlayers(),
            serverInfo  = {
                license = GetConvar('sv_licenseKey', '')
            }
        }), {
            ['Content-Type'] = 'application/json',
            ['x-api-key']    = Config.ApiKey
        })
    end
end)

911 Calls from FiveM

Rate Limit: 911 calls are limited to 10 requests per minute per community to prevent spam.
POST /api/fivem/911

Create a new 911 call from your FiveM server. The call appears on the dispatch board in real time.

Requires x-api-key

Request Body

FieldTypeRequiredDescription
callTypestringYesType of emergency (e.g., "Robbery", "Shots Fired", "Traffic Stop")
locationstringYesStreet address or area name
callerNamestringNoName of the 911 caller
serverNamestringNoOriginating server name
descriptionstringNoDetailed description of the emergency
coordinatesobjectNoGTA map coordinates
coordinates.xnumberNoX coordinate
coordinates.ynumberNoY coordinate
coordinates.znumberNoZ coordinate
postalstringNoPostal code for the location
communityIdstringNoCommunity ID (resolved from API key if omitted)

Response (201 Created)

{
  "success": true,
  "_id": "665a1b2c3d4e5f6a7b8c9d0e",
  "incidentNumber": "911-20240601-0042",
  "message": "911 call created successfully"
}

Lua Example

function Send911Call(callType, location, description, callerName)
    local playerPed = PlayerPedId()
    local coords    = GetEntityCoords(playerPed)
    local street, _  = GetStreetNameAtCoord(coords.x, coords.y, coords.z)
    local streetName = GetStreetNameFromHashKey(street)

    local payload = json.encode({
        callType    = callType,
        location    = location or streetName,
        callerName  = callerName or GetPlayerName(PlayerId()),
        serverName  = Config.ServerName,
        description = description or '',
        coordinates = {
            x = coords.x,
            y = coords.y,
            z = coords.z
        },
        postal      = GetNearestPostal(coords),  -- your postal resource
        communityId = Config.CommunityID
    })

    PerformHttpRequest(Config.CadUrl .. '/api/fivem/911', function(statusCode, response, headers)
        if statusCode == 201 then
            local data = json.decode(response)
            print('[CDE CAD] 911 call created: ' .. data.incidentNumber)
        else
            print('[CDE CAD] 911 call failed: ' .. tostring(statusCode))
            -- Fallback: try x-payload header for Cloudflare compatibility
            if statusCode == 400 then
                PerformHttpRequest(Config.CadUrl .. '/api/fivem/911', function(sc, res, hdr)
                    if sc == 201 then
                        print('[CDE CAD] 911 call created via x-payload fallback')
                    end
                end, 'POST', '', {
                    ['Content-Type'] = 'application/json',
                    ['x-api-key']    = Config.ApiKey,
                    ['x-payload']    = Base64Encode(payload)
                })
            end
        end
    end, 'POST', payload, {
        ['Content-Type'] = 'application/json',
        ['x-api-key']    = Config.ApiKey
    })
end
POST /api/fivem/public/911-call

Legacy alias for the 911 call endpoint. Accepts the same body and returns the same response. Provided for backward compatibility.

Requires x-api-key

Panic Button

POST /api/fivem/panic

Trigger a panic alert for an officer. This emits a panic-button WebSocket event to all connected dispatchers and officers in the community.

Requires x-api-key

Request Body

FieldTypeRequiredDescription
officerNamestringYesName of the officer triggering panic
officerIdstringNoOfficer badge/unit ID
locationstringNoCurrent location or street name
serverNamestringNoOriginating server name
postalstringNoPostal code for the location
coordinatesobjectNoGTA map coordinates
coordinates.xnumberNoX coordinate
coordinates.ynumberNoY coordinate
coordinates.znumberNoZ coordinate
communityIdstringNoCommunity ID (resolved from API key if omitted)

WebSocket Event Emitted

When a panic is triggered, a panic-button event is emitted to the community's WebSocket room containing the officer name, location, coordinates, and timestamp.

Response

{
  "success": true,
  "message": "Panic alert triggered successfully"
}

Lua Example

function TriggerPanic(officerName, officerId)
    local playerPed  = PlayerPedId()
    local coords     = GetEntityCoords(playerPed)
    local street, _  = GetStreetNameAtCoord(coords.x, coords.y, coords.z)
    local streetName = GetStreetNameFromHashKey(street)

    PerformHttpRequest(Config.CadUrl .. '/api/fivem/panic', function(statusCode, response, headers)
        if statusCode == 200 then
            local data = json.decode(response)
            print('[CDE CAD] Panic triggered: ' .. data.message)
        else
            print('[CDE CAD] Panic failed: ' .. tostring(statusCode))
        end
    end, 'POST', json.encode({
        officerName = officerName,
        officerId   = officerId or 'UNKNOWN',
        location    = streetName,
        serverName  = Config.ServerName,
        postal      = GetNearestPostal(coords),
        coordinates = {
            x = coords.x,
            y = coords.y,
            z = coords.z
        },
        communityId = Config.CommunityID
    }), {
        ['Content-Type'] = 'application/json',
        ['x-api-key']    = Config.ApiKey
    })
end

-- Keybind example: F9 to trigger panic
RegisterKeyMapping('panic_button', 'CAD Panic Button', 'keyboard', 'F9')
RegisterCommand('panic_button', function()
    local name = GetPlayerName(PlayerId())
    TriggerPanic(name, Config.OfficerId)
end, false)

LiveMap (Location Updates)

Important: Location update endpoints accept raw GTA V coordinates. The CDE CAD frontend handles the transformation to map coordinates. Do not convert coordinates before sending them.
POST /api/dispatch/location-update

Update a unit's location on the live dispatch map. Send this periodically (every 5-10 seconds) for each active unit.

Requires X-API-Key header

Request Body

FieldTypeRequiredDescription
unitIdstringYesUnique identifier for the unit
unitNamestringYesDisplay name (e.g., "1-Adam-12")
xnumberYesGTA V X coordinate (raw)
ynumberYesGTA V Y coordinate (raw)
znumberNoGTA V Z coordinate (raw)
headingnumberNoUnit heading / direction (0-360)
jobstringNoUnit job type (e.g., "police", "ems", "fire")
statusstringNoUnit status (e.g., "available", "busy", "en-route")
postalstringNoCurrent postal code
communityIdstringNoCommunity ID (resolved from API key if omitted)

Response

{
  "success": true,
  "message": "Location updated",
  "unitId": "unit_1a2b3c",
  "coordinates": {
      "x": -432.15,
      "y": -29.87
  },
  "postal": "342"
}

Lua Example

-- Send location updates for on-duty officers every 5 seconds
Citizen.CreateThread(function()
    while true do
        Citizen.Wait(5000)

        if isOnDuty then
            local playerPed = PlayerPedId()
            local coords    = GetEntityCoords(playerPed)
            local heading   = GetEntityHeading(playerPed)

            PerformHttpRequest(Config.CADEndpoint, function(statusCode, response, headers)
                if statusCode ~= 200 then
                    print('[LiveMap] Update failed: ' .. tostring(statusCode))
                end
            end, 'POST', json.encode({
                unitId      = Config.UnitId or GetPlayerServerId(PlayerId()),
                unitName    = Config.UnitName or GetPlayerName(PlayerId()),
                x           = coords.x,
                y           = coords.y,
                z           = coords.z,
                heading     = heading,
                job         = PlayerJob or 'police',
                status      = DutyStatus or 'available',
                postal      = GetNearestPostal(coords),
                communityId = Config.CommunityID
            }), {
                ['Content-Type'] = 'application/json',
                ['X-API-Key']    = Config.APIKey
            })
        end
    end
end)
GET /api/dispatch/locations

Retrieve all active unit locations for a community. Useful for building custom map displays or checking which units are being tracked.

Requires API Key

Query Parameters

ParameterTypeRequiredDescription
communityIdstringYesThe community to retrieve locations for

Response

[
  {
    "unitId": "unit_1a2b3c",
    "unitName": "1-Adam-12",
    "x": -432.15,
    "y": -29.87,
    "z": 39.12,
    "heading": 180.5,
    "job": "police",
    "status": "available",
    "postal": "342",
    "lastUpdate": "2024-06-01T12:34:56.789Z"
  },
  {
    "unitId": "unit_4d5e6f",
    "unitName": "Medic-3",
    "x": 310.22,
    "y": -590.88,
    "z": 43.29,
    "heading": 90.0,
    "job": "ems",
    "status": "en-route",
    "postal": "128",
    "lastUpdate": "2024-06-01T12:34:52.123Z"
  }
]

Character Sync (FiveM-specific)

Character sync endpoints allow you to push and pull civilian data between your FiveM server and CDE CAD. This keeps character records, vehicles, and identities in sync with the CAD database.

POST /api/civilian/fivem-sync-character

Create or update a civilian record from FiveM. If a civilian with the same SSN exists, it will be updated; otherwise, a new record is created.

Requires API Key

Request Body

Send the full civilian data object. Fields may include:

FieldTypeDescription
firstNamestringCivilian first name
lastNamestringCivilian last name
ssnstringSocial Security Number (unique identifier)
dateOfBirthstringDate of birth (YYYY-MM-DD)
genderstringGender
racestringRace/ethnicity
addressstringResidential address
phonestringPhone number
occupationstringCurrent occupation
communityIdstringCommunity to sync with

Lua Example

function SyncCharacterToCAD(charData)
    PerformHttpRequest(Config.CadUrl .. '/api/civilian/fivem-sync-character', function(statusCode, response, headers)
        if statusCode == 200 or statusCode == 201 then
            local data = json.decode(response)
            print('[CDE CAD] Character synced: ' .. charData.firstName .. ' ' .. charData.lastName)
        else
            print('[CDE CAD] Character sync failed: ' .. tostring(statusCode))
        end
    end, 'POST', json.encode({
        firstName   = charData.firstName,
        lastName    = charData.lastName,
        ssn         = charData.ssn,
        dateOfBirth = charData.dob,
        gender      = charData.gender,
        race        = charData.race,
        address     = charData.address,
        phone       = charData.phone,
        occupation  = charData.job,
        communityId = Config.CommunityID
    }), {
        ['Content-Type'] = 'application/json',
        ['x-api-key']    = Config.ApiKey
    })
end
GET /api/civilian/fivem-civilian/:ssn

Look up a civilian record by their SSN. Returns the full civilian profile if found.

Requires API Key

Path Parameters

ParameterTypeDescription
ssnstringThe civilian's Social Security Number

Lua Example

function LookupCivilian(ssn)
    PerformHttpRequest(Config.CadUrl .. '/api/civilian/fivem-civilian/' .. ssn, function(statusCode, response, headers)
        if statusCode == 200 then
            local civilian = json.decode(response)
            print('[CDE CAD] Found: ' .. civilian.firstName .. ' ' .. civilian.lastName)
            -- Use civilian data in-game
        elseif statusCode == 404 then
            print('[CDE CAD] No civilian found with SSN: ' .. ssn)
        end
    end, 'GET', '', {
        ['x-api-key'] = Config.ApiKey
    })
end
GET /api/civilian/fivem-vehicle/:plate

Look up a vehicle record by its license plate. Returns the full vehicle profile including registered owner information.

Requires API Key

Path Parameters

ParameterTypeDescription
platestringThe vehicle's license plate number

Lua Example

function LookupVehicle(plate)
    PerformHttpRequest(Config.CadUrl .. '/api/civilian/fivem-vehicle/' .. plate, function(statusCode, response, headers)
        if statusCode == 200 then
            local vehicle = json.decode(response)
            print('[CDE CAD] Vehicle: ' .. vehicle.make .. ' ' .. vehicle.model)
            print('[CDE CAD] Owner: ' .. vehicle.ownerName)
        elseif statusCode == 404 then
            print('[CDE CAD] No vehicle found with plate: ' .. plate)
        end
    end, 'GET', '', {
        ['x-api-key'] = Config.ApiKey
    })
end
POST /api/civilian/fivem-register-vehicle

Register a vehicle from FiveM into the CAD database. Links the vehicle to an existing civilian record.

Requires API Key

Lua Example

function RegisterVehicleInCAD(vehicleData)
    PerformHttpRequest(Config.CadUrl .. '/api/civilian/fivem-register-vehicle', function(statusCode, response, headers)
        if statusCode == 200 or statusCode == 201 then
            local data = json.decode(response)
            print('[CDE CAD] Vehicle registered: ' .. vehicleData.plate)
        else
            print('[CDE CAD] Vehicle registration failed: ' .. tostring(statusCode))
        end
    end, 'POST', json.encode(vehicleData), {
        ['Content-Type'] = 'application/json',
        ['x-api-key']    = Config.ApiKey
    })
end
DELETE /api/civilian/fivem-delete-character/:ssn

Delete a civilian character record by SSN. This permanently removes the character from the CAD database.

Requires API Key

Path Parameters

ParameterTypeDescription
ssnstringThe SSN of the character to delete

Lua Example

function DeleteCharacterFromCAD(ssn)
    PerformHttpRequest(Config.CadUrl .. '/api/civilian/fivem-delete-character/' .. ssn, function(statusCode, response, headers)
        if statusCode == 200 then
            print('[CDE CAD] Character deleted: ' .. ssn)
        else
            print('[CDE CAD] Delete failed: ' .. tostring(statusCode))
        end
    end, 'DELETE', '', {
        ['x-api-key'] = Config.ApiKey
    })
end

FiveM Settings (Admin Panel API)

These endpoints manage FiveM integration settings for a community. They require JWT authentication and community admin permissions.

GET /api/fivem-settings/:communityId/fivem-settings

Retrieve the current FiveM integration settings for a community.

Requires JWT + Community Admin

Path Parameters

ParameterTypeDescription
communityIdstringThe community ID

Response

{
  "fivemServerIP": "123.45.67.89",
  "fivemServerPort": 30120,
  "enableAutoPlateReader": true,
  "enablePanicButton": true,
  "enable911Integration": true,
  "enableTrafficStops": false,
  "enableStatusUpdates": true,
  "webhookUrl": "https://discord.com/api/webhooks/..."
}
PUT /api/fivem-settings/:communityId/fivem-settings

Update FiveM integration settings for a community.

Requires JWT + Community Admin

Request Body

FieldTypeDescription
fivemServerIPstringFiveM server IP address
fivemServerPortnumberFiveM server port
enableAutoPlateReaderbooleanEnable automatic plate reader integration
enablePanicButtonbooleanEnable panic button alerts
enable911IntegrationbooleanEnable in-game 911 call forwarding
enableTrafficStopsbooleanEnable traffic stop integration
enableStatusUpdatesbooleanEnable unit status updates
webhookUrlstringDiscord webhook URL for notifications

Response

{
  "success": true,
  "message": "FiveM settings updated"
}
POST /api/fivem-settings/:communityId/api-key/generate

Generate a new FiveM API key for the community. The previous key is invalidated. The full key is returned only once in the response — store it securely.

Requires JWT + Community Admin
Warning: Generating a new API key immediately invalidates the previous key. All FiveM scripts using the old key will stop working until updated.

Response

{
  "success": true,
  "apiKey": "fvm_a1b2c3d4e5f6...full_64_hex_characters"
}
POST /api/fivem-settings/:communityId/test-fivem-connection

Test the connection to your FiveM server from CDE CAD. Uses a 5-second timeout to verify the server is reachable.

Requires JWT + Community Admin

Request Body

FieldTypeRequiredDescription
serverIPstringYesIP address of the FiveM server to test
serverPortnumberYesPort of the FiveM server to test

Response (Success)

{
  "success": true,
  "message": "Connection successful",
  "responseTime": 45
}

Response (Timeout)

{
  "success": false,
  "message": "Connection timed out after 5000ms"
}

Configuration Examples

Panic Button Script — config.lua

This configuration is used by the CDE CAD panic button resource for FiveM.

Config = {}

Config.CadUrl      = 'https://cdecad.com'
Config.ApiKey      = 'fvm_your_api_key_here'
Config.CommunityID = '1200664516858495056'  -- Discord guild ID
Config.ServerName  = 'My RP Server'

LiveMap Script — config.lua

This configuration is used by the CDE CAD live map tracking resource for FiveM.

Config = {}

Config.CADEndpoint = 'https://cdecad.com/api/dispatch/location-update'
Config.CommunityID = '1200664516858495056'
Config.APIKey      = 'livemap-cad-key-2024'
Discord Guild ID: Your CommunityID is your Discord server's guild ID. To find it, enable Developer Mode in Discord settings, then right-click your server name and select "Copy Server ID".

Troubleshooting

400 Bad Request — Empty Body

Cloudflare Body Stripping: Cloudflare may strip POST request bodies from non-browser clients (including FiveM's PerformHttpRequest). If you are receiving 400 errors despite sending a valid body, use the x-payload header as a fallback.

Encode your JSON payload as Base64 and send it in the x-payload header:

-- Fallback for Cloudflare body stripping
local payload = json.encode({
    callType = 'Robbery',
    location = 'Vinewood Blvd'
})

PerformHttpRequest(Config.CadUrl .. '/api/fivem/911', function(statusCode, response, headers)
    print('[CDE CAD] Status: ' .. tostring(statusCode))
end, 'POST', '', {
    ['Content-Type'] = 'application/json',
    ['x-api-key']    = Config.ApiKey,
    ['x-payload']    = Base64Encode(payload)
})

The server will check for the x-payload header, decode it, and use it as the request body if the normal body is empty.

401 Unauthorized

CauseSolution
Missing API key Ensure the x-api-key header is included in every request.
Invalid API key Verify the key matches the one generated in the Admin Panel. Keys start with fvm_.
Key was regenerated If someone generated a new key, the old key is invalidated. Update your config.lua with the new key.
Wrong header name Use x-api-key (lowercase). Some endpoints also accept X-API-Key.

429 Too Many Requests

Endpoint GroupLimitWindow
911 Calls10 requests1 minute per community
General FiveM API120 requests1 minute per API key
High-Impact (panic)20 requests1 minute per API key

If you hit rate limits, implement exponential backoff or reduce your request frequency. For location updates, 5-10 second intervals are recommended instead of every frame.

-- Simple retry with backoff
function SafeRequest(url, method, payload, headers, retries)
    retries = retries or 3
    local attempt = 0

    local function doRequest()
        attempt = attempt + 1
        PerformHttpRequest(url, function(statusCode, response, hdrs)
            if statusCode == 429 and attempt < retries then
                -- Wait before retrying (exponential backoff)
                Citizen.SetTimeout(attempt * 2000, doRequest)
            elseif statusCode >= 200 and statusCode < 300 then
                print('[CDE CAD] Request succeeded')
            else
                print('[CDE CAD] Request failed: ' .. tostring(statusCode))
            end
        end, method, payload, headers)
    end

    doRequest()
end

Common Debugging Tips

IssueDebug Step
No response from CAD Check that Config.CadUrl is correct and includes https://. Test the URL in a browser first.
Coordinates not showing on map Verify you are sending raw GTA coordinates. Do not transform them before sending.
911 calls not appearing Check that enable911Integration is enabled in the Admin Panel FiveM settings.
Panic not triggering alerts Verify enablePanicButton is enabled and dispatchers are connected to the WebSocket.
Community not found Ensure the communityId matches your Discord guild ID and the community exists in CDE CAD.