Designing Fair Promotions: Rate Limits and Eligibility Logic
It was 11:57 p.m. We set a “one-night boost” live. The idea was simple: a small bonus for the next 60 minutes. At 12:03 a.m., support broke. Users could not claim. Others claimed twice. A few got blocked with no reason on screen. Some said the rules were not clear. Trust fell overnight. That mess was not about a big budget. It was about design. In this guide, we fix that.
What “fair” means (for users, for you, for law)
Fair is not a vibe. Fair has shape. It means: rules are clear, the result is the same for people in the same case, and a person can ask for a review if they think we got it wrong. For users, fair means no tricks and no hidden limits. For the business, fair means you protect the offer, do not burn trust, and can explain each call. For law and ads rules, fair means your promo terms are not unfair, false, or hard to read. See the FTC guidance on promotions and the UK ASA/CAP rules on promotional marketing for plain rules on claims, terms, and how to avoid misleading ads.
Field note: If a user must read a long PDF to know if they can join, you already lost. Use a short rules box at the top. Put the full terms one click away.
Design in the right order: eligibility first, then the “fun” bits
Most teams start with art, copy, and big numbers. Do the opposite. Start with eligibility. That is, who may join, when, and under what limits. Only then shape the UX and the message. Think in layers:
- Identity: per legal person (KYC entity), not just per account.
- History: past claims, chargebacks, bans, prior wins, past abuse flags.
- Channel: email, SMS, push, on-site, partner link.
- Geo and rules: country, state, age, license scope.
- Time: claim window, cool-down after a claim, start and end time.
Anti-pattern: “New users only” with no KYC check. It invites multi-account abuse. Tie “new user” to a KYC entity, not just an email.
Rate limits are not just “X per user”
Rate limits should match your risk map. Yes, per-user limits help. But abuse comes from many paths: device farms, shared IPs, stolen cards, or bots. Use more than one unit at once, and make the logic clear. When you block due to high request rate, speak the truth. If you return HTTP 429, follow the spec for retry hints (see HTTP 429 (Too Many Requests)). For system design tips, the OWASP rate limiting cheat sheet is a solid base, and here are some Cloudflare rate limiting best practices on patterns and pitfalls.
Promo patterns vs rate-limit levers (table)
| Signup bonus | Multi-accounting, device farm, stolen cards | Per KYC entity; per device; per payment method | 1 claim per KYC per 30 days; 3 attempts per device / 24h | Soft deny on first fail; captcha after 2 fails | 72h; ID re-verify; card proof | Rule version; device hash; BIN; IP/ASN; geo |
| Refer-a-friend | Self-referral, fake users, bot signups | Per KYC pair; per device; per IP/ASN rep | Max 1 reward per pair; 10 refs per KYC / 30 days | Progressive cool-down; audit if surge >3x median | 48h; proof of unique person; KYC checks | Referrer ID; referee ID; ref source; session ID |
| Time-boxed boost | Botting at start, script refresh spam | Per session; per device; per IP burst | 1 claim per session; 20 req per IP / 10 min | Exponential backoff; queue token | 24h; screen shot + server request ID | Request ts; rate bucket; 429 count; retry-after |
| High-value risk promo | Arbitrage, collusion, chargebacks | Per KYC; per payment; per geo; per campaign | 1 claim / campaign; manual review if risk score > T | Shadow deny + ask for docs; allowlist after check | 5 days; source of funds; KYC level | Risk score; features; reviewer ID; decision note |
| Winback / reactivation | Churn farm loops, shared devices | Per KYC; per device; per email domain | Once per 90 days per KYC; 2 attempts / device / 7 days | Soft cap with grace window; captcha on 3rd try | 72h; proof of account control | Last active ts; cohort ID; device hash |
| Partner / cross-sell | Coupon leaks, mass redemption | Per code; per referrer; per IP/ASN | Code cap (e.g., 5k); 1 per KYC; 10 per IP / 24h | Rotate codes; throttle by ASN rep | 48h; receipt / partner ID | Code; partner ID; ASN; ref URL |
| Free spins / credits (regulated) | Bonus abuse, VPN, multi-account | Per KYC; per device; per geo license | 1 claim / 7 days; block if geo mismatch | Ask for KYC step-up; show reason on deny | 72h; KYC proof; geo confirm | License region; device hash; KYC level |
Note: numbers here are guides. You must test with your data and risk level. Start strict in shadow mode. Then tune.
Edge cases you will meet on day one
- Shared homes and dorms: many users on one IP. Do not hard-block only by IP.
- Public Wi‑Fi: coffee shops can look like bot farms. Mix IP with device and KYC.
- VPN: watch for large ASN ranges and fast country flips.
- Family devices: same device used by two KYC users. Track per KYC too.
- One-time cards or wallets: tie claims to payment owner, not just success.
- Dynamic IP regions: build a grace band, not a binary cut.
Decision trade-off: A strict limit blocks abuse and a few good users. A loose limit lets abuse in and hurts trust later. Start with a soft wall (captcha, short wait), then step up.
Signals vs rules vs models
Rules are great when the abuse is simple and the cost is low. Use signals and scores when you see patterns across many features (device, IP rep, time, spend). Use models when scale and noise grow and you need rank, not yes/no. Always log the features you used so you can explain the call later. For API risks and common attack paths, review the OWASP API Security Top 10.
Field note: If you cannot explain a deny in one short line of text, your rule is too complex or your log is too thin.
The decision diary: log, explain, and allow appeals
Every promo claim should make a small paper trail you can read: request ID, user ID, KYC level, rule version, risk score, final path, and a one-line reason. If you deny, show a short reason in simple words. Give a clear appeal path, a time window (for example, 72 hours), and a list of proof you will accept. Store the state you used at the time, not just the user now. That way, your support and legal team can check past calls.
Privacy, law, and how to stay clear
Use the smallest set of data you need. Tell users why you need it. Keep it safe. Follow local law. For core rules on fair use of data, see GDPR Article 5. For a design frame on privacy risk, the NIST Privacy Framework is a good map. If you work with real-money promos, know your license zone, and make sure your terms are easy to read and fair (see the UK Gambling Commission guidance on fair terms).
Anti-pattern: Hide key limits in long legal text. Use a short list with the key rules up front: who can join, how many times, time window, and how to appeal.
From spec to rollout: test without losing trust
Do not ship hard walls on day one. Use a “shadow rules” phase: compute the deny, log it, but still allow. Check the false deny rate with a sample. Then move to a small canary, like 1–5% of users. Keep guardrails: a max deny rate, a max 429 rate, and an auto roll-back if you cross the line. If you run A/B tests, be clear with users, and protect them. For deeper craft on good tests, see Trustworthy Online Controlled Experiments.
The honesty metrics: measure what users feel
- Eligibility pass rate by cohort (new, winback, high risk).
- Hard denies vs soft challenges.
- Appeal rate, appeal win rate, and time to close.
- 429 rate, average retry-after, and queue wait time.
- Repeat participation after first deny.
- Promo NPS or a short “Was this fair?” score.
For system health, track the well-known “golden signals” (latency, errors, traffic, saturation). The Google SRE ‘golden signals’ page has a clear guide.
Case notes: regulated promos (real money, gambling)
Regulated promos need extra care. KYC binds the user to a legal person. Limits must be per KYC entity, not just per email. Geo must map to license. Terms must avoid “traps” like unclear play-through or hard-to-meet time bars. Show the key rules in plain words on the first screen. If you run bonus credits or free spins, show the wagering need, the max cash-out, and the end date in one short line.
Before you launch a bonus, it helps to check how others phrase their terms in plain words. A neutral source can help you spot unclear parts. For a live view of operator terms and bonus styles, you can look at https://casino-gambling-network.com/. Use it as a benchmark to make sure your own copy is clear, and to see common user pain points across brands.
Responsible play note: Set age checks. Promote safe play. Share help links. Never push users to chase losses. Let users opt out of promo emails with one click.
Reference design: minimal flow that holds up
Here is a simple flow that most teams can ship fast and keep safe:
- Receive claim request with idempotency key.
- Load user KYC, geo, device, past claims, and risk score snapshot.
- Check eligibility rules (license, age, new/returning, channel).
- If fail, return soft deny with clear reason and appeal link.
- Else, check rate limits across units (KYC, device, IP/ASN, payment).
- If hit limit, return 429 with Retry-After or show queue ETA.
- If pass, issue reward atomically and write a durable log with rule version and reason.
- Return success + show next steps (use window, any play-through, end date).
For the coupon and code side of things, the Stripe promotion codes guide shows solid patterns on idempotency and limits.
Copy that avoids confusion (and tickets)
- Say who can join in one clear line: “New users with verified ID in [region]”.
- Say the limit: “One claim per person (ID check), per 30 days”.
- Say the time: “From 12:00 to 14:00 local time, today”.
- Say the path to appeal: “If this looks wrong, appeal within 72h here”.
- Say the reason on deny: “We blocked this due to too many tries from this device”.
Field kit: how to pick thresholds
Start with your abuse rate now. Pick a target (for example, cut by 50%). Choose units that match the main abuse path. Add a small grace band to avoid edge pain. Pilot in shadow. Run a small canary. Watch appeal rate and win rate. If appeals win a lot, your rules are too strict or unclear.
Checklist you will use
- Write a one-page spec: goal, risk map, key rules, limits, and who can appeal.
- Bind “person” to KYC entity for all “new user” or “once only” promos.
- Use at least two limit units (e.g., KYC + device) for any cash-like promo.
- Return 429 with Retry-After for rate blocks; log the reason string.
- Show key rules up front; put full T&Cs one click away.
- Log request ID, rule version, features used, and final reason.
- Run a two-week shadow phase; then a small canary with guardrails.
- Set an appeal SLA (e.g., 72h) and train support on proofs to accept.
- Track deny rate, appeal rate, 429s, NPS/fairness score, and repeat take-up.
- Re-test after each big change; keep a change log.
FAQ (short and real)
Q: What is a fair rate limit?
A: One that stops abuse with the least pain to good users. It is clear, has a backoff or queue, and tells users what to do next.
Q: How do I explain a deny?
A: In one line, with a cause and a next step: “We saw too many tries from this device. Please wait 10 minutes or complete ID check.”
Q: Do I need models?
A: Not at first. Start with rules and good logs. Add scores or models when scale and noise rise and you need rank, not a hard cut.
Further reading and templates
- RFC 9110: HTTP 429, Retry-After, and semantics (link above).
- OWASP sheets for API and rate limits (links above).
- NIST, GDPR, and UKGC links (above) for fair and legal terms.
- Ask for the “Promo patterns vs rate-limit levers” table as CSV to seed your spec.
About the author
I design promos and anti-abuse systems for high-risk and regulated products. I work with product, risk, legal, and support teams. I like clear rules, small safe steps, and logs that tell a story.
Legal note
This article is for information only. It is not legal advice. Check your local law and license rules before you launch any promo.
