Recipient events

The recipient.* family, covering the entitlement as a whole, its running balance, and the four transitions we notify on.

recipient.* events report the entitlement as a whole, meaning everything one recipient was granted by a payout order and how much of it is left.

Payout events tell you about one gift card or one crypto send. Recipient events tell you where the person stands. They carry the running balance, so you can follow progress across several redemptions without calling the API.

They fire for any payout order with a callback_url. See Subscribing.

Events

EventStatusFires when
recipient.viewedviewedThe recipient opened their claim link for the first time.
recipient.partially_redeemedpartially_redeemedThe recipient redeemed some of their balance and some remains.
recipient.redeemedredeemedThe entitlement is fully redeemed. Terminal.
recipient.expiredexpiredThe entitlement lapsed with balance unspent. Terminal.

pending and sent emit nothing. See Events we do not send.

📘

partially_redeemed fires once, not once per redemption

The event marks the transition, so re-entering the same status does not re-emit. A recipient redeeming three gift cards in a row produces one recipient.partially_redeemed, not three.

For per-card granularity use payout.fulfilled, which fires every time.

Body

The subject is the recipient, and subject_type is "recipient".

The GIFQ envelope, plus the wallet balance.

FieldTypeNotes
initial_amountNumberThe full amount the recipient was granted, in currency.
remaining_amountNumberUnredeemed balance at the moment of the event, in currency.
currencyStringThe recipient's wallet currency.

The gift-card keys payout_uuid, brand_uuid, brand_name, and amount are not on this body, because they belong to a specific card. Crypto data is not here either.

🚧

payout_type can be null

payout_type carries the recipient's effective type, which stays unresolved until they choose one. On a campaign offering both crypto and gift cards, a recipient.viewed can arrive with payout_type: null, meaning the recipient opened the link without picking a method yet. Later events resolve it.

Do not branch on payout_type being non-null in this domain.

Balances and FX

initial_amount and remaining_amount are always in the recipient's wallet currency.

A gift card redeemed in another currency gets converted, so remaining_amount will not equal initial_amount minus the face value of the cards you saw on payout.fulfilled. Take balances from these events and card denominations from payout events. Deriving one from the other will not add up.

Examples

Partially redeemed, with £25 of £75 spent:

{
  "event": "recipient.partially_redeemed",
  "payout_order_uuid": "11111111-2222-3333-4444-555555555555",
  "recipient_email": "[email protected]",
  "recipient_uuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "recipient_name": "Alice Doe",
  "subject_type": "recipient",
  "status": "partially_redeemed",
  "updated_at": "2026-05-21T10:05:00Z",
  "payout_type": "gift_cards",
  "initial_amount": 75.0,
  "remaining_amount": 50.0,
  "currency": "GBP",
  "sent_at": "2026-05-20T09:00:00Z",
  "viewed_at": "2026-05-21T10:00:00Z",
  "expires_at": "2026-08-20T09:00:00Z"
}

Expired with £50 unspent:

{
  "event": "recipient.expired",
  "payout_order_uuid": "11111111-2222-3333-4444-555555555555",
  "recipient_email": "[email protected]",
  "recipient_uuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "recipient_name": "Alice Doe",
  "subject_type": "recipient",
  "status": "expired",
  "updated_at": "2026-08-20T09:00:01Z",
  "payout_type": "gift_cards",
  "initial_amount": 75.0,
  "remaining_amount": 50.0,
  "currency": "GBP",
  "sent_at": "2026-05-20T09:00:00Z",
  "viewed_at": "2026-05-21T10:00:00Z",
  "expires_at": "2026-08-20T09:00:00Z"
}

What to do on receipt

recipient.viewed. The claim link works and the person is engaged. Useful for suppressing reminders. payout_type may still be null.

recipient.partially_redeemed. Update the balance you show. More is coming.

recipient.redeemed. Terminal, nothing remains. For gift cards this arrives with the final payout.fulfilled, written in the same transaction. For crypto it arrives when the send completes.

recipient.expired. Terminal, and the one that costs you money if you ignore it. remaining_amount was never spent and the entitlement is gone. If you debited your end users up front, this is your signal to credit them back.

📘

Expiry arrives in bursts

Recipients on one order usually share an expiry window, so a single sweep can enqueue a delivery for every recipient at once. We cap deliveries at 5 per second per account, so they arrive spread out and unordered.

Sort on updated_at, and size this handler for the burst rather than the average.

Relationship to payout events

Here is one gift-card recipient's full stream, in causal order.

recipient.viewed              → opened the link
  payout.processing           → card #1 requested
  payout.fulfilled            → card #1 issued
recipient.partially_redeemed  → £25 of £75 spent
  payout.processing           → card #2 requested
  payout.fulfilled            → card #2 issued
recipient.redeemed            → balance exhausted

Arrival order will differ from causal order. Sort on updated_at.