Skip to main content
A reference is a unique string you attach to an action that moves money. It is your idempotency key. If the same request reaches us twice with the same reference, we execute it once. Retries are normal. Networks time out, workers restart, and users press Send twice. Without a reference, each of those repeats a payout. With one, each repeat is harmless. This guide covers how to design references and how to deduplicate on your side.

Where duplicates come from

Four causes produce almost every duplicate: None of these are faults in your code. They are properties of distributed systems, and the reference is the defense against all four.

Design a reference

Make references unique, stable, and readable.
Follow four rules:
  1. Generate the reference before the first attempt, and store it with the intent.
  2. Include a type prefix, such as payout_, trade_, or card_.
  3. Include enough entropy to avoid collision, such as a date and a short random suffix.
  4. Reuse the same reference for every retry of the same business action.
Never generate a new reference on retry. A new reference is a new action, and it will execute a second time.
On card calls, a reference can contain only letters, digits, hyphens, and underscores. A bare timestamp such as 1689731218712 or a bare UUID satisfies uniqueness but tells you nothing in a log. A readable prefix pays for itself during an incident.

Deduplicate on your side

We enforce the reference. You still need your own check, because your system also processes each event. Record the key before you act, and check it before you act again. For a webhook, the key is event_id. Several events can share one reference, so don’t use reference there. For your own requests and jobs, the key is the reference.
Put this check in three places:
  • Your webhook handler, using event_id.
  • Your user-facing send or payment endpoint, using the reference.
  • Your asynchronous job processors, using the reference.

Store references in a dedicated table

A dedicated table gives you a fast uniqueness check, an audit trail, and the data behind a replay tool.

Lock across concurrent workers

A check followed by a write is not atomic. If two workers run the check at the same moment, both pass it. Take a lock, either in your database:
Or in Redis:
SET ... NX succeeds only if the key is absent. Treat a failed SET as “another worker owns this reference”.

Where references appear

Send a reference on every endpoint that moves value: The reference comes back on the object and on the webhook event. That is what lets you match our record to yours.

Handle a duplicate response

What a reused reference does depends on the endpoint: In every case, generate the reference before the first attempt and never mint a new one for a retry. A UUID is fine, as long as you store it against the transaction before the first attempt. See Errors and retries.

Worked example

A user requests a payout. Your service does the following:
1

Create and store the reference

Generate payout_20260408_a41f9c and write it to your database with status pending.
2

Submit the payout

Call Initialize payout with that reference. The call times out.
3

Retry with the same reference

Submit the identical request. We recognize the reference and return the original result. Nothing executes twice.
4

Receive the webhook

We send payouts.withdrawal.success carrying the same reference and a new event_id. Your handler checks the event_id, finds it unprocessed, and marks the payout delivered.
5

Receive the webhook again

A retried delivery arrives with the same event_id. Your handler finds it already processed and returns 200 without acting.

Avoid these patterns

Not storing the reference. If you cannot search your logs by reference, you cannot answer a support question, and neither can we. Generating references inside a retry loop. Each attempt then becomes a separate payout. Treating every request as new. Any system that assumes each call is unique will duplicate money movement under retry.

Summary

Next

Continue to Webhooks and event handling, which covers how to receive and verify the events that carry your references back.