Skip to main content
Every delivery wraps its event in the envelope described in the Webhooks guide. This page lists the data object for each event type under api_version 2026-10-07. Fields can be added without a new version, so ignore fields you do not recognize; see Versioning.

Conventions

These rules hold for every event type, so they are stated once here.
  • Every data object carries organization_id, in addition to the envelope’s own organization_id.
  • Field names match the public API. A field that names the same thing as an API response field uses the same name: external_id, reward_id, status, provider_order_id.
  • Optional fields are omitted when absent. No field is ever sent as null. Treat a missing key and a null the same way when you parse.
  • Amounts are decimal strings, such as "100.00". face_value_minor is the one integer amount, because gift-card face values are integer minor units.
  • Related resources are named by their public id: redemption_id, reversal_id, reservation_id, event_id, fulfillment_id, fulfillment_account_id, reward_id.
Each event type is a movement event or a lifecycle event. The fields a family shares are listed once at the start of its section.

Movement events

A movement event announces one journal entry. Every journal action has exactly one movement event. A participant or group balance changes only through movement events that name it as the subject, the counterparty, or a transfer source or recipient, so those events reconstruct every participant and group balance. Program wallet balances cannot be reconstructed from webhooks, because prefunded issuance, voids, and settlement differences post to the wallet without an event naming it. Reconcile wallets with Get program balance or Get program statement. Every movement event carries these fields.

Target forms

Exactly one of participant_id or group_id identifies the account owner. The examples on this page show the participant form. The group form is identical, with group_id in place of participant_id. When the account owner is a program wallet, for example a CREDIT or DEBIT rule action with "target": {"type": "PROGRAM"}, the payload has neither participant_id nor group_id. Its program_id is both the program and the target. This is the program-wallet form. program.funded and program.burned always use it.

balance.credited

amount is the value credited. A credit or settlement into DEFERRED sends balance.credited with bucket: "DEFERRED". balance.matured follows when that value becomes spendable.

balance.debited

amount is the value debited.

balance.held and balance.released

balance.held announces value moving from AVAILABLE to HELD. balance.released announces value moving from HELD back to AVAILABLE. amount is the value moved. A fail or cancel of a pending redemption that releases live reserved value emits balance.released.

balance.voided

amount is the HELD value voided back to its source, the program wallet or system issuance. When the void request asked for more than the provisional rewards left under the reference, amount is the smaller amount that was voided.

balance.expired

amount is the total forfeited to breakage. One event covers every lot of one asset in one bucket that expired for the same participant or group in the same sweep. The expiration journal entry has no program, so program_id is omitted.

balance.matured

balance.matured announces lots in DEFERRED reaching matures_at and moving to AVAILABLE. One event can cover several lots of the same asset for the same participant, group, or program wallet, including lots that different programs issued for a shared asset. amount is the total that became spendable. When programs share an asset, one event can include lots that different programs issued:
The meaning of the top-level program_id depends on the target: Read issuer_programs to see how much of amount each program issued. An endpoint subscribed to balance.matured receives the event for every program in your organization. A lot whose expires_at has already passed is forfeited by expiration and sends balance.expired instead of maturing.

balance.redeemed

balance.redeemed announces the REDEMPTION journal entry of a redemption. amount is the value redeemed. An instant redemption spends from AVAILABLE. A pending redemption that is captured spends from HELD. journal_entry_id matches the redemption’s journal_entry_id for an instant redemption and its capture_journal_entry_id for a capture.

balance.forfeited

balance.forfeited announces a FORFEIT journal entry: Forfeit participant balance, Forfeit group balance, or a FORFEIT rule action. amount is the value forfeited to breakage. A forfeit whose filters matched no lots posts no journal entry and sends nothing. Expiration forfeits send balance.expired instead.

balance.reversed

balance.reversed announces a REVERSAL journal entry. Exactly one of redemption_id or event_id names what was reversed, and it tells you which way the value moved. amount is the value this entry moved.

transfer.completed

amount is the total moved out of the source, which is the sum of the recipient amounts.

program.funded and program.burned

Both always use the program-wallet form. program.funded announces value entering a program wallet from system issuance. program.burned announces value leaving a program wallet to system breakage. amount is the value funded or burned. There are no fields beyond the shared set.

Lifecycle events

A lifecycle event announces a resource changing state. It carries the resource id, the resource’s status where it has one, and the ids of related resources. It never carries a journal entry id; the matching movement event does.

redemption.pending, redemption.completed, redemption.failed, and redemption.cancelled

The four redemption status events share one shape, built from the redemption resource.
redemption.pending
redemption.failed
Each redemption status event pairs with one movement event:

redemption.reversed

This event leads with the reversal. It pairs with balance.reversed carrying the same redemption_id.

redemption.fulfillment_succeeded and redemption.fulfillment_failed

redemption.fulfillment_succeeded
redemption.fulfillment_failed
These events announce the outcome of a gift-card order. They never carry a claim link or any other credential. Retrieve the card’s URL with Create a claim link after success.

fulfillment_account.funds_low

Sent the first time a gift-card order enters AWAITING_FUNDS because the fulfillment account could not cover it. Add funds to the account in the dashboard; Scrip then retries the order. Repeated low-balance responses for the same fulfillment do not send another alert. If the funding window ends before the account is funded, the order fails with failure_reason: "insufficient_funds" and redemption.fulfillment_failed follows. See Handle a pending order. This event never carries a claim link.

fulfillment_account.status_changed

Sent when a fulfillment account’s status changes: onboarding progresses, the account is approved or rejected, you enable or disable it, or it needs to be reconnected. This event never carries a session URL or credential. Reconnect or remove the account in the dashboard.

reward.status_changed

previous_status and status are always different; a same-status write produces no event. Creating a reward does not send this event. See Reward status events for what triggers it.

participant.created

participant.tier_changed

Exactly one of participant_id, group_id, or program_id identifies the target of the tier change. When the target is a program, program_id is both the target and the program. The SET_TIER rule action can target groups and programs through its target field, so do not assume the target is a participant.

event.completed

event.failed

event.reversed

One event per reversal. Each line that recovered value pairs with one balance.reversed carrying the same event_id.
For endpoint setup, signature verification, and retry behavior, see the Webhooks guide.