Skip to content

Exports ​

Resources register routes from the server side. Get a handle to the gateway once and use it for every call:

lua
local api = tm.exports.get('tm_api')

A handle waits for tm_api to start, so ensure order does not matter.

registerRoute(method, path, handler, description?) ​

Registers a route. Both path styles are accepted:

  • Short path (endpoint only): the resource name is added in front.
  • Full path (starts with /{resourceName}/): used as is, with no double prefix.
lua
-- Called from a resource named 'myresource'
api:registerRoute('GET', '/status', function(res, params, body, helpers)
    helpers.success({ online = true })
end, 'Returns service status')
-- stored as /myresource/status

api:registerRoute('POST', '/action', function(res, params, body, helpers)
    if not body or not body.target then
        return helpers.fail('Missing target', 400)
    end
    helpers.success({ done = true })
end, 'Perform an action')
-- stored as /myresource/action

Handler arguments:

ArgumentTypeDescription
restableThe FiveM HTTP response object.
paramstablePath parameters taken from the URL.
bodytable or nilThe decoded JSON body (POST and PUT only).
helpers.successfunction(data, status?)Sends { success = true, data = ... } (default status 200).
helpers.failfunction(message, status?)Sends { success = false, error = ... } (default status 400).

Returns true, or false, reason (invalid method or path, handler is not a function, or the route already exists).

registerRouteRaw(method, path, handler, description?, owner?) ​

Same as registerRoute, except the handler receives only res, params and body (no helpers) and the path is not prefixed, so pass the full path.

lua
api:registerRouteRaw('GET', '/myresource/raw', function(res, params, body)
    res.writeHead(200, { ['Content-Type'] = 'text/plain' })
    res.send('ok')
end, 'Raw response example')

unregisterRoute(method, path) ​

Removes a route. Only the resource that registered it can remove it. Routes are also removed on their own when the owning resource stops.

lua
api:unregisterRoute('GET', '/status')

Path rules ​

registerRoute and unregisterRoute check whether the first segment already matches the calling resource name.

Path you passResource nameStored and served as
/statusmyresource/myresource/status
/myresource/statusmyresource/myresource/status
/:id/kickmyresource/myresource/:id/kick

Full example ​

lua
CreateThread(function()
    local api = tm.exports.get('tm_api')

    api:registerRoute('GET', '/online', function(res, params, body, helpers)
        local players = {}
        for _, src in ipairs(GetPlayers()) do
            players[#players + 1] = { id = tonumber(src), name = GetPlayerName(src) }
        end
        helpers.success(players)
    end, 'List all online players')

    api:registerRoute('POST', '/:id/kick', function(res, params, body, helpers)
        local src = tonumber(params.id)
        if not src or not GetPlayerName(src) then
            return helpers.fail('Player not found', 404)
        end
        DropPlayer(tostring(src), body and body.reason or 'No reason provided')
        helpers.success({ kicked = src })
    end, 'Kick a player')
end)