This page lists the exact fields in every webhook event. It is the companion to Events and member synchronization, which covers the catalog, the envelope, and how the pieces fit together; come here when you need the precise shape of one event's data block.
Each group opens with one generated example, then a table per event. Types read as follows: member is the two-value member object (id plus unique_identifier), string (UUID) a record id, integer a whole number, and business time the timezone-plus-date object. Both the member object and business time are described on the events page. "Null" tells you whether the field can be JSON null. A field declared for an event is always present; when a value does not apply, or an older record never stored it, it is null rather than absent.
Event payloads
Points and rewards payloads
A points.transferred example:
{
"card_id": "822570e3-f2b1-4b08-851c-e16ca3beac0f",
"sender": {
"id": "c54f3c5a-2470-4b38-be0c-786af120164a",
"unique_identifier": "SAMPLE-0001"
},
"receiver": {
"id": "1f6654d5-f0a2-4481-940b-ba74dc76d3b6",
"unique_identifier": "SAMPLE-0001"
},
"sender_transaction_id": "d3b28ee5-6b69-4baa-bb28-f8041f0c67c9",
"receiver_transaction_id": "e1fba76f-105a-4dbc-bc0b-e79936270e0d",
"points_transferred": 20,
"source": "member"
}
points.earned
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The member whose balance increased |
card_id |
string (UUID) |
Never |
The loyalty card |
points |
integer |
Never |
Points added by this ledger entry |
purchase_amount |
integer |
Yes |
Purchase amount in minor units; null for points-only credit. Kept for backward compatibility |
transaction_id |
string (UUID) |
Never |
The ledger entry |
ledger_event |
string |
Never |
A fixed code naming the kind of credit, for example staff_credited_points_for_purchase; unknown_legacy for an old entry with no known code |
source |
string |
Yes |
A fixed channel code such as staff, agent_api, partner_rest, shopify, woocommerce, system, or member; null for older entries |
balance_after |
integer |
Never |
The member's spendable balance after this entry |
purchase_amount_minor |
integer |
Yes |
Purchase amount in minor units; null for points-only credit |
currency |
string |
Yes |
ISO 4217 code for the amounts; null when no money is involved |
points.spent
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The member whose balance decreased |
card_id |
string (UUID) |
Never |
The loyalty card |
points |
integer |
Never |
The change, always negative on this event |
purchase_amount |
integer |
Yes |
Purchase amount in minor units when one applies; null on most deductions |
transaction_id |
string (UUID) |
Never |
The ledger entry |
event |
string |
Never |
The raw ledger event string, for example staff_redeemed_points_for_reward. The original field on this event, unchanged |
ledger_event |
string |
Never |
The same information as a fixed code; unknown_legacy for an old entry with no known code |
source |
string |
Yes |
A fixed channel code; null for older entries |
balance_after |
integer |
Never |
The member's spendable balance after this entry |
purchase.recorded
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The buying member |
card_id |
string (UUID) |
Never |
The loyalty card |
transaction_id |
string (UUID) |
Never |
The purchase ledger entry |
purchase_amount_minor |
integer |
Yes |
The sale amount in minor units; null when no amount was recorded |
currency |
string |
Yes |
ISO 4217 code; null when no amount was recorded |
points_awarded |
integer |
Never |
Points this purchase earned |
source |
string |
Never |
One of staff, agent_api, partner_rest, shopify, woocommerce, system |
business_time |
business time |
Never |
The business's calendar context for the sale |
points.adjusted
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The adjusted member |
card_id |
string (UUID) |
Never |
The loyalty card |
transaction_id |
string (UUID) |
Never |
The adjustment ledger entry |
direction |
string |
Never |
credit or debit |
points_adjusted |
integer |
Never |
The size of the adjustment, never negative |
points_delta |
integer |
Never |
The signed balance change |
balance_after |
integer |
Never |
The balance after the adjustment |
source |
string |
Never |
One of staff, agent_api, partner_rest |
reason_code |
string |
Never |
A fixed reason code such as staff_adjustment; never free text |
points.reversed
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The member losing the points |
card_id |
string (UUID) |
Never |
The loyalty card |
transaction_id |
string (UUID) |
Never |
The reversal ledger entry |
original_transaction_id |
string (UUID) |
Yes |
The credit being reversed; null when a refund cannot name a single original |
points_reversed |
integer |
Never |
Points removed, never negative |
points_delta |
integer |
Never |
The signed balance change |
balance_after |
integer |
Never |
The balance after the reversal |
source |
string |
Never |
One of staff_void, voucher_void, shopify_refund, woocommerce_refund, system |
reason_code |
string |
Never |
A fixed reason code; never the free-text void note |
points.expired
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The member whose points expired |
card_id |
string (UUID) |
Never |
The loyalty card |
transaction_id |
string (UUID) |
Never |
The expiry ledger entry |
points_expired |
integer |
Never |
Points that expired, never negative |
points_delta |
integer |
Never |
The signed balance change |
balance_after |
integer |
Never |
The balance after the expiry |
expired_at |
string |
Never |
UTC instant of the expiry |
business_time |
business time |
Never |
The business's calendar context for the expiry |
This event is the only signal for expiry; an expiry never sends points.spent.
points.transferred
| Field |
Type |
Null |
Meaning |
card_id |
string (UUID) |
Never |
The loyalty card both members share |
sender |
member |
Never |
The sending member |
receiver |
member |
Never |
The receiving member |
sender_transaction_id |
string (UUID) |
Never |
The sender's ledger entry |
receiver_transaction_id |
string (UUID) |
Never |
The receiver's ledger entry |
points_transferred |
integer |
Never |
Points moved |
source |
string |
Never |
Always member |
Sent once per transfer. The receiver's points.earned and the sender's points.spent arrive as separate deliveries under the same correlation_id.
points.code_redeemed
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The redeeming member |
card_id |
string (UUID) |
Never |
The loyalty card |
transaction_id |
string (UUID) |
Never |
The credit ledger entry |
redemption_code_id |
string (UUID) |
Yes |
The stored code record; null only for an old entry that never recorded it. The redeemable code value itself is never sent |
points_awarded |
integer |
Never |
Points the code granted |
balance_after |
integer |
Never |
The balance after the credit |
reward.redeemed
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The redeeming member |
card_id |
string (UUID) |
Never |
The loyalty card |
reward_id |
string (UUID) |
Yes |
The redeemed reward; null only for an old hand-written entry |
transaction_id |
string (UUID) |
Never |
The redemption ledger entry |
points_spent |
integer |
Never |
The reward's cost, never negative |
points_delta |
integer |
Never |
The signed balance change |
balance_after |
integer |
Never |
The balance after the redemption |
Stamps payloads
A stamp.expired example:
{
"member": {
"id": "dbc26b96-3344-41f0-8e25-e9ba7850e33d",
"unique_identifier": "SAMPLE-0001"
},
"stamp_card_id": "9547be32-f42c-4578-a7f7-1e2e983d2241",
"transaction_id": "cb4131c1-6e9d-4bab-97ee-c823f04276b6",
"stamps_expired": 6,
"stamps_delta": -6,
"stamps_after": 0,
"expired_at": "2026-07-10T03:00:00Z",
"business_time": {
"timezone": "Europe/Amsterdam",
"local_date": "2026-07-10"
}
}
stamp.added
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The member earning stamps |
stamp_card_id |
string (UUID) |
Never |
The stamp card |
stamps |
integer |
Never |
Stamps added by this action |
stamps_after |
integer |
Never |
The member's stamp count after it |
ledger_event |
string |
Never |
stamp_earned for a normal earn, stamps_bonus for a bonus recorded by an older version |
source |
string |
Yes |
staff or agent_api; null for older entries |
stamp_card.completed
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The completing member |
stamp_card_id |
string (UUID) |
Never |
The stamp card |
completion_count |
integer |
Never |
The member's lifetime completions of this card, including this one |
stamp.reward_redeemed
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The redeeming member |
stamp_card_id |
string (UUID) |
Never |
The stamp card |
transaction_id |
string (UUID) |
Never |
The redemption entry |
completion_count |
integer |
Yes |
The member's lifetime completions; null only for an old entry that no longer resolves |
pending_rewards_after |
integer |
Yes |
Earned rewards still waiting after this redemption; null only for an old entry that no longer resolves |
stamp.adjusted
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The adjusted member |
stamp_card_id |
string (UUID) |
Never |
The stamp card |
transaction_id |
string (UUID) |
Never |
The adjustment entry |
stamps_delta |
integer |
Never |
The signed stamp change |
stamps_after |
integer |
Never |
The stamp count after it |
reason_code |
string |
Never |
A fixed reason code; the staff note never leaves the platform |
stamp.voided
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The member |
stamp_card_id |
string (UUID) |
Never |
The stamp card |
original_transaction_id |
string (UUID) |
Never |
The stamp entry being reversed |
void_transaction_id |
string (UUID) |
Never |
The reversing entry |
stamps_delta |
integer |
Never |
The signed stamp change the void applied |
stamps_after |
integer |
Never |
The stamp count after it |
reason_code |
string |
Never |
A fixed reason code |
stamp.expired
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The member whose stamps expired |
stamp_card_id |
string (UUID) |
Never |
The stamp card |
transaction_id |
string (UUID) |
Never |
The expiry entry |
stamps_expired |
integer |
Never |
Stamps that expired, never negative |
stamps_delta |
integer |
Never |
The signed stamp change |
stamps_after |
integer |
Never |
The stamp count after it |
expired_at |
string |
Never |
UTC instant of the expiry |
business_time |
business time |
Never |
The business's calendar context |
Vouchers payloads
A voucher.issued example:
{
"member": {
"id": "748d9494-82de-41c3-aca8-3257881e216a",
"unique_identifier": "SAMPLE-0001"
},
"voucher_id": "faf2c99b-1eeb-49f6-a2fa-aa2921535240",
"source_voucher_id": "22b5a0e3-3810-4d81-a49c-a83cbee6faaa",
"source": "birthday",
"issued_at": "2026-07-10T03:15:00Z",
"valid_from": "2026-07-10T00:00:00Z",
"valid_until": "2026-07-16T23:59:59Z",
"business_time": {
"timezone": "Europe/Amsterdam",
"local_date": "2026-07-10"
}
}
voucher.redeemed
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The redeeming member |
voucher_id |
string (UUID) |
Never |
The voucher |
redemption_id |
string (UUID) |
Never |
The redemption record; the anchor to deduplicate on |
discount_amount_minor |
integer |
Never |
The applied discount in minor units |
currency |
string |
Yes |
ISO 4217 code; null when the redemption carried no currency |
points_awarded |
integer |
Yes |
Voucher-bonus points credited in the same operation; null when none |
order_amount_minor |
integer |
Yes |
The order total in minor units when the redemption carried one; null otherwise |
The voucher code value is never sent.
voucher.claimed
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The claiming member |
voucher_id |
string (UUID) |
Never |
The voucher |
source |
string |
Never |
One of qr_batch, member_wallet, deferred_wallet, redemption_auto_attach, wallet_pass |
claimed_at |
string |
Never |
UTC instant of the claim |
valid_until |
string |
Yes |
The voucher's expiry; null when open-ended |
Sent once per new voucher-member relationship. Re-saving a voucher the member already holds sends nothing.
voucher.issued
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The receiving member |
voucher_id |
string (UUID) |
Never |
The voucher the member received |
source_voucher_id |
string (UUID) |
Yes |
The template voucher for a birthday or win-back gift; null for a tier reward |
source |
string |
Never |
One of tier, birthday, winback |
issued_at |
string |
Never |
UTC instant of the issuance |
valid_from |
string |
Yes |
Start of validity; null when unrestricted |
valid_until |
string |
Yes |
End of validity; null when open-ended |
business_time |
business time |
Never |
The business's calendar context |
voucher.redemption_voided
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The member whose redemption was voided |
voucher_id |
string (UUID) |
Never |
The voucher |
redemption_id |
string (UUID) |
Never |
The voided redemption record |
voided_at |
string |
Never |
UTC instant of the void |
uses_restored |
integer |
Never |
Uses handed back, one per redemption |
reason_code |
string |
Never |
A fixed reason code; never the staff note |
voucher.exhausted
| Field |
Type |
Null |
Meaning |
voucher_id |
string (UUID) |
Never |
The voucher |
times_used |
integer |
Never |
Total recorded uses at the crossing |
max_uses_total |
integer |
Never |
The voucher's total-use limit |
exhausted_at |
string |
Never |
UTC instant of the crossing |
A shared voucher has no single member, so this event carries no member field.
Passes payloads
A pass.issued example:
{
"member": {
"id": "fb5d5784-8be5-4f77-8b98-5aa4f7407414",
"unique_identifier": "SAMPLE-0001"
},
"member_pass_id": "07df8be8-9243-4425-93a0-85d5183c8e6f",
"prepaid_pass_id": "2eeb0db3-819f-4649-829c-22489d055e8b",
"uses_total": 10,
"price_minor": 8900,
"currency": "EUR",
"valid_from": "2026-07-10T12:00:00Z",
"valid_until": "2026-08-08T21:59:59Z",
"business_time": {
"timezone": "Europe/Amsterdam",
"local_date": "2026-07-10"
}
}
pass.issued
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The member receiving the pass |
member_pass_id |
string (UUID) |
Never |
The member's pass instance |
prepaid_pass_id |
string (UUID) |
Never |
The pass product |
uses_total |
integer |
Yes |
The pass size; null for an unlimited pass |
price_minor |
integer |
Yes |
The recorded price in minor units; null when unknown |
currency |
string |
Yes |
ISO 4217 code; null when no price was recorded |
valid_from |
string |
Yes |
Start of the validity window; null when unrestricted |
valid_until |
string |
Yes |
End of the validity window; null for an open-ended pass |
business_time |
business time |
Never |
The business's calendar context |
pass.used
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The member using the pass |
member_pass_id |
string (UUID) |
Never |
The member's pass instance |
uses |
integer |
Never |
Visits deducted by this action |
uses_remaining |
integer |
Yes |
Visits left; null for an unlimited pass |
transaction_id |
string (UUID) |
Never |
The use ledger entry |
prepaid_pass_id |
string (UUID) |
Never |
The pass product |
status |
string |
Never |
The pass status after the use; used_up on the final deduction |
pass.use_voided
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The member |
member_pass_id |
string (UUID) |
Never |
The member's pass instance |
prepaid_pass_id |
string (UUID) |
Never |
The pass product |
transaction_id |
string (UUID) |
Never |
The reversing entry |
original_transaction_id |
string (UUID) |
Never |
The use being reversed |
uses_restored |
integer |
Never |
Visits handed back |
uses_remaining |
integer |
Yes |
Visits left after the void; null for an unlimited pass |
status |
string |
Never |
The pass status after the void; a void can revive a used-up pass |
reason_code |
string |
Never |
A fixed reason code |
pass.used_up
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The member |
member_pass_id |
string (UUID) |
Never |
The member's pass instance |
prepaid_pass_id |
string (UUID) |
Never |
The pass product |
trigger_transaction_id |
string (UUID) |
Never |
The final use's ledger entry; that use also sends pass.used under the same correlation_id |
uses_total |
integer |
Never |
The pass's full size |
used_up_at |
string |
Never |
UTC instant of the final use |
pass.expired
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The member |
member_pass_id |
string (UUID) |
Never |
The member's pass instance |
prepaid_pass_id |
string (UUID) |
Never |
The pass product |
transaction_id |
string (UUID) |
Never |
The expiry marker entry |
uses_remaining |
integer |
Yes |
Visits left when the window closed; null for an unlimited pass |
valid_until |
string |
Never |
The validity window that closed |
expired_at |
string |
Never |
UTC instant of the expiry |
business_time |
business time |
Never |
The business's calendar context |
Members and tiers payloads
A member.tier_changed example:
{
"member": {
"id": "b1e4f069-9b21-4b0c-b2f4-063209f55deb",
"unique_identifier": "SAMPLE-0001"
},
"club_id": "c90d4040-dfdf-43bb-a608-924ea876bdd6",
"previous_tier_id": "c4051af7-a81e-4e8b-8069-3827c4dff110",
"previous_level": 1,
"new_tier_id": "6148c869-6af9-4b87-ab2a-cf71d44cf394",
"new_level": 2,
"direction": "upgraded",
"changed_at": "2026-07-10T17:45:00Z"
}
member.enrolled
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The joining member |
card_id |
string (UUID) |
Never |
Present for a loyalty card enrollment; then stamp_card_id is absent |
stamp_card_id |
string (UUID) |
Never |
Present for a stamp card enrollment; then card_id is absent |
Exactly one of card_id or stamp_card_id is present, never both.
member.unenrolled
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The leaving member |
program_type |
string |
Never |
loyalty or stamp |
program_id |
string (UUID) |
Never |
The card or stamp card |
source |
string |
Never |
member or staff |
stamps_lost |
integer |
Yes |
Stamps removed by leaving; an integer for stamp programs (0 when progress is preserved), null for loyalty programs |
pending_rewards_lost |
integer |
Yes |
Earned rewards removed by leaving; same rule as stamps_lost |
member.tier_changed
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The member |
club_id |
string (UUID) |
Never |
The club whose tiers apply |
previous_tier_id |
string (UUID) |
Yes |
The tier left behind; null on a first assignment |
previous_level |
integer |
Yes |
Its level; null on a first assignment |
new_tier_id |
string (UUID) |
Never |
The new tier |
new_level |
integer |
Never |
Its level |
direction |
string |
Never |
One of assigned, upgraded, downgraded |
changed_at |
string |
Never |
UTC instant of the change |
Tier names are edited, translated labels, so they make unstable machine keys; the payload carries ids and levels instead.
Member cards payloads
A member_card.disabled example:
{
"member": {
"id": "3ae5af8f-d735-4110-9154-ae94c959f594",
"unique_identifier": "SAMPLE-0001"
},
"member_card_id": "2d64f9a3-4c02-456d-8d37-77a31c6d7d1a",
"disabled_at": "2026-07-10T17:45:00Z",
"reason_code": "partner_disabled",
"status": "disabled"
}
member_card.issued
| Field |
Type |
Null |
Meaning |
member |
member |
Yes |
The linked member for a personalized card; null for a blank card minted in a batch |
member_card_id |
string (UUID) |
Never |
The card record. The only card identifier a webhook carries |
issued_at |
string |
Never |
UTC instant of issuance |
status |
string |
Never |
The card status |
member_card.claimed
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The member who claimed the card |
member_card_id |
string (UUID) |
Never |
The card record |
claimed_at |
string |
Never |
UTC instant of the claim |
status |
string |
Never |
The card status |
member_card.disabled
| Field |
Type |
Null |
Meaning |
member |
member |
Yes |
The linked member; null when the card was still unclaimed |
member_card_id |
string (UUID) |
Never |
The card record |
disabled_at |
string |
Never |
UTC instant of the disable |
reason_code |
string |
Never |
One of partner_disabled, replaced, security, privacy_removal, unspecified_legacy |
status |
string |
Never |
Always disabled |
The physical card number, its QR value, and its claim link never appear in any webhook.
Privacy payloads
The member.relationship_removed example:
{
"member": {
"id": "1e3bddd3-de01-4d1c-9707-b2fbcbb1f89c",
"unique_identifier": "SAMPLE-0001"
},
"removal_id": "6fb25576-db8e-4d03-8d05-8b6e2afbebe5",
"scope": "partner_relationship",
"requested_at": "2026-07-10T17:45:00Z"
}
member.relationship_removed
| Field |
Type |
Null |
Meaning |
member |
member |
Never |
The minimal identifiers of the member whose data was deleted |
removal_id |
string (UUID) |
Never |
The deletion operation; the anchor to deduplicate on |
scope |
string |
Never |
Always partner_relationship |
requested_at |
string |
Never |
UTC instant of the deletion |