Twitch Watch-Drops: Setup & Integration
A watch-drop rewards viewers for watching your stream: hit a watch-time tier, claim a reward. The reward is non-tradable — it's an in-game item you grant, not a resellable asset — which keeps it squarely inside Twitch's rules. The real win is acquisition: every claim provisions the viewer a wallet on the spot, so a watch-drop turns your stream audience into onboarded players. You build one campaign; every creator who runs it funnels new wallets to you.
This guide is the full integration: set up the campaign, then wire the one webhook that lets you grant the reward.
The loop
viewer watches your stream ─▶ crosses a watch-time tier ─▶ claims (instant)
│ (FlipKey provisions a wallet = the signup;
│ the soulbound ticket mints in the background)
▼
viewer REDEEMS the ticket in their FlipKey library (burn)
▼
FlipKey POSTs a SIGNED handoff to your webhook ─▶ you grant the item ─▶ you ack
FlipKey.gg verifies a real viewer and provisions the wallet; you grant the item on your side. FlipKey.gg never holds your keys or items.
Part 1 — Set up watch-time tracking on Twitch
Pick one of two gates when you create the campaign:
A) Twitch Drops (recommended — real entitlements). Uses Twitch's official Drops system, so watch-time is measured by Twitch and can't be spoofed.
- In the Twitch Developer Console, create an Organization (if you don't have one).
- Create a Drops Campaign under that org and link it to your game.
- Add a reward / benefit for each watch-time tier (e.g. 60 min, 120 min). Twitch gives each a Benefit ID — copy these.
- Note the Campaign ID. You'll paste the campaign + benefit IDs into the FlipKey.gg builder.
FlipKey.gg subscribes to Twitch's drop.entitlement.grant events for your org/campaign and maps each Benefit ID to the matching FlipKey.gg tier. (Wiring the subscription is a one-time step we run for you during onboarding.)
B) Presence (lighter, no Drops campaign). A FlipKey.gg chat bot polls who's watching. Simpler to start, but presence is a softer signal than official Drops.
- Link your Twitch channel to FlipKey.gg (one-time
!linkin your chat). - Make the FlipKey.gg bot a moderator on your channel (needed to read chatters).
Part 2 — Create the campaign in FlipKey.gg
Go to Watch Drops in the dashboard and create a campaign:
- Title — e.g. "Launch Week Drops".
- Creator wallet — the broadcaster's linked wallet.
- Gate — Twitch Drops or Presence (Part 1).
- Campaign ID — paste from Twitch (Drops gate only).
- Tiers (one or more):
- Watch minutes (e.g. 60, 120, 180)
- Reward — pick one of your items
- Quota — how many to give out at this tier
- Benefit ID — paste from Twitch (Drops gate only)
Creating the campaign reserves its reward budget from your mint credits — the sum of your tier quotas is checked up front (your first 1,000 promotional mints are free; beyond that they're $0.02 each, prepaid). You don't pre-grant anything else. Creating campaigns needs the minting role (or admin) on your team. The campaign is live; viewers can now earn.
Part 3 — Receive the handoff (the only code you write)
A viewer's claim mints them a soulbound ticket (instantly accepted;
the on-chain mint settles in the background). The handoff fires when they
redeem that ticket in their FlipKey.gg library — the ticket burns and FlipKey.gg
POSTs a signed item_ticket.redeem event to your webhook. Use the
Watch-Drop Handoff SDK (zero-dependency Node):
const express = require("express");
const flipkey = require("./flipkey-watchdrop");
app.post(
"/flipkey/watchdrop",
express.raw({ type: "application/json" }), // ← required for signature verify
flipkey.expressHandler({
secret: process.env.FLIPKEY_WEBHOOK_SECRET, // dashboard → Webhooks
apiKey: process.env.FLIPKEY_API_KEY, // to ack fulfillment
onClaim: async (claim) => {
const player = await myDb.playerByFlipkeyAccount(claim.flipkey_account_id);
await myGame.grantItem(player, claim.reward_drop_id); // idempotent on claim.redemption_id
return `granted:${claim.redemption_id}`; // opaque receipt
},
})
);
Then set your webhook URL to https://yourgame.com/flipkey/watchdrop
on the dashboard Webhooks page. That's the whole integration.
Don't assume game ownership. Watch-drop claims come from viewers,
many of whom don't own your game yet — that's the acquisition funnel working, not an error
(a viewer holding your skin is a buyer-to-be). By the time the handoff reaches you the ticket
is already burned, so never reject a claim because the account doesn't own the
game: respond 200, park the grant in the account's inventory (idempotently), and
let the game pick it up whenever they show up. A non-2xx response just makes FlipKey.gg retry the
delivery — the player's ticket stays spent either way.
The handoff you receive:
{
event: "item_ticket.redeem",
redemption_id, // opaque id — use as your idempotency key
reward_drop_id, // the reward to grant
item_name, // display name of the item
flipkey_account_id, // stable account key — map to YOUR player
wallet_address, // the viewer's wallet (same value)
amount, // units redeemed (1)
burn_tx_hash, // on-chain burn of the consumed ticket
connected: true // connection is a redeem precondition
}
X-FlipKey-Signature = HMAC-SHA256(rawBody, webhook_secret). The SDK verifies it —
which is why the route uses express.raw(), not express.json(). Make
onClaim idempotent on redemption_id: FlipKey.gg retries on any
non-2xx response, so a duplicate handoff must not double-grant.
Part 4 — Mapping a claim to your player
You decide who gets the item using flipkey_account_id — a stable key for that
player. Two ways to hold the map:
- Connect once (recommended). The player does a one-time "Connect <Game>"
that gives you their
flipkey_account_id; you storeflipkey_account_id → your player id. After that, every future drop auto-delivers with zero re-linking — the retention hook. FlipKey.gg keeps only a pointer; the map lives on your side, and FlipKey.gg hosts the consent page (players can withdraw consent there). - Connection is guaranteed at handoff time. Redeeming requires the player
to have connected first, so every handoff you receive already has a mapping waiting on your
side —
connectedis alwaystrue.
By design, FlipKey.gg never sends a raw game/player id and never stores your player map. This keeps a database breach a non-event — there's no cross-platform identity graph to steal. Details: the pass-through-broker model.
Part 5 — Test it before you go live
- Set your webhook URL + grab your webhook secret and API key (Webhooks page).
- Run the reference server (
examples/handoff-server.jsin the SDK) and point a tunnel (e.g. ngrok) at it, or deploy it. - Use the "Send test" button on the Webhooks page to confirm signature verification works against your endpoint.
- Run a short presence-gate campaign on a test channel to exercise the full earn → claim → handoff → grant loop end-to-end.
What you need from us
During onboarding we'll: wire your Twitch EventSub subscription (Drops gate) or bot moderator access (presence gate), confirm your webhook secret, and walk the first test campaign with you. Reach out and we'll get you a sandbox campaign.
Guidance only — not legal, financial, or tax advice. Publishers are responsible for their own compliance and for honoring Twitch's Drops and developer terms.