Score this redemption
The per-request Risk Score (0-100) on the session reaching for the reward, live in the webhook.
Count accounts behind the device
The Abuse Patterns that tie many accounts to one device or one local IP, read from the dashboard or reconstructed from history.
Where this differs from signup
The signup recipe scores the account at the moment it is created. That stops the obviously anonymous registration, but a patient farm creates accounts slowly and quietly, each one clean on its own, and only cashes them in later. The reward moment is where the farm reveals itself: ten “different” customers redeeming the same coupon from one machine is a shape that no single clean signup ever shows. So run both. Score at signup to thin the farm early, and check again at redemption to count how many accounts that one device or local IP has actually used to claim the reward.Step 1: score the redemption session
Add the snippet to the page where the reward is claimed (the cart with the coupon applied, the “start trial” screen, the bonus-claim button). Re-identify on the action itself so you score the session that is redeeming, not a stale page load. Pass the account’s hashed id, never a raw email.redeem.html
requestID. The score arrives on the webhook, so cache it by RequestID and read it back with the shared waitForScore helper defined in the cookbook overview, or fall back to a History API read by request_id.
api/redeem.js
Step 2: count the accounts behind the device and the local IP
A bonus farm clears cookies and goes incognito between accounts to look new every time. The score on each individual redemption can look fine. What gives it away is the count: how many distinct accounts has this one device, or this one local IP, already used to claim the reward? Two Abuse Patterns answer exactly that, and ShieldLabs grades each flagged entity Suspicious or Dangerous. An entity that crosses no threshold stays the unflagged baseline and is never recorded.Many Accounts on One Device
Many Accounts on One Device
One device linked to many different accounts: the classic bonus-farm shape. The grouping identity is the DeviceID, which is durable and browser-bound. It survives a cookie clear, an incognito window, and an IP rotation, so clearing storage does not reset the link. Suspicious at 3 to 5 accounts in a month, Dangerous at 6 or more.
Many Accounts on One Local IP
Many Accounts on One Local IP
Many accounts redeeming through the same local IP, even when each session uses a fresh cookie and a different public IP. Catches the farm sitting behind one router or one NAT. Suspicious at 3 in 24 hours, 4 to 5 in 7 days, or 6 to 9 in 30 days; Dangerous at 4 or more in 24 hours, 6 or more in 7 days, or 10 or more in 30 days.
Count it live at redemption
For the reward decision you often want the count right now, not on the next pattern run. Read the History API bydevice_id to reconstruct every account that device has touched. Each snapshot carries the UserHID for that session, so the number of distinct UserHID values is the number of accounts behind the machine.
Read a device's history
Gate the reward on account count
The History API bills 1 request per returned row, and an empty result still bills 1, while the webhook delivery is free. For high-volume redemption flows, lean on the pattern export as your denylist and reserve live
device_id reads for the rewards that are expensive to give away by mistake.Weigh the device count with the local IP
A determined operator who uses several genuinely separate browsers shows up as several devices, because the DeviceID is browser-bound. That is the gap the device count alone leaves open. Close it by weighing three things together: the “Many Accounts on One Device” signal, the “Many Accounts on One Local IP” signal, and your own redemption limits on the code or campaign. A reward claimed by ten accounts that share one local IP is a strong shape even when each one reports a different device, and a coupon you have capped at one redemption per customer does not need a perfect farm detector to hold the line.Putting it together
Wire the signup gate first
Join accounts to the DeviceID at registration with the signup recipe so the farm is already thinned before it reaches the reward.
Score the redemption session
Load the snippet on the claim page and call
checkAuthenticatedUser on the action, following the snippet setup.Cache the score and read it back
Receive the webhook, verify the HMAC, and read the result with the shared
waitForScore helper from the cookbook overview.Count accounts behind the device and local IP
Check the redeeming device against the “Many Accounts on One Device” and “Many Accounts on One Local IP” exports, or count distinct
UserHID values from a live device_id history read.Recommended starting thresholds
The four bands are defined in Risk Scoring, and the per-band playbook lives in Acting on the Risk Score. Mapped to a reward gate, with the account count layered on top:| Signal at redemption | Suggested reward action |
|---|---|
| Clean / Low score, no pattern flag | Grant the reward |
| Medium score, no pattern flag | Grant, but log and watch the device |
| High score | Require verification before granting |
| Device or local IP flagged Suspicious | Require verification, regardless of the session score |
| Device or local IP flagged Dangerous | Deny the reward and route to review |
Next: Acting on the Risk Score
The full per-band decision playbook, including Details-aware decisioning and how to combine the score with specific signals.