Roblox Ranking
Service API
A Lua module that connects your Roblox game to the Node API — letting you rank, exile, and manage group members directly from your game scripts.
Getting Started
Node lets you control your Roblox group's rankings from inside your game. Instead of writing complex Roblox API calls yourself, you install one module, add a config script, and you're ready to rank players with a single line of code.
What you need
A Node account + linked token
Sign up at the Node website, link the Roblox account that has your group permissions, and copy the token the portal generates for your experience.
A Roblox account with group permissions
The account you link must be a member of the group with the permissions you need for ranking and member management.
HTTP Requests enabled in Studio
Game Settings → Security → Allow HTTP Requests must be toggled ON.
Installation
Add the RankingService module to your game using the Roblox Toolbox or directly via the asset ID.
Open your place in Roblox Studio
Make sure you have the correct game open that you want to add ranking to.
Open the Toolbox
View → Toolbox → search for RankingService by AlienRanks, or click the link above and click "Get" in the Roblox catalog.
Move it to ServerStorage
Drag the RankingService ModuleScript from wherever it lands into ServerStorage. It must be in ServerStorage — not ReplicatedStorage, not Workspace.
Enable HTTP Requests
File → Game Settings → Security → toggle Allow HTTP Requests to ON. Without this, the module cannot reach the server.
Quick Start
Two scripts and you're done. The first sets up the service globally, the second uses it.
-- Place this Script inside ServerScriptService -- This runs once and makes the service available globally local RankingService = require(game.ServerStorage.RankingService) local ranking = RankingService.new( "LINK_TOKEN_HERE", -- your token from the portal "https://noderoblox.com" ) -- Make it accessible from any Script in the game _G.Ranking = ranking _G.GROUP_ID = 12345678 -- your Roblox group ID print("[Node] Ranking service ready ✅")
-- Wait for RankConfig to load first while not _G.Ranking do task.wait(0.5) end -- Rank a player to rank 5 local result = _G.Ranking:setRank(_G.GROUP_ID, player.UserId, 5) if result.success then print("✅ Ranked successfully!") else warn("❌ Error: " .. result.error) end
Link Your Experience
Sign in to the Node dashboard
Go to your Node server URL and click Sign In. Create an account or log in with Google/Discord.
Start Roblox OAuth
Open the dashboard and click Link Roblox. Roblox will show a consent screen where you approve the app with your linked account.
Approve the link
After Roblox returns you to the dashboard, the server saves your OAuth tokens and gives you a linked token for the module.
Copy your token into RankConfig
Paste the linked token into the RankConfig script where it says "LINK_TOKEN_HERE".
Studio Setup
Script placement
ServerStorage → RankingService (ModuleScript)
The module from asset ID 110200251504544. Must be a ModuleScript, must be in ServerStorage.
ServerScriptService → RankConfig (Script)
Your configuration script that calls RankingService.new() and sets _G.Ranking. Must be a Script (not LocalScript).
ServerScriptService → Your game scripts (Script)
Any other Script that uses _G.Ranking:setRank() etc. Always wait for _G.Ranking to exist before using it.
API Reference
Sets a player's rank in the group to a specific rank number (1–255). The bot must have a rank higher than the target rank to perform this action.
| Parameter | Type | Description |
|---|---|---|
| groupId | number | Your Roblox group ID |
| userId | number | Target player's UserId |
| rank | number | Rank number to assign (1–255) |
local result = _G.Ranking:setRank(_G.GROUP_ID, player.UserId, 10) if result.success then print("Ranked to 10!") end
Removes a player from the group entirely. This cannot be undone — the player would need to re-join the group.
| Parameter | Type | Description |
|---|---|---|
| groupId | number | Your Roblox group ID |
| userId | number | Target player's UserId |
local result = _G.Ranking:exile(_G.GROUP_ID, player.UserId) if result.success then player:Kick("You have been exiled from the group.") end
Returns the player's current rank number in the group. Returns 0 if the player is not in the group.
| Parameter | Type | Description |
|---|---|---|
| groupId | number | Your Roblox group ID |
| userId | number | Target player's UserId |
local result = _G.Ranking:getRank(_G.GROUP_ID, player.UserId) if result.success then print("Current rank: " .. result.data) end
Accepts or denies a pending group join request. The player must have an active join request for this to work.
| Parameter | Type | Description |
|---|---|---|
| groupId | number | Your Roblox group ID |
| userId | number | The requesting player's UserId |
| accept | boolean | true to accept, false to deny |
-- Accept a join request _G.Ranking:handleJoinRequest(_G.GROUP_ID, player.UserId, true) -- Deny a join request _G.Ranking:handleJoinRequest(_G.GROUP_ID, player.UserId, false)
Posts a message to the group shout wall. Max 255 characters. Be careful calling this repeatedly — excessive calls may get the linked Roblox account rate-limited.
| Parameter | Type | Description |
|---|---|---|
| groupId | number | Your Roblox group ID |
| message | string | Message to post (max 255 chars) |
_G.Ranking:shout(_G.GROUP_ID, "⚔️ New server online — come join us!")
Touch a Part to Rank
When a player touches a part in the game, they get ranked up. Place this as a Script inside the Part.
local Players = game:GetService("Players") local part = script.Parent local RANK = 5 -- rank number to assign local COOLDOWN = 10 -- seconds before the same player can trigger again local debounce = {} part.Touched:Connect(function(hit) local player = Players:GetPlayerFromCharacter(hit.Parent) if not player or debounce[player.UserId] then return end debounce[player.UserId] = true -- Wait for RankConfig to finish loading local t = 0 while not _G.Ranking and t < 10 do task.wait(0.5); t += 0.5 end if not _G.Ranking then debounce[player.UserId] = nil; return end local result = _G.Ranking:setRank(_G.GROUP_ID, player.UserId, RANK) if result.success then print("✅ Ranked " .. player.Name .. " to rank " .. RANK) else warn("❌ Failed: " .. result.error) end task.wait(COOLDOWN) debounce[player.UserId] = nil end)
Rank GamePass Owners on Join
Automatically promote players who own a specific GamePass when they join the server.
local Players = game:GetService("Players") local MarketplaceService = game:GetService("MarketplaceService") local VIP_PASS_ID = 123456789 -- replace with your GamePass ID local VIP_RANK = 50 -- rank to assign to VIP players Players.PlayerAdded:Connect(function(player) player.CharacterAdded:Wait() task.wait(1) -- Wait for ranking service while not _G.Ranking do task.wait(0.5) end -- Check if they own the pass local ok, hasPass = pcall(function() return MarketplaceService:UserOwnsGamePassAsync(player.UserId, VIP_PASS_ID) end) if not ok or not hasPass then return end -- Only promote if they're not already at or above VIP rank local current = _G.Ranking:getRank(_G.GROUP_ID, player.UserId) if current.success and current.data < VIP_RANK then _G.Ranking:setRank(_G.GROUP_ID, player.UserId, VIP_RANK) print("⭐ Promoted VIP: " .. player.Name) end end)
Score-Based Rank Tiers
Promote players to different ranks based on their score. Call checkPromotion(player, score) whenever a player's score changes.
-- Score thresholds → rank numbers local TIERS = { { score = 100, rank = 50 }, { score = 50, rank = 30 }, { score = 25, rank = 15 }, { score = 10, rank = 5 }, } local function checkPromotion(player, score) while not _G.Ranking do task.wait(0.5) end -- Find the highest tier they qualify for local targetRank = nil for _, tier in ipairs(TIERS) do if score >= tier.score then targetRank = tier.rank break end end if not targetRank then return end -- Only promote, never demote local current = _G.Ranking:getRank(_G.GROUP_ID, player.UserId) if current.success and current.data < targetRank then local res = _G.Ranking:setRank(_G.GROUP_ID, player.UserId, targetRank) if res.success then print("⬆️ Promoted " .. player.Name .. " to rank " .. targetRank) end end end -- Example: call this from your game logic -- checkPromotion(player, playerScore)
Admin Chat Commands
Let specified admins use chat commands to rank or exile players in-game.
local Players = game:GetService("Players") -- Add your UserId(s) here local ADMINS = { [123456789] = true } -- Commands: !rank PlayerName RankNumber | !exile PlayerName Players.PlayerAdded:Connect(function(player) player.Chatted:Connect(function(msg) if not ADMINS[player.UserId] then return end local args = string.split(msg, " ") local cmd = string.lower(args[1]) while not _G.Ranking do task.wait(0.5) end if cmd == "!rank" and #args == 3 then local target = Players:FindFirstChild(args[2]) local rank = tonumber(args[3]) if target and rank then local r = _G.Ranking:setRank(_G.GROUP_ID, target.UserId, rank) print(r.success and "✅ Ranked "..target.Name or "❌ "..r.error) end elseif cmd == "!exile" and #args == 2 then local target = Players:FindFirstChild(args[2]) if target then local r = _G.Ranking:exile(_G.GROUP_ID, target.UserId) print(r.success and "✅ Exiled "..target.Name or "❌ "..r.error) end end end) end)
Error Reference
All methods return a table with success (boolean) and either data or error (string).
| Error Message | Cause | Fix |
|---|---|---|
| Invalid linked token | The token doesn't exist in the database | Get a fresh token from the Node dashboard |
| Roblox OAuth link expired | The stored access token needs to be refreshed | Click Link Roblox again from the dashboard |
| Can't parse JSON | Server returned HTML — it's down or wrong URL | Check your server URL in RankConfig is correct and server is running |
| HTTP 403 | Linked account doesn't have permission to rank that player | Give the linked Roblox account the correct group role or permissions |
| Number of requests exceeded limit | Roblox's own rate limit hit | Module auto-retries after 30s — no action needed |
| Request already pending for this user | Two simultaneous requests for same userId | Your code called the method twice — add a debounce |
| groupId and userId required | Missing parameters in the call | Make sure you're passing both _G.GROUP_ID and player.UserId |
FAQ
Does this work in Studio?
Yes — the module auto-detects Studio vs live server and uses the correct API path. You can test ranking in Studio with your real linked token.
Can I use this for multiple groups?
Yes — just pass a different groupId to each method call. One linked Roblox account can manage multiple groups as long as it has permissions in each one.
Why is my bot not ranking players above a certain rank?
Roblox enforces that an account can only rank players below its own rank. If your linked account is rank 100 (Officer), it cannot promote anyone to rank 100 or above. Give the linked account a higher role to fix this.
How often does my OAuth link expire?
Roblox access tokens expire automatically, but the server refreshes them when possible. If the refresh token is invalidated, click Link Roblox again from the dashboard.
Is it safe to put my linked token in a Script?
Scripts in ServerScriptService are server-side only — players cannot access them. Never put your linked token in a LocalScript or ModuleScript that clients can access.
The first request after server start is slow — is that normal?
If you're using Render's free tier, the server sleeps after inactivity and takes ~30 seconds to wake up on the first request. Use Koyeb instead for always-on hosting with no cold starts.