GET Public /api/v1/callbacks/{codes}
Callbacks are how the Roblox server asks Kiba for the current Discord activity of active players. Send every player code in one request and Kiba returns one text block per code.
Plain English Flow
- Your game stores each player's
KibaCodeafter a successful bind. - Every 30 to 60 seconds, collect the codes for players currently in the server.
- Join those codes with
&and callGET /api/v1/callbacks/{codes}. - Kiba checks each linked Discord user in real time.
- Your game parses each response block and updates the overhead UI or status display.
Endpoint
GET https://api.kiba-is-a.top/api/v1/callbacks/AB12&CD34&EF56
| Part | Meaning |
|---|---|
AB12 | A 4-character Kiba code. |
& | Separator between multiple codes. |
text/plain | The response content type. It is intentionally not JSON. |
Roblox Server Example
Run this from a ServerScript. Polling every 45 seconds is a good starting point. Keep the render logic separate so this script only fetches and parses the data.
local HttpService = game:GetService("HttpService")
local Players = game:GetService("Players")
local CALLBACK_BASE = "https://api.kiba-is-a.top/api/v1/callbacks/"
local POLL_SECONDS = 45
local function collectPlayerCodes()
local codes = {}
for _, player in Players:GetPlayers() do
local code = player:GetAttribute("KibaCode")
if typeof(code) == "string" and string.match(code, "^[A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9]$") then
table.insert(codes, code)
end
end
return codes
end
local function parseBlocks(responseText)
local blocks = {}
for block in string.gmatch(responseText, "{(.-)}") do
local code = string.match(block, "^([A-Z0-9][A-Z0-9][A-Z0-9][A-Z0-9])")
local isError = string.sub(block, 5, 5) == ":"
blocks[code] = {
raw = block,
is_error = isError
}
end
return blocks
end
local function pollKiba()
local codes = collectPlayerCodes()
if #codes == 0 then
return
end
local url = CALLBACK_BASE .. table.concat(codes, "&")
local ok, responseText = pcall(function()
return HttpService:GetAsync(url)
end)
if not ok then
warn("Kiba callback request failed: " .. tostring(responseText))
return
end
local blocks = parseBlocks(responseText)
for code, block in pairs(blocks) do
print(code, block.is_error, block.raw)
-- Update your overhead UI, player tag, or status board here.
end
end
while true do
pollKiba()
task.wait(POLL_SECONDS)
end
Out-of-Game Test
curl "https://api.kiba-is-a.top/api/v1/callbacks/AB12&CD34&EF56"
Response Blocks
Each code produces one block. A semicolon after the code means normal/active. A colon after the code means an error or locked state.
Active User With Activity
{AB12;
SomeRobloxUser;
Listening to Spotify,
Song Name Here,
Artist1, Artist2;
Playing,
Game Name Here;
}
Active User With No Activity
{AB12;
SomeRobloxUser;
No activity detected;
}
Banned Code
{AB12:
SomeRobloxUser;
"This code is banned, Contact support for more info";
}
Invalidated Code
{AB12:
SomeRobloxUser;
"This code has been invalidated, contact support for help";
}
Paused Code
{AB12:
"Detection Paused";
}
Code Not Found
{AB12:
"Code not found";
}
State Rules
| Marker | Meaning | Game behavior |
|---|---|---|
; | Normal block. | Read the username and activity lines. |
: | Error, locked, paused, banned, invalidated, or not found. | Show a safe fallback message or hide activity. |
Activity Filtering
Kiba removes Discord activities containing Roblox in the name, details, state,
or asset text. This keeps the Roblox game itself from being echoed back into the in-game display.
Rate Limit
GET /callbacks/* is limited to 60 requests per minute per IP.
Poll once for the whole server instead of calling once per player.
Status Codes
| HTTP | Meaning |
|---|---|
200 | Request accepted. Individual codes can still return not found, paused, banned, or invalidated blocks. |
400 | No usable code path was provided. |
429 | The server is polling too often. |