Check up to 10,000 members in a single request. Perfect for scanning entire Discord servers. Each ID checked counts as 1 usage toward your daily limit.
curl -X GET "https://robloxwatcher.info/checker/api/check.php?id=USER_ID_HERE&key=ROBLOXWATCHERFREEKEY"
A complete, production-ready Discord bot using discord.js. This bot handles slash commands (/check, /scan, /search) and includes safe batch-fetching for large servers.
const { Client, GatewayIntentBits, Partials, Routes, REST, SlashCommandBuilder, EmbedBuilder, PermissionsBitField, AttachmentBuilder } = require('discord.js');
// ==========================================// CONFIGURATION// ==========================================// 1. Enter your Discord Bot Token hereconstDISCORD_TOKEN = 'YOUR_BOT_TOKEN_HERE';
// 2. Enter your API Key (Use 'ROBLOXWATCHERFREEKEY' for public access)constAPI_KEY = 'ROBLOXWATCHERFREEKEY';
// 3. The API EndpointconstAPI_URL = 'https://robloxwatcher.info/checker/api/check.php';
// ==========================================const client = newClient({
intents: [
GatewayIntentBits.Guilds,
GatewayIntentBits.GuildMembers,
GatewayIntentBits.GuildMessages,
GatewayIntentBits.MessageContent
],
partials: [Partials.GuildMember]
});
constsleep = ms => newPromise(r => setTimeout(r, ms));
// -------------------// API CHECK FUNCTION// -------------------asyncfunctioncheckUserId(id) {
try {
const res = awaitfetch(`${API_URL}?id=${id}&key=${API_KEY}`, {
headers: { 'User-Agent': 'BanlistBot/1.0' }
});
const data = await res.json();
if (data.error) return { banned: false, error: data.error };
return { banned: data.banned === true, servers: data.roblox_servers || [] };
} catch (e) {
return { banned: false, error: 'Connection Failed' };
}
}
// -------------------// SAFE BATCH FETCH (For Large Servers)// -------------------asyncfunctionfetchMembersInBatches(guild, batchSize = 50, delayMs = 1200) {
const allMembers = newMap();
let lastId = '0';
while (true) {
const members = await guild.members.list({ limit: batchSize, after: lastId });
if (members.size === 0) break;
for (const [id, member] of members) allMembers.set(id, member);
lastId = Array.from(members.keys()).pop();
awaitsleep(delayMs);
}
return allMembers;
}
// -------------------// SLASH COMMANDS// -------------------const commands = [
newSlashCommandBuilder().setName('check').setDescription('Checks and bans malicious users.').setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator),
newSlashCommandBuilder().setName('scan').setDescription('Scans all members for flags.').setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator),
newSlashCommandBuilder().setName('search').setDescription('Search for a User ID.').addStringOption(o => o.setName('userid').setDescription('ID').setRequired(true)).setDefaultMemberPermissions(PermissionsBitField.Flags.Administrator)
].map(c => c.toJSON());
client.once('ready', async () => {
const rest = newREST({ version: '10' }).setToken(DISCORD_TOKEN);
await rest.put(Routes.applicationCommands(client.user.id), { body: commands });
console.log('Bot is online.');
});
// -------------------// COMMAND HANDLER (Slash & Message)// -------------------
client.on('interactionCreate', asynci => {
if (!i.isChatInputCommand()) return;
await i.deferReply({ ephemeral: true });
// SEARCH & SCAN & CHECK logic
if (i.commandName === 'search') {
const id = i.options.getString('userid');
const result = await checkUserId(id);
const embed = new EmbedBuilder().setTimestamp();
if (result.banned) embed.setColor('#ff4444').setDescription('⚠️ **MATCH FOUND** User is flagged.');
else embed.setColor('#44ff44').setDescription('✅ No flags found.');
await i.editReply({ embeds: [embed] });
}
if (i.commandName === 'scan' || i.commandName === 'check') {
const members = await fetchMembersInBatches(i.guild);
let flagged = [];
for (const [id, member] of members) {
if (member.user.bot) continue;
const res = await checkUserId(id);
if (res.banned) {
flagged.push(`<@${id}>`);
if (i.commandName === 'check') await member.ban({ reason: 'Flagged by Global API' }).catch(() => {});
}
}
const embed = new EmbedBuilder()
.setTitle(i.commandName === 'check' ? 'Check & Ban Complete' : 'Scan Complete')
.setDescription(`Found ${flagged.length} flagged users. ${i.commandName === 'check' ? 'They have been banned.' : ''}`)
.setColor(flagged.length ? '#ff4444' : '#44ff44');
await i.editReply({ embeds: [embed] });
}
});
// Prefix command handler (!)
client.on('messageCreate', asyncmessage => {
if (!message.guild || message.author.bot) return;
if (!message.member.permissions.has(PermissionsBitField.Flags.Administrator)) return;
const prefix = '!';
if (!message.content.startsWith(prefix)) return;
const args = message.content.slice(prefix.length).trim().split(/ +/);
const cmd = args.shift().toLowerCase();
if (cmd === 'search') {
const result = await checkUserId(args[0]);
message.reply(result.banned ? '⚠️ **MATCH FOUND**' : '✅ No flags found.');
}
if (cmd === 'scan' || cmd === 'check') {
message.reply(`Starting ${cmd}... this may take a moment.`);
const members = await fetchMembersInBatches(message.guild);
let count = 0;
for (const [id, member] of members) {
if (member.user.bot) continue;
const res = await checkUserId(id);
if (res.banned) {
count++;
if (cmd === 'check') await member.ban({ reason: 'Flagged by Global API' }).catch(() => {});
}
}
message.reply(`${cmd.toUpperCase()} complete. Found ${count} flagged users.`);
}
});
client.login(DISCORD_TOKEN);
API Playground
Try out the API live without writing any code. Enter a User ID and your API Key to see the raw JSON response.