POST Auth Required /api/v1/bind

Bind is the one-time link between a Discord code and a Roblox account. A user gets a 4-character code from Discord, enters it in the game, and the Roblox server sends that code to this endpoint with the player's Roblox identity.

Keep the API key on the Roblox server side only. Do not put it in a LocalScript, UI asset, public module, or anything a client can download.

Plain English Flow

  1. User runs /code in Discord and receives a private code such as AB12.
  2. User types that code into your Roblox UI.
  3. Your LocalScript sends the typed code to a RemoteEvent.
  4. A ServerScript receives the RemoteEvent and calls POST /api/v1/bind.
  5. If the bind succeeds, store the code as a server-side player attribute or in your datastore.
  6. Your game can later poll GET /api/v1/callbacks/{codes} for active players.

Endpoint

POST https://api.kiba-is-a.top/api/v1/bind
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Request Body

{
    "code": "AB12",
    "roblox_username": "PlayerName",
    "roblox_user_id": 12345678
}
FieldRequiredMeaning
codeYesThe 4-character Discord code typed by the player. Allowed format: A-Z and 0-9.
roblox_usernameYesThe Roblox username from player.Name.
roblox_user_idRecommendedThe Roblox user ID from player.UserId. If omitted, the API tries to resolve it from the username.

In-Game Roblox Example

Use a UI LocalScript only to collect the code. The HTTP call belongs in a ServerScript. This keeps the bearer token out of the player's client.

LocalScript: send the entered code

local ReplicatedStorage = game:GetService("ReplicatedStorage")

local bindEvent = ReplicatedStorage:WaitForChild("KibaBindCode")
local textBox = script.Parent.CodeTextBox
local submitButton = script.Parent.SubmitButton

submitButton.MouseButton1Click:Connect(function()
    local code = string.upper(textBox.Text or "")
    bindEvent:FireServer(code)
end)

ServerScript: call /bind safely

local HttpService = game:GetService("HttpService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local API_KEY = "YOUR_API_KEY"
local BIND_URL = "https://api.kiba-is-a.top/api/v1/bind"

local bindEvent = Instance.new("RemoteEvent")
bindEvent.Name = "KibaBindCode"
bindEvent.Parent = ReplicatedStorage

local function isValidCode(code)
    return typeof(code) == "string" and string.match(code, "^[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]$") ~= nil
end

bindEvent.OnServerEvent:Connect(function(player, code)
    code = string.upper(tostring(code or ""))
    if not isValidCode(code) then
        warn("Invalid Kiba code from " .. player.Name)
        return
    end

    local body = HttpService:JSONEncode({
        code = code,
        roblox_username = player.Name,
        roblox_user_id = player.UserId
    })

    local ok, response = pcall(function()
        return HttpService:RequestAsync({
            Url = BIND_URL,
            Method = "POST",
            Headers = {
                ["Authorization"] = "Bearer " .. API_KEY,
                ["Content-Type"] = "application/json"
            },
            Body = body
        })
    end)

    if not ok then
        warn("Kiba bind request failed: " .. tostring(response))
        return
    end

    local payload = HttpService:JSONDecode(response.Body)
    local status = response.Success and payload.status or (payload.detail and payload.detail.status)

    if status == "bound" or status == "already_bound" then
        player:SetAttribute("KibaCode", code)
        print(player.Name .. " linked to Kiba code " .. code)
    elseif status == "banned" then
        warn("Kiba code is banned for " .. player.Name)
    elseif status == "invalidated" then
        warn("Kiba code was invalidated for " .. player.Name)
    else
        warn("Kiba bind failed for " .. player.Name .. ": " .. tostring(status))
    end
end)

Polling After Bind

Once players have a stored KibaCode, the server can poll callbacks for everyone currently in the server. The callback endpoint is public and does not need the API key.

local HttpService = game:GetService("HttpService")
local Players = game:GetService("Players")

local CALLBACK_BASE = "https://api.kiba-is-a.top/api/v1/callbacks/"

local function pollKibaPresence()
    local codes = {}
    for _, player in Players:GetPlayers() do
        local code = player:GetAttribute("KibaCode")
        if code then
            table.insert(codes, code)
        end
    end

    if #codes == 0 then
        return
    end

    local response = HttpService:GetAsync(CALLBACK_BASE .. table.concat(codes, "&"))
    print(response)
    -- Parse the callback blocks and render them in your overhead UI.
end

while true do
    pollKibaPresence()
    task.wait(45)
end

Out-of-Game Test

Use this from your terminal, Postman, or any backend tool when you want to verify a code without starting Roblox Studio.

curl -X POST https://api.kiba-is-a.top/api/v1/bind \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"code":"AB12","roblox_username":"PlayerName","roblox_user_id":12345678}'

Responses

StatusMeaningWhat to do
boundThe code is now linked to this Roblox user.Store the code for that player and continue.
already_boundThe same Roblox user used the same code again.Treat it as success.
not_foundThe code does not exist.Ask the user to check their Discord code.
bannedThe code exists but is banned.Do not link it. Show a support/admin message.
invalidatedA different Roblox account tried to use an already-bound code, or the code was already invalidated.Do not retry automatically. The user needs staff help.
errorThe request body failed validation or Roblox username resolution failed.Fix the code, username, or user ID being sent.

Success

{
    "status": "bound",
    "roblox_username": "PlayerName"
}

Already Linked

{
    "status": "already_bound",
    "roblox_username": "PlayerName"
}

Invalidated

{
    "detail": {
        "status": "invalidated",
        "message": "This code has been invalidated, contact support for help."
    }
}

Security Notes