Server API
Everything here lives in CoreServerAPI and runs from a server Script:
local hd = game:GetService("ReplicatedStorage"):WaitForChild("HD Admin")
local ServerAPI = require(hd.Core.ServerAPI)
Commands¶
requestCommand Server¶
ServerAPI.requestCommand(message: string, fromPlayer: Player?): (boolean, {any}, {Task})
Runs a command message exactly as if it was chatted. When no player is given, a Server User takes the caller's place, so commands can fire from anywhere in your game code without permission checks. When a player is provided, their roles, permissions and rate limits all apply, and any caller notices are sent to them. Returns whether approved, the notices produced, and the tasks it created.
-- Run as the server
ServerAPI.requestCommand(";fly all")
-- Or on behalf of a player
ServerAPI.requestCommand(";fly me", player)
getTasks Server¶
ServerAPI.getTasks(commandName: string?, target: Target?): {Task}
Returns the running tasks. Both filters are optional. ServerAPI.getTasks() returns every task, ServerAPI.getTasks("fly") every fly task, and ServerAPI.getTasks("fly", player) only that player's fly tasks.
endTasks Server¶
ServerAPI.endTasks(commandName: string?, target: Target?): number
Ends the matching tasks and returns how many were ended. This is ;unCommand in code form, with the same optional filters as getTasks.
-- End every fly in the server
ServerAPI.endTasks("fly")
-- Clear everything running on one player
ServerAPI.endTasks(nil, player)
canUseCommandAsync Server¶
ServerAPI.canUseCommandAsync(target: Target, commandName: string): (boolean, string?)
Whether the target's roles allow them to run the given command. Returns true, or false and the reason.
disableCommands Server¶
ServerAPI.disableCommands(player: Player)
Blocks the player from running any new commands until enableCommands is called or they rejoin. Useful while they're inside a minigame round or a cutscene. Their already-running tasks carry on, so pair this with endTasks if you want those cleared too. It's safe to call straight from PlayerAdded.
enableCommands Server¶
ServerAPI.enableCommands(player: Player)
Lets the player run commands again.
Roles¶
Role names are matched case-insensitively, so "VIP" and "vip" reach the same role.
giveRoleAsync Server¶
ServerAPI.giveRoleAsync(target: Target, roleName: string, options: ActionOptions?): (boolean, string?)
Gives the role to the target and returns true, or false and the reason it couldn't. Permanent grants save, travel cross-server, and work for offline targets too.
| Option | What it does |
|---|---|
scope |
"perm" saves forever (the default), "server" lasts this server only, "expire" removes itself after duration |
duration |
Seconds, required for scope "expire" |
reason |
The reason for giving |
callerUserId |
A UserId of the person who gave it and to rank-check against |
-- Reward a purchase forever
ServerAPI.giveRoleAsync(player, "VIP")
-- A 24 hour trial, granted by an offline head admin
ServerAPI.giveRoleAsync(player, "Mod", {
scope = "expire",
duration = 24 * 3600,
callerUserId = 1234567,
})
takeRoleAsync Server¶
ServerAPI.takeRoleAsync(target: Target, roleName: string, options: ActionOptions?): (boolean, string?)
Takes the role from the target, including permanent grants made on other servers or while they were offline. options accepts scope ("perm" or "server") and callerUserId, matching giveRoleAsync.
getRolesAsync Server¶
ServerAPI.getRolesAsync(target: Target): (boolean, {Role} | string)
Returns true and the target's roles ordered highest rank first, or false and a reason. The target must be in this server.
local success, roles = ServerAPI.getRolesAsync(player)
if success then
for _, role in roles do
print(role.name, role.rank)
end
end
getTopRoleAsync Server¶
ServerAPI.getTopRoleAsync(target: Target): (boolean, (Role | string)?)
Returns true and the target's most senior role (nil if they hold none), or false and a reason. The target must be in this server.
hasRoleAsync Server¶
ServerAPI.hasRoleAsync(target: Target, roleName: string): boolean
Whether the target currently holds the role. The target must be in this server.
getRole Server¶
ServerAPI.getRole(roleName: string): Role?
Returns the Role for the given name, or nil if no role matches.
getAllRoles Server¶
ServerAPI.getAllRoles(): {Role}
Returns every role in the game's configuration.
Moderation¶
banAsync Server¶
ServerAPI.banAsync(target: Target, options: BanOptions): (boolean, string?)
Bans the target for entering your game, and kicks them if they're currently in any server. Returns true and the new banId, or false and the reason it couldn't. Offline targets work too.
| Option | What it does |
|---|---|
reason |
Required, shown to the player when they try to join |
scope |
"perm" (the default), "server" for this server only, or "expire" |
duration |
Seconds, for scope "expire" |
expiresAt |
An absolute epoch which overrides duration |
banAlts |
Defaults to true, banning alt accounts through Roblox's BanService |
callerUserId |
A UserId to credit the ban to and rank-check against. Leave it out for a system ban with no restrictions |
-- A 7 day ban issued by your own anti-cheat
ServerAPI.banAsync(player, {
reason = "Exploiting",
scope = "expire",
duration = 7 * 24 * 3600,
})
unbanAsync Server¶
ServerAPI.unbanAsync(target: Target, banId: string?, options: UnbanOptions?): (boolean, string?, number?)
Clears the target's bans and returns (success, failReason, totalBansCleared). Pass a banId to clear one specific ban, or nil to clear them all. options accepts scope and callerUserId.
getBanAsync Server¶
ServerAPI.getBanAsync(target: Target): (BanRecord?, string?)
Returns the target's active BanRecord and its banId, checking offline records too, or nil if they aren't banned.
local ban, banId = ServerAPI.getBanAsync(userId)
if ban then
print(`Banned for '{ban.reason}' by {ban.bannedBy}`)
end
Prompts¶
prompt Shared¶
ServerAPI.prompt(promptType: PromptType, player: Player, text: string, options: PromptOptions?): PromptHandle
Shows a notice, message or card to the player using HD Admin's own UI, from any server Script. This is the same function as the Command API's prompt, which covers every prompt type, the full list of options, and the action cards with buttons and sliders.
ServerAPI.prompt("success", player, "Quest complete!", {duration = 5})
Text¶
filterTextAsync Server¶
ServerAPI.filterTextAsync(text: string, author: Target, viewer: Target?): (boolean, string)
Runs the text through Roblox's filter and returns true and the filtered text, or false and the reason. Leave out viewer to filter for everyone, which is right for anything every player can see and for text you save. Pass a viewer to filter for that one player instead. The author must be in this server, because Roblox's filter refuses to run for anyone who isn't. Text that comes back as nothing but hashtags counts as a failure, so you never display an empty result.
local success, result = ServerAPI.filterTextAsync(petName, player)
if success then
nameLabel.Text = result
else
ServerAPI.prompt("warn", player, "That name can't be used")
end
Info¶
getSetting Shared¶
ServerAPI.getSetting(settingName: string, player: Player?): any
Returns the value of a game setting, like ServerAPI.getSetting("Prefix"). Pass a player to also apply their own You Settings, so you get the exact value that player experiences.
getVersion Shared¶
ServerAPI.getVersion(): string
The running HD Admin version, like "v2.0.0".
Isolation¶
isolateServer Server¶
ServerAPI.isolateServer()
Cuts this server off from saving data and sending anything to other servers. Everything will still appear to work as normal, such as perm bans, role edits, game settings, global commands and global votes, except none of it actually saves or reaches other servers, so it all disappears when the server ends. Saved data is still read as normal, so the server starts with your real roles, bans, settings, etc.
This is very useful for example for demo or test places, or even private servers or reserved servers where you want to grant someone "Owner" without having any impact on the rest of your universe. The HD Admin Hub uses it for example so that visitors can try every command without breaking anything for the next server.
local hd = game:GetService("ReplicatedStorage"):WaitForChild("HD Admin")
local ServerAPI = require(hd:WaitForChild("Core"):WaitForChild("ServerAPI"))
ServerAPI.isolateServer()
isServerIsolated Server¶
ServerAPI.isServerIsolated(): boolean
Returns true once isolateServer has been called in this server.
Emotes¶
getEmoteById Server¶
ServerAPI.getEmoteById(emoteId: number): Emote?
Returns the registered Emote with the given id, or nil.
getEmoteByName Server¶
ServerAPI.getEmoteByName(emoteName: string, matchLength: boolean?): Emote?
Returns the registered Emote matching the given name, or nil.
getRandomEmote Server¶
ServerAPI.getRandomEmote(): Emote?
addEmoteAsync Server¶
ServerAPI.addEmoteAsync(emote: IncompleteEmote, dontRegister: boolean?): (boolean, Emote | string)
Registers a new emote from an emote animation asset, so it can be played by ;emote and appear in the emotes menu. Only emoteId is required, and the missing details are fetched for you. Returns true and the completed Emote, or false and the reason it couldn't.
Types¶
Role¶
The full role configuration table, exactly as defined under ConfigRoles. See Roles.
BanRecord¶
type BanRecord = {
type: "perm" | "expire" | "server",
source: "admin" | "loader",
bannedBy: number | string,
bannedAt: number,
expiresAt: number?,
grantedOnJobId: string?, -- only present on server-scope bans
reason: string,
banAlts: boolean,
}
The banId isn't part of the record itself, so getBanAsync hands it to you as a second return value.
Task¶
See Task API.
Emote¶
type Emote = {
name: string,
originalName: string?,
order: number,
animationId: number,
emoteId: number,
}