What it is
A drop-in RNG layer for Discord bots. Replace the Math.random() that backs your /roll, /giveaway, /pick, and /raidloot slash commands with HTTP calls to /api/dice, /api/pick, /api/ints, and /api/shuffle. Every reply embeds the shortId permalink so any user can verify the roll without trusting the bot operator.
The pain point
Discord communities run on bots, and bots run on RNG that nobody can audit. The standard pattern is "post the result, hope the moderators don't get accused of nepotism." A verifiable RNG turns each bot reply into a link a curious user can click — they get the math, the mods get their evening back.
Try it live — a slash-command dice roll
The same call your /roll 4d6 handler will make:
curl "https://api.provable.io/api/dice?clientSeed=guild_123_user_456_roll_2026_05_25¬ation=4d6"
A /pick slash command — pick one option from a poll choices list:
curl "https://api.provable.io/api/pick?clientSeed=guild_123_poll_42&items=pizza,tacos,sushi,ramen,burgers"
Integration snippet
// discord.js v14 — /roll <notation> handler
import { SlashCommandBuilder } from "discord.js";
export const data = new SlashCommandBuilder()
.setName("roll")
.setDescription("Roll dice (NdM notation)")
.addStringOption((o) => o.setName("notation").setDescription("e.g. 3d6, 2d20+5").setRequired(true));
export async function execute(interaction) {
const notation = interaction.options.getString("notation");
// One seed per (guild, channel, user, interaction) — never reused.
const clientSeed = `g${interaction.guildId}_c${interaction.channelId}` +
`_u${interaction.user.id}_i${interaction.id}`;
const url = new URL("https://api.provable.io/api/dice");
url.searchParams.set("clientSeed", clientSeed);
url.searchParams.set("notation", notation);
const res = await fetch(url, {
headers: { "x-api-key": process.env.PROVABLE_KEY }
});
const { outcome, shortId } = await res.json();
await interaction.reply({
content: `🎲 \`${notation}\` → **${outcome.total}** ` +
`(${outcome.rolls.join(", ")})\n` +
`Verify: https://provable.io/o/${shortId}`,
});
}
Where this drops in
/roll— TTRPG dice via/api/dice./pick— random user, channel, or option via/api/pick./giveaway— winners from reaction lists via/api/pick(link the official rules to a pre-publishedserverHash)./raidloot— weighted drops from boss tables via/api/pickwith weights./coinflip— heads or tails via/api/intswithmin=1&max=2./randomuser— pick an active member for spotlights via/api/pick.
Why this is fair
- Per-interaction seeds. Building the
clientSeedfrom(guildId, channelId, userId, interactionId)guarantees seeds are never reused and the mapping is reproducible from public IDs. - Public permalinks. Embedding
https://provable.io/o/<shortId>in the bot reply turns "is your bot rigged?" into a closed conversation. - One key, one quota. The bot uses one Provable.io API key — the dashboard shows per-day rolls, top channels, and which command types dominate traffic.
Where it fits
- TTRPG communities running Pathfinder, D&D, indie systems.
- Esports / FGC servers doing fair seeding for tournament brackets.
- Streamer mod packs with giveaway / shout-out commands.
- Web3 community Discords running mint-day raffles or whitelist draws.