Idempotency
Sending a gift moves money. If a request times out, you cannot know whether the order was placed — so retrying it blind risks sending the same person two gifts and paying twice.
externalReference solves that.
How it works
Section titled “How it works”Put a value from your own system on the send:
{ "productId": 184, "value": 25.00, "externalReference": "q4-bonus-2026-aisha", "recipients": [{ "email": "aisha@example.com" }]}It is stamped on the order and must be unique for your customer. Send the same value again — whatever else the request carries — and the call is rejected:
{ "error": "An order with that external reference already exists."}The value is echoed back on every successful send, so you can reconcile it against your own records.
Choosing a reference
Section titled “Choosing a reference”It should be derivable from the thing you are sending a gift for, so that a retry of the same logical operation produces the same reference:
const externalReference = `bonus-${payrollRunId}-${employeeId}`Good choices:
- A UUID generated once per logical send and stored with it before the call
- A composite of ids from your own system, as above
- The id of the row in your own outbox table
Avoid anything that changes between attempts — a timestamp, Math.random(), a retry counter. Those
make the reference useless, because the retry will not collide.
At most 128 characters.
Retrying safely
Section titled “Retrying safely”async function sendGift(body) { const res = await fetch('https://api.1up.gift/send/gift', { method: 'POST', headers: { Authorization: `Bearer ${process.env.API_KEY}`, 'Content-Type': 'application/json', }, body: JSON.stringify(body), })
if (res.status === 409) { // Already placed on an earlier attempt. Not an error. return { alreadySent: true } }
if (!res.ok) throw new Error((await res.json()).error)
return await res.json()}Opting out
Section titled “Opting out”Omit externalReference, or send it blank, and no uniqueness check is applied. Do that only when
duplicate sends genuinely do not matter.
