Skip to content

Webhook events

Every event has this shape, and data depends on type:

{ id: string; type: WebhookEventType; data: … }

id is stable across retries and replays, so deduplicate on it.

Event Sent when Delivery
credits.earned An earn was accepted, and is still pending Best-effort
credits.earn.confirmed The chain confirmed an earn Exactly one per transaction is queued
credits.redemption.confirmed The chain confirmed a spend, for checkout or a paid voucher Exactly one per transaction is queued
credits.reversed A confirmed earn or redemption was reversed Queued with the reversal
voucher.redeemed A voucher serial was used Queued with the redemption

Queued events can still be retried, so your receiver may see the same id more than once.

An earn is on its way to the chain. Wait for credits.earn.confirmed before treating the points as spendable.

Field Type Description
transactionId string
organizationEndUserId string
purchaseAmount number
estimatedPoints number An estimate, not the credited amount
newBalance number Confirmed balance, which doesn’t include this earn yet
Field Type Description
transactionId string
organizationEndUserId string
pointsAmount number The amount actually credited on-chain
newBalance number Confirmed balance right after this transaction
blockchainDigest string

Has the same fields as credits.earn.confirmed, where pointsAmount is the amount debited.

Settled in the ledger immediately. A chain-confirmed original is also mirrored on-chain afterwards, which sends no separate event.

Field Type Description
reversalTransactionId string
reversedTransactionId string
organizationEndUserId string
pointsAmount number
newBalance number
balanceWentNegative boolean True when reversing a spent earn left a debt

No points move here. A paid claim already sent credits.redemption.confirmed for its cost.

Field Type Description
voucherOwnershipId string
voucherId string
organizationEndUserId string
serialCode string
status string REDEEMED
redeemedAt string
voucherTitle string
discountType string
discountValue string | null