What it is

A weighted prize wheel built on /api/pick. Pass the segment labels (10% off, free shipping, $5 credit, grand prize) and segment weights (their angular share of the wheel), and the API returns the winning segment plus a serverHash a player can verify after the spin.

The wheel animation in the UI is purely visual; the segment that lands under the pointer is whichever segment the API selected.

The pain point

Spin-to-win promotions get accused of two things: "the grand prize never actually lands" and "the wheel landed on what the promotion needed for margin." Both accusations vanish when the segment weights are public and the per-spin outcome is verifiable. The wheel becomes UI decoration over a transparent calculation.

Try it live — one spin on a 6-segment wheel

curl "https://api.provable.io/api/pick?clientSeed=spin_user_42_2026_05_25_001&items=10pct_off,20pct_off,free_ship,5_credit,try_again,grand_prize&weights=35,15,25,15,9.5,0.5"

A second spin (different nonce → independent outcome):

curl "https://api.provable.io/api/pick?clientSeed=spin_user_42_2026_05_25_002&items=10pct_off,20pct_off,free_ship,5_credit,try_again,grand_prize&weights=35,15,25,15,9.5,0.5"

Integration snippet

// 1. Publish the wheel segments + weights on a public /wheel-rates page.
const WHEEL = [
  { id: "10pct_off",   weight: 35.0 },
  { id: "20pct_off",   weight: 15.0 },
  { id: "free_ship",   weight: 25.0 },
  { id: "5_credit",    weight: 15.0 },
  { id: "try_again",   weight:  9.5 },
  { id: "grand_prize", weight:  0.5 },
];

async function spin(userId, spinIndex) {
  const url = new URL("https://api.provable.io/api/pick");
  url.searchParams.set("clientSeed", `spin_${userId}_${spinIndex}`);
  url.searchParams.set("items",   WHEEL.map((s) => s.id).join(","));
  url.searchParams.set("weights", WHEEL.map((s) => s.weight).join(","));

  const res = await fetch(url, {
    headers: { "x-api-key": process.env.PROVABLE_KEY }
  });
  const { outcome: segmentId, index, serverHash, shortId } = await res.json();

  // 2. Drive the wheel animation toward segmentId at index `index`.
  //    The UI rotation is cosmetic — the result is already decided.
  return { segmentId, serverHash, permalink: `/o/${shortId}` };
}

Why this is fair

Common patterns

Where it fits

Related