SendReward

← All guides

How to stop people claiming the same reward twice

It happens in every kind of reward program. A customer claims your promotion on their laptop and their phone. A participant takes your survey twice. Someone signs up for your referral bonus under two email addresses. Either way you paid twice for one thing. Here is how to make that structurally hard, whether you send rewards from a spreadsheet or from code.

Updated October 2026 · 7 min read

Two kinds of duplicate — and only one of them is fraud

Before reaching for fraud controls, it helps to separate two very different problems that both end in "we paid twice."

The first is technical duplication. Your script retried after a timeout and sent a second reward. Someone double-clicked "send." You re-ran last week's campaign file by mistake. This is by far the most common cause, it is entirely your own systems' fault, and it is completely preventable with the right identifiers.

The second is deliberate double-claiming. One person claims the same offer twice using two email addresses, or joins your program twice, to collect two rewards. This is real fraud, it is harder to stop, and no payment platform can fully solve it for you — because the platform only sees an email address and an amount, not a human being.

The good news: the same basic tool — a unique identifier per recipient — defends against the first problem completely and makes the second much harder. Start there.

The one rule that prevents most of it: a unique reference

Every reward in SendReward can carry a reference: your own identifier for that payment, up to 128 characters. A customer ID, an order number, a participant code, or a user ID plus an event name like user-4412-referral-bonus. SendReward stores it, lets you search and filter by it, and — crucially — will not create a second reward for a reference it has already seen.

That single rule kills technical duplication outright. If your script retries, or your file gets uploaded twice, the second attempt is recognised and held back instead of paying again. You do not have to build any of this yourself; you just have to pass a reference that is unique per payment you intend to make.

If you send from a spreadsheet (no code)

The campaign flow has a reference column for exactly this reason. Fill it with your customer code, order number or participant ID, and duplicates within or across campaigns are caught.

None of this requires a developer. It is a column in a spreadsheet.

If you send from code (API)

Developers get two layers of protection, and you should use both.

Idempotency keys

Send an Idempotency-Key header with any value unique to that reward — an order number, a user ID plus event name, a claim ID. If the same key arrives again, whether from a retry, a duplicate webhook on your side, or a double-submit, SendReward returns the original reward with a 200 and an Idempotent-Replayed: true header, and sends nothing new.

curl https://sendreward.com/api/v1/rewards \
  -H "Authorization: Bearer sr_live_…" \
  -H "Idempotency-Key: order-88213" \
  -H "Content-Type: application/json" \
  -d '{"recipient_email":"maria@example.com","amount":10,"reference":"order-88213"}'

The difference between the two fields is worth understanding. The Idempotency-Key protects a single request from being processed twice — it is about network retries and double-clicks. The reference is your business identifier for the payment, and it protects against the same logical payment being made twice, even days apart. Set both, to the same value if you like.

Idempotent webhook handling

When SendReward tells you a reward was redeemed, the same event can arrive more than once. Handle events by their id and ignore ones you have already processed, so a redelivered webhook does not trigger a second action on your side — like crediting an account twice.

Retry safely. Because idempotency keys are stored, the correct way to handle any timeout or 500 is simply to retry with the same key. You will either get the original reward back or a clean new one — never a silent double charge.

Defending against deliberate double-claiming

Now the harder problem: one human, two identities. No payment platform can see this for you, but your program design can. The controls below are cheap and effective in combination.

What SendReward does — and does not — do for you

We want to be precise, because "fraud prevention" gets oversold.

ControlSendReward
Block a second reward for the same referenceYes
Block a retried API request (idempotency key)Yes
Cancel an unredeemed duplicate and refund itYes
Search and filter rewards by your referenceYes
Identity verification / fraud scoringNo
Detect one person behind two emailsNo
Know whether a claim is genuineNo

In plain terms: we guarantee you will not pay the same reference twice, and we give you the tools to make your own identity rules work. We do not decide who is a real customer or participant — that is a program-design problem, and the checklist above is how you solve it.

Frequently asked questions

What is the simplest way to stop duplicate rewards?

Give every recipient a unique reference — a customer ID, an order number, a participant code, a user ID plus an event name. SendReward will not create a second reward for a reference it has already seen, so running the same list twice cannot pay anyone twice.

Does that work for the spreadsheet/campaign flow too?

Yes. The reference column in your campaign file does the same job. If two rows share a reference, the duplicate is held back rather than sent.

What is an idempotency key and do I need one?

It is a header (Idempotency-Key) you send with an API request so that a retry after a timeout does not create a second reward. If you use the API, you should always send one. If you only use the dashboard or campaigns, you never touch it.

Can SendReward tell me if the same person is using two email addresses?

No. We prevent the same reference or idempotency key from paying twice, but we do not do identity verification or fraud scoring. Catching one human behind two addresses is up to how you design your program — we cover how below.

Does a duplicate cost me anything?

Not if it is blocked by a reference or idempotency key — no reward is created and nothing is charged. If a duplicate does slip through as a genuine second reward, you can cancel it before it is redeemed and the full amount returns to your balance.

Send rewards that can't double-pay.

Free account, $1,000 test balance, unique references built in.

Get started free

Related: Paying survey participants · API idempotency reference · Why we don't charge a platform fee