Skip to content
Developer docs
⌘ K
Dashboard ↗

HTTP endpoints

approveReward

POST /api/v1/rewards/{id}/approve

Requires rewards:approve. Keep the Bearer key on your server.

SDK

ts
grizzlee.approveReward(id: string): Promise<Reward>

HTTP

Use your backend's HTTP client. The cURL request shows the wire format. Replace path parameters and example values.

sh
curl --fail-with-body --request POST \
  'https://app.grizzlee.ca/api/v1/rewards/{id}/approve' \
  -H "Authorization: Bearer $GRIZZLEE_SERVER_KEY"

Response

HTTP responses wrap this value in data. The SDK returns the value directly unless the note above describes a wrapper.

FieldTypeRequiredDetails
idstringYes
companyIdstringYes
orderIdstringNoThe order that earned the reward. Absent on milestone rewards.
milestonestringNoThe milestone that earned the reward. Absent on order rewards. Exactly one of the two is set.
reportEventIdstringNoEach-report rewards name their source. Absent on at-count bonuses.
milestoneReportReversedunionNo
valueCentsnumberNo
milestoneCountnumberNoMilestone rewards: the person's reports of the milestone that count for this program now, those at or after the referral minus reversed ones. Grizzlee updates it with every report, reversal, revocation and reinstatement for the person and milestone. Absent on rewards no milestone event has touched since milestones were counted.
milestoneRevokedunionNoMilestone rewards: true while the milestone is revoked for the person. Updated with milestoneCount. Absent when not revoked, and on rewards no milestone event has touched since milestones were counted.
programIdstringYes
partnerIdstringYes
customerIdstringYes
currencyunionYes
rewardTypeunionYes
offerobjectNoOffer rewards only. Terms copied when earned. Later program edits leave them alone.
originalCentsnumberYesWhat the reward earned when it was created. Never changes.
adjustedCentsnumberNoSigned total that order adjustments added to or removed from originalCents. Absent until the order is adjusted. The reward is worth originalCents + adjustedCents - reversedCents.
reversedCentsnumberYesReversed by refunds, a rejection or a milestone revocation.
statusunionYes
selfReferralobjectNoPresent when the customer's identity signals matched the partner's. With action review the reward started pending and waits for someone to approve or reject it, and automatic approval skips it. With action flagged it follows the program's usual approval.
fraudobjectNoPresent when fraud rules fired. rules lists each rule ID with its signal types, never values. With action review the reward started pending, waits for someone to approve or reject it, and automatic approval skips it. With action flagged it follows the program's usual approval.
rejectedAtstringNoWhen someone rejected the pending reward. A rejected reward is reversed for good.
rejectionReasonstringNoWhy it was rejected, as entered.
statusBeforeReversalunionNoStatus the reward had when a refund fully reversed it. A later restoration returns it to this status.
deliveryModeunionNoDelivery mode when earned. Absent on older money rewards, which use the Grizzlee wallet. Absent on offer rewards. Readers ignore delivery for offers.
createdAtstringYes
availableAtstringYesRewards no longer have a hold, so new rewards use createdAt. Older rewards keep their original date.
programSnapshotobjectYes
programVersionnumberNoThe program version the reward was earned under. Absent on rewards earned before programs had versions. programSnapshot holds their rules either way.
historicalBasis"total"NoHistorical subtotal rewards keep their reporting-total basis for refunds and adjustments.
basisCentsnumberNo
explanationstringYes
explanationPartsarrayNoexplanation as codes. Absent on rewards earned before codes existed.
calculationobjectNo

milestoneReportReversed

Variant 1

Type: boolean.

Variant 2

Type: boolean.

milestoneRevoked

Variant 1

Type: boolean.

Variant 2

Type: boolean.

currency

Variant 1

Type: string.

Variant 2

Type: string.

Variant 3

Type: string.

Variant 4

Type: string.

rewardType

Variant 1

Type: string.

Variant 2

Type: string.

Variant 3

Type: string.

offer

FieldTypeRequiredDetails
offer.termsunionYes
offer.expiresAtunionYes

offer.terms

Variant 1

FieldTypeRequiredDetails
offer.terms.type"percent"Yes
offer.terms.rateBpsnumberYes
offer.terms.ordersnumberYesHow many of the friend's orders get the incentive.
offer.terms.expiresAfterDaysunionYesDays after the referral was captured, claimed or entered. null means it never expires.
offer.terms.returnOnFullRefundbooleanYestrue: a full refund gives the use back, so the customer can get the offer again.
offer.terms.maxDiscountCentsnumberNoLargest discount for one order.
offer.terms.minOrderCentsnumberNoThe friend's order total before the discount must reach this amount. Checked by the merchant's checkout.
offer.terms.orderCategoriesobjectNoOrder categories that get the discount. Checked apart from the program's own orderCategories, which decide rewards. Absent means every order qualifies.

offer.terms.expiresAfterDays

Variant 1

Type: null.

Variant 2

Type: number.

offer.terms.orderCategories

FieldTypeRequiredDetails
offer.terms.orderCategories.includearrayNo
offer.terms.orderCategories.excludearrayNo

Variant 2

FieldTypeRequiredDetails
offer.terms.type"fixed"Yes
offer.terms.ordersnumberYesHow many of the friend's orders get the incentive.
offer.terms.expiresAfterDaysunionYesDays after the referral was captured, claimed or entered. null means it never expires.
offer.terms.returnOnFullRefundbooleanYestrue: a full refund gives the use back, so the customer can get the offer again.
offer.terms.amountCentsnumberYes
offer.terms.minOrderCentsnumberNoThe friend's order total before the discount must reach this amount. Checked by the merchant's checkout.
offer.terms.orderCategoriesobjectNoOrder categories that get the discount. Checked apart from the program's own orderCategories, which decide rewards. Absent means every order qualifies.

offer.terms.expiresAfterDays

Variant 1

Type: null.

Variant 2

Type: number.

offer.terms.orderCategories

FieldTypeRequiredDetails
offer.terms.orderCategories.includearrayNo
offer.terms.orderCategories.excludearrayNo

offer.expiresAt

Variant 1

Type: null.

Variant 2

Type: string.

status

Variant 1

Type: string.

Variant 2

Type: string.

Variant 3

Type: string.

selfReferral

FieldTypeRequiredDetails
selfReferral.actionunionYes
selfReferral.signalsarrayYes

selfReferral.action

Variant 1

Type: string.

Variant 2

Type: string.

Variant 3

Type: string.

selfReferral.signals[]

Variant 1

Type: string.

Variant 2

Type: string.

Variant 3

Type: string.

Variant 4

Type: string.

Variant 5

Type: string.

Variant 6

Type: string.

fraud

FieldTypeRequiredDetails
fraud.actionunionYes
fraud.rulesarrayYes

fraud.action

Variant 1

Type: string.

Variant 2

Type: string.

Variant 3

Type: string.

fraud.rules[]

FieldTypeRequiredDetails
fraud.rules.actionunionYes
fraud.rules.ruleunionYes
fraud.rules.signalsarrayYesMatching signal types, never values. Empty for disposable_email.
fraud.rules.countnumberNoCustomers counted, this one included when referred inside the window. Velocity rules only.

fraud.rules.action

Variant 1

Type: string.

Variant 2

Type: string.

Variant 3

Type: string.

fraud.rules.rule

Variant 1

Type: string.

Variant 2

Type: string.

Variant 3

Type: string.

Variant 4

Type: string.

fraud.rules.signals[]

Variant 1

Type: string.

Variant 2

Type: string.

Variant 3

Type: string.

Variant 4

Type: string.

Variant 5

Type: string.

statusBeforeReversal

Variant 1

Type: string.

Variant 2

Type: string.

deliveryMode

Variant 1

Type: string.

Variant 2

Type: string.

programSnapshot

FieldTypeRequiredDetails
programSnapshot.currencyunionYesMust match the company currency.
programSnapshot.namestringYes
programSnapshot.kindunionYes
programSnapshot.rewardTypeunionYes
programSnapshot.attributionWindowDaysunionYesDays after a referral that a first purchase, or a milestone, still counts. The latest referral always wins until one qualifies. Only milestone programs may use null, which means the referral never expires.
programSnapshot.activebooleanYes
programSnapshot.orderCategoriesobjectNoOrder categories that earn rewards. Order programs only. The friend incentive has its own orderCategories. Absent means every order can earn.
programSnapshot.compensationunionNo
programSnapshot.trackingobjectNoTracking methods are independent of kind. Provider discounts require a connected provider.
programSnapshot.destinationUrlstringNoThe page partner links and QR codes open. A published signup page's destination takes precedence. Without either, partners have no link.
programSnapshot.displayobjectNoOptional public name, headline and milestone label for partner and customer screens.
programSnapshot.triggerunionNoWhat earns a reward. Defaults to completed orders.
programSnapshot.milestoneRewardsobjectNo
programSnapshot.fixedRefundModeunionNoHow fixed rewards change after a partial refund.
programSnapshot.durationunionNo
programSnapshot.deliveryobjectNoWho delivers approved rewards of each type. Defaults to the Grizzlee wallet for both.
programSnapshot.reviewRewardsunionNoWhen true, new rewards wait as pending until someone approves them. Otherwise they start approved.
programSnapshot.fraudChecksobjectNoSelf-referral and other fraud rules. Absent means every rule uses its default.
programSnapshot.performanceobjectNo
programSnapshot.limitsobjectNo
programSnapshot.customTermsarrayNo
programSnapshot.friendIncentiveunionNoOptional offer for the referred customer.
programSnapshot.partnerOfferunionNoOffer programs only. What the partner earns per qualifying referred order.

programSnapshot.currency

Variant 1

Type: string.

Variant 2

Type: string.

Variant 3

Type: string.

Variant 4

Type: string.

programSnapshot.kind

Variant 1

Type: string.

Variant 2

Type: string.

Variant 3

Type: string.

programSnapshot.rewardType

Variant 1

Type: string.

Variant 2

Type: string.

Variant 3

Type: string.

programSnapshot.attributionWindowDays

Variant 1

Type: null.

Variant 2

Type: number.

programSnapshot.orderCategories

FieldTypeRequiredDetails
programSnapshot.orderCategories.includearrayNo
programSnapshot.orderCategories.excludearrayNo

programSnapshot.compensation

Variant 1

FieldTypeRequiredDetails
programSnapshot.compensation.type"percentage"Yes
programSnapshot.compensation.rateBpsnumberYes
programSnapshot.compensation.phasesarrayNo

programSnapshot.compensation.phases[]

FieldTypeRequiredDetails
programSnapshot.compensation.phases.rateBpsnumberYes
programSnapshot.compensation.phases.afterMonthsnumberYes

Variant 2

FieldTypeRequiredDetails
programSnapshot.compensation.type"fixed"Yes
programSnapshot.compensation.amountCentsnumberYes

programSnapshot.tracking

FieldTypeRequiredDetails
programSnapshot.tracking.linksunionNo
programSnapshot.tracking.qrCodesunionNo
programSnapshot.tracking.attributionCodesunionNo
programSnapshot.tracking.providerPromoCodesunionNo

Variant 1

Type: boolean.

Variant 2

Type: boolean.

programSnapshot.tracking.qrCodes

Variant 1

Type: boolean.

Variant 2

Type: boolean.

programSnapshot.tracking.attributionCodes

Variant 1

Type: boolean.

Variant 2

Type: boolean.

programSnapshot.tracking.providerPromoCodes

Variant 1

Type: boolean.

Variant 2

Type: boolean.

programSnapshot.display

FieldTypeRequiredDetails
programSnapshot.display.enobjectNo
programSnapshot.display.fr-CAobjectNo
programSnapshot.display.hyobjectNo
programSnapshot.display.ruobjectNo

programSnapshot.display.en

FieldTypeRequiredDetails
programSnapshot.display.en.publicNamestringNoThe name partners and customers see. Falls back to the program name.
programSnapshot.display.en.headlinestringNoReplaces the generated headline, such as "Give 20%, get $10".
programSnapshot.display.en.milestoneLabelobjectNoMilestone programs only. What one report counts, such as one: "lesson", other: "lessons". In Russian, other is the genitive plural, such as "уроков", which reward terms put after "число".

programSnapshot.display.en.milestoneLabel

FieldTypeRequiredDetails
programSnapshot.display.en.milestoneLabel.onestringYes
programSnapshot.display.en.milestoneLabel.otherstringYes

programSnapshot.display.fr-CA

FieldTypeRequiredDetails
programSnapshot.display.fr-CA.publicNamestringNoThe name partners and customers see. Falls back to the program name.
programSnapshot.display.fr-CA.headlinestringNoReplaces the generated headline, such as "Give 20%, get $10".
programSnapshot.display.fr-CA.milestoneLabelobjectNoMilestone programs only. What one report counts, such as one: "lesson", other: "lessons". In Russian, other is the genitive plural, such as "уроков", which reward terms put after "число".

programSnapshot.display.fr-CA.milestoneLabel

FieldTypeRequiredDetails
programSnapshot.display.fr-CA.milestoneLabel.onestringYes
programSnapshot.display.fr-CA.milestoneLabel.otherstringYes

programSnapshot.display.hy

FieldTypeRequiredDetails
programSnapshot.display.hy.publicNamestringNoThe name partners and customers see. Falls back to the program name.
programSnapshot.display.hy.headlinestringNoReplaces the generated headline, such as "Give 20%, get $10".
programSnapshot.display.hy.milestoneLabelobjectNoMilestone programs only. What one report counts, such as one: "lesson", other: "lessons". In Russian, other is the genitive plural, such as "уроков", which reward terms put after "число".

programSnapshot.display.hy.milestoneLabel

FieldTypeRequiredDetails
programSnapshot.display.hy.milestoneLabel.onestringYes
programSnapshot.display.hy.milestoneLabel.otherstringYes

programSnapshot.display.ru

FieldTypeRequiredDetails
programSnapshot.display.ru.publicNamestringNoThe name partners and customers see. Falls back to the program name.
programSnapshot.display.ru.headlinestringNoReplaces the generated headline, such as "Give 20%, get $10".
programSnapshot.display.ru.milestoneLabelobjectNoMilestone programs only. What one report counts, such as one: "lesson", other: "lessons". In Russian, other is the genitive plural, such as "уроков", which reward terms put after "число".

programSnapshot.display.ru.milestoneLabel

FieldTypeRequiredDetails
programSnapshot.display.ru.milestoneLabel.onestringYes
programSnapshot.display.ru.milestoneLabel.otherstringYes

programSnapshot.trigger

Variant 1

FieldTypeRequiredDetails
programSnapshot.trigger.type"order"Yes

Variant 2

FieldTypeRequiredDetails
programSnapshot.trigger.type"milestone"Yes
programSnapshot.trigger.milestonestringYes

programSnapshot.milestoneRewards

FieldTypeRequiredDetails
programSnapshot.milestoneRewards.eachReportobjectNo
programSnapshot.milestoneRewards.atCountobjectNo

programSnapshot.milestoneRewards.eachReport

FieldTypeRequiredDetails
programSnapshot.milestoneRewards.eachReport.compensationunionYes
programSnapshot.milestoneRewards.eachReport.limitnumberNoAbsent means every counted report. Reversed reports do not count toward the limit.

programSnapshot.milestoneRewards.eachReport.compensation

Variant 1

FieldTypeRequiredDetails
programSnapshot.milestoneRewards.eachReport.compensation.type"fixed"Yes
programSnapshot.milestoneRewards.eachReport.compensation.amountCentsnumberYes

Variant 2

FieldTypeRequiredDetails
programSnapshot.milestoneRewards.eachReport.compensation.type"percentage"Yes
programSnapshot.milestoneRewards.eachReport.compensation.rateBpsnumberYes

programSnapshot.milestoneRewards.atCount

FieldTypeRequiredDetails
programSnapshot.milestoneRewards.atCount.amountCentsnumberYes
programSnapshot.milestoneRewards.atCount.countnumberYes

programSnapshot.fixedRefundMode

Variant 1

Type: string.

Variant 2

Type: string.

programSnapshot.duration

Variant 1

FieldTypeRequiredDetails
programSnapshot.duration.type"only_order"Yes

Variant 2

FieldTypeRequiredDetails
programSnapshot.duration.type"first_order"Yes

Variant 3

FieldTypeRequiredDetails
programSnapshot.duration.type"first_n_orders"Yes
programSnapshot.duration.countnumberYes

Variant 4

FieldTypeRequiredDetails
programSnapshot.duration.type"days"Yes
programSnapshot.duration.daysnumberYes

Variant 5

FieldTypeRequiredDetails
programSnapshot.duration.type"months"Yes
programSnapshot.duration.monthsnumberYes

Variant 6

FieldTypeRequiredDetails
programSnapshot.duration.type"lifetime"Yes

programSnapshot.delivery

FieldTypeRequiredDetails
programSnapshot.delivery.cashunionNo
programSnapshot.delivery.creditunionNo

programSnapshot.delivery.cash

Variant 1

Type: string.

Variant 2

Type: string.

programSnapshot.delivery.credit

Variant 1

Type: string.

Variant 2

Type: string.

programSnapshot.reviewRewards

Variant 1

Type: boolean.

Variant 2

Type: boolean.

programSnapshot.fraudChecks

FieldTypeRequiredDetails
programSnapshot.fraudChecks.selfReferralobjectNo
programSnapshot.fraudChecks.duplicateAccountsobjectNo
programSnapshot.fraudChecks.rapidRepeatsobjectNo
programSnapshot.fraudChecks.repeatCustomerobjectNo
programSnapshot.fraudChecks.disposableEmailobjectNo

programSnapshot.fraudChecks.selfReferral

FieldTypeRequiredDetails
programSnapshot.fraudChecks.selfReferral.actionunionNo

programSnapshot.fraudChecks.selfReferral.action

Variant 1

Type: string.

Variant 2

Type: string.

Variant 3

Type: string.

Variant 4

Type: string.

programSnapshot.fraudChecks.duplicateAccounts

FieldTypeRequiredDetails
programSnapshot.fraudChecks.duplicateAccounts.actionunionNo
programSnapshot.fraudChecks.duplicateAccounts.accountsnumberNoCustomers sharing one card or device that trigger the rule. This one counts when referred inside the window.
programSnapshot.fraudChecks.duplicateAccounts.windowDaysnumberNo
programSnapshot.fraudChecks.duplicateAccounts.ipAccountsunionNoCustomers sharing one IP address that trigger the rule. null leaves IP addresses out.

programSnapshot.fraudChecks.duplicateAccounts.action

Variant 1

Type: string.

Variant 2

Type: string.

Variant 3

Type: string.

Variant 4

Type: string.

programSnapshot.fraudChecks.duplicateAccounts.ipAccounts

Variant 1

Type: null.

Variant 2

Type: number.

programSnapshot.fraudChecks.rapidRepeats

FieldTypeRequiredDetails
programSnapshot.fraudChecks.rapidRepeats.actionunionNo
programSnapshot.fraudChecks.rapidRepeats.referralsnumberNoReferrals from one device that trigger the rule. This one counts when referred inside the window.
programSnapshot.fraudChecks.rapidRepeats.windowMinutesnumberNo
programSnapshot.fraudChecks.rapidRepeats.ipReferralsunionNoReferrals from one IP address that trigger the rule. null leaves IP addresses out.

programSnapshot.fraudChecks.rapidRepeats.action

Variant 1

Type: string.

Variant 2

Type: string.

Variant 3

Type: string.

Variant 4

Type: string.

programSnapshot.fraudChecks.rapidRepeats.ipReferrals

Variant 1

Type: null.

Variant 2

Type: number.

programSnapshot.fraudChecks.repeatCustomer

FieldTypeRequiredDetails
programSnapshot.fraudChecks.repeatCustomer.actionunionNo

programSnapshot.fraudChecks.repeatCustomer.action

Variant 1

Type: string.

Variant 2

Type: string.

Variant 3

Type: string.

Variant 4

Type: string.

programSnapshot.fraudChecks.disposableEmail

FieldTypeRequiredDetails
programSnapshot.fraudChecks.disposableEmail.actionunionNoA disposable address does not show a second person, so this rule cannot block.

programSnapshot.fraudChecks.disposableEmail.action

Variant 1

Type: string.

Variant 2

Type: string.

Variant 3

Type: string.

programSnapshot.performance

FieldTypeRequiredDetails
programSnapshot.performance.metricunionYes
programSnapshot.performance.tiersarrayYes
programSnapshot.performance.windowDaysnumberNo

programSnapshot.performance.metric

Variant 1

Type: string.

Variant 2

Type: string.

programSnapshot.performance.tiers[]

FieldTypeRequiredDetails
programSnapshot.performance.tiers.namestringYes
programSnapshot.performance.tiers.minValuenumberYes
programSnapshot.performance.tiers.bonusBpsnumberYes

programSnapshot.limits

FieldTypeRequiredDetails
programSnapshot.limits.customerCapCentsnumberNo
programSnapshot.limits.partnerCapCentsnumberNo

programSnapshot.customTerms[]

Variant 1

FieldTypeRequiredDetails
programSnapshot.customTerms.target"partner"Yes
programSnapshot.customTerms.targetIdstringYes
programSnapshot.customTerms.compensationunionNo
programSnapshot.customTerms.milestoneRewardsobjectNo
programSnapshot.customTerms.customerCapCentsunionNo
programSnapshot.customTerms.partnerCapCentsunionNo

programSnapshot.customTerms.compensation

Variant 1

FieldTypeRequiredDetails
programSnapshot.customTerms.compensation.type"percentage"Yes
programSnapshot.customTerms.compensation.rateBpsnumberYes
programSnapshot.customTerms.compensation.phasesarrayNo

programSnapshot.customTerms.compensation.phases[]

FieldTypeRequiredDetails
programSnapshot.customTerms.compensation.phases.rateBpsnumberYes
programSnapshot.customTerms.compensation.phases.afterMonthsnumberYes

Variant 2

FieldTypeRequiredDetails
programSnapshot.customTerms.compensation.type"fixed"Yes
programSnapshot.customTerms.compensation.amountCentsnumberYes

programSnapshot.customTerms.milestoneRewards

FieldTypeRequiredDetails
programSnapshot.customTerms.milestoneRewards.eachReportobjectNo
programSnapshot.customTerms.milestoneRewards.atCountobjectNo

programSnapshot.customTerms.milestoneRewards.eachReport

FieldTypeRequiredDetails
programSnapshot.customTerms.milestoneRewards.eachReport.compensationunionYes
programSnapshot.customTerms.milestoneRewards.eachReport.limitnumberNoAbsent means every counted report. Reversed reports do not count toward the limit.

programSnapshot.customTerms.milestoneRewards.eachReport.compensation

Variant 1

FieldTypeRequiredDetails
programSnapshot.customTerms.milestoneRewards.eachReport.compensation.type"fixed"Yes
programSnapshot.customTerms.milestoneRewards.eachReport.compensation.amountCentsnumberYes

Variant 2

FieldTypeRequiredDetails
programSnapshot.customTerms.milestoneRewards.eachReport.compensation.type"percentage"Yes
programSnapshot.customTerms.milestoneRewards.eachReport.compensation.rateBpsnumberYes

programSnapshot.customTerms.milestoneRewards.atCount

FieldTypeRequiredDetails
programSnapshot.customTerms.milestoneRewards.atCount.amountCentsnumberYes
programSnapshot.customTerms.milestoneRewards.atCount.countnumberYes

programSnapshot.customTerms.customerCapCents

Variant 1

Type: null.

Variant 2

Type: number.

programSnapshot.customTerms.partnerCapCents

Variant 1

Type: null.

Variant 2

Type: number.

Variant 2

FieldTypeRequiredDetails
programSnapshot.customTerms.target"customer"Yes
programSnapshot.customTerms.targetIdstringYes
programSnapshot.customTerms.compensationunionNo
programSnapshot.customTerms.milestoneRewardsobjectNo
programSnapshot.customTerms.customerCapCentsunionNo

programSnapshot.customTerms.compensation

Variant 1

FieldTypeRequiredDetails
programSnapshot.customTerms.compensation.type"percentage"Yes
programSnapshot.customTerms.compensation.rateBpsnumberYes
programSnapshot.customTerms.compensation.phasesarrayNo

programSnapshot.customTerms.compensation.phases[]

FieldTypeRequiredDetails
programSnapshot.customTerms.compensation.phases.rateBpsnumberYes
programSnapshot.customTerms.compensation.phases.afterMonthsnumberYes

Variant 2

FieldTypeRequiredDetails
programSnapshot.customTerms.compensation.type"fixed"Yes
programSnapshot.customTerms.compensation.amountCentsnumberYes

programSnapshot.customTerms.milestoneRewards

FieldTypeRequiredDetails
programSnapshot.customTerms.milestoneRewards.eachReportobjectNo
programSnapshot.customTerms.milestoneRewards.atCountobjectNo

programSnapshot.customTerms.milestoneRewards.eachReport

FieldTypeRequiredDetails
programSnapshot.customTerms.milestoneRewards.eachReport.compensationunionYes
programSnapshot.customTerms.milestoneRewards.eachReport.limitnumberNoAbsent means every counted report. Reversed reports do not count toward the limit.

programSnapshot.customTerms.milestoneRewards.eachReport.compensation

Variant 1

FieldTypeRequiredDetails
programSnapshot.customTerms.milestoneRewards.eachReport.compensation.type"fixed"Yes
programSnapshot.customTerms.milestoneRewards.eachReport.compensation.amountCentsnumberYes

Variant 2

FieldTypeRequiredDetails
programSnapshot.customTerms.milestoneRewards.eachReport.compensation.type"percentage"Yes
programSnapshot.customTerms.milestoneRewards.eachReport.compensation.rateBpsnumberYes

programSnapshot.customTerms.milestoneRewards.atCount

FieldTypeRequiredDetails
programSnapshot.customTerms.milestoneRewards.atCount.amountCentsnumberYes
programSnapshot.customTerms.milestoneRewards.atCount.countnumberYes

programSnapshot.customTerms.customerCapCents

Variant 1

Type: null.

Variant 2

Type: number.

programSnapshot.friendIncentive

Variant 1

FieldTypeRequiredDetails
programSnapshot.friendIncentive.type"percent"Yes
programSnapshot.friendIncentive.rateBpsnumberYes
programSnapshot.friendIncentive.maxDiscountCentsnumberNoLargest discount for one order.
programSnapshot.friendIncentive.minOrderCentsnumberNoThe friend's order total before the discount must reach this amount. Checked by the merchant's checkout.
programSnapshot.friendIncentive.ordersnumberNoHow many of the friend's orders get the incentive.
programSnapshot.friendIncentive.newCustomersOnlyunionNotrue: use the merchant's newCustomer answer, or recorded purchases when omitted. false: returning customers qualify too. A supplied answer uses the order limit after the referral.
programSnapshot.friendIncentive.expiresAfterDaysunionNoDays after the referral was captured, claimed or entered. null means it never expires.
programSnapshot.friendIncentive.returnOnFullRefundunionNotrue: a full refund gives the use back, so the customer can get the offer again.
programSnapshot.friendIncentive.orderCategoriesobjectNoOrder categories that get the discount. Checked apart from the program's own orderCategories, which decide rewards. Absent means every order qualifies.

programSnapshot.friendIncentive.newCustomersOnly

Variant 1

Type: boolean.

Variant 2

Type: boolean.

programSnapshot.friendIncentive.expiresAfterDays

Variant 1

Type: null.

Variant 2

Type: number.

programSnapshot.friendIncentive.returnOnFullRefund

Variant 1

Type: boolean.

Variant 2

Type: boolean.

programSnapshot.friendIncentive.orderCategories

FieldTypeRequiredDetails
programSnapshot.friendIncentive.orderCategories.includearrayNo
programSnapshot.friendIncentive.orderCategories.excludearrayNo

Variant 2

FieldTypeRequiredDetails
programSnapshot.friendIncentive.type"fixed"Yes
programSnapshot.friendIncentive.amountCentsnumberYes
programSnapshot.friendIncentive.minOrderCentsnumberNoThe friend's order total before the discount must reach this amount. Checked by the merchant's checkout.
programSnapshot.friendIncentive.ordersnumberNoHow many of the friend's orders get the incentive.
programSnapshot.friendIncentive.newCustomersOnlyunionNotrue: use the merchant's newCustomer answer, or recorded purchases when omitted. false: returning customers qualify too. A supplied answer uses the order limit after the referral.
programSnapshot.friendIncentive.expiresAfterDaysunionNoDays after the referral was captured, claimed or entered. null means it never expires.
programSnapshot.friendIncentive.returnOnFullRefundunionNotrue: a full refund gives the use back, so the customer can get the offer again.
programSnapshot.friendIncentive.orderCategoriesobjectNoOrder categories that get the discount. Checked apart from the program's own orderCategories, which decide rewards. Absent means every order qualifies.

programSnapshot.friendIncentive.newCustomersOnly

Variant 1

Type: boolean.

Variant 2

Type: boolean.

programSnapshot.friendIncentive.expiresAfterDays

Variant 1

Type: null.

Variant 2

Type: number.

programSnapshot.friendIncentive.returnOnFullRefund

Variant 1

Type: boolean.

Variant 2

Type: boolean.

programSnapshot.friendIncentive.orderCategories

FieldTypeRequiredDetails
programSnapshot.friendIncentive.orderCategories.includearrayNo
programSnapshot.friendIncentive.orderCategories.excludearrayNo

programSnapshot.partnerOffer

Variant 1

FieldTypeRequiredDetails
programSnapshot.partnerOffer.type"percent"Yes
programSnapshot.partnerOffer.rateBpsnumberYes
programSnapshot.partnerOffer.maxDiscountCentsnumberNoLargest discount for one order.
programSnapshot.partnerOffer.minOrderCentsnumberNoThe friend's order total before the discount must reach this amount. Checked by the merchant's checkout.
programSnapshot.partnerOffer.ordersnumberNoHow many of the friend's orders get the incentive.
programSnapshot.partnerOffer.expiresAfterDaysunionNoDays after the referral was captured, claimed or entered. null means it never expires.
programSnapshot.partnerOffer.returnOnFullRefundunionNotrue: a full refund gives the use back, so the customer can get the offer again.
programSnapshot.partnerOffer.orderCategoriesobjectNoOrder categories that get the discount. Checked apart from the program's own orderCategories, which decide rewards. Absent means every order qualifies.

programSnapshot.partnerOffer.expiresAfterDays

Variant 1

Type: null.

Variant 2

Type: number.

programSnapshot.partnerOffer.returnOnFullRefund

Variant 1

Type: boolean.

Variant 2

Type: boolean.

programSnapshot.partnerOffer.orderCategories

FieldTypeRequiredDetails
programSnapshot.partnerOffer.orderCategories.includearrayNo
programSnapshot.partnerOffer.orderCategories.excludearrayNo

Variant 2

FieldTypeRequiredDetails
programSnapshot.partnerOffer.type"fixed"Yes
programSnapshot.partnerOffer.amountCentsnumberYes
programSnapshot.partnerOffer.minOrderCentsnumberNoThe friend's order total before the discount must reach this amount. Checked by the merchant's checkout.
programSnapshot.partnerOffer.ordersnumberNoHow many of the friend's orders get the incentive.
programSnapshot.partnerOffer.expiresAfterDaysunionNoDays after the referral was captured, claimed or entered. null means it never expires.
programSnapshot.partnerOffer.returnOnFullRefundunionNotrue: a full refund gives the use back, so the customer can get the offer again.
programSnapshot.partnerOffer.orderCategoriesobjectNoOrder categories that get the discount. Checked apart from the program's own orderCategories, which decide rewards. Absent means every order qualifies.

programSnapshot.partnerOffer.expiresAfterDays

Variant 1

Type: null.

Variant 2

Type: number.

programSnapshot.partnerOffer.returnOnFullRefund

Variant 1

Type: boolean.

Variant 2

Type: boolean.

programSnapshot.partnerOffer.orderCategories

FieldTypeRequiredDetails
programSnapshot.partnerOffer.orderCategories.includearrayNo
programSnapshot.partnerOffer.orderCategories.excludearrayNo

explanationParts[]

FieldTypeRequiredDetails
explanationParts.codeunionYes
explanationParts.paramsobjectNo

explanationParts.code

Variant 1

Type: string.

Variant 2

Type: string.

Variant 3

Type: string.

Variant 4

Type: string.

Variant 5

Type: string.

Variant 6

Type: string.

Variant 7

Type: string.

Variant 8

Type: string.

Variant 9

Type: string.

Variant 10

Type: string.

Variant 11

Type: string.

explanationParts.params

Type: object.

calculation

FieldTypeRequiredDetails
calculation.compensationunionYes
calculation.milestoneRewardsobjectNo
calculation.fixedRefundModeunionNoSaved for fixed reward refunds. Older rewards default to prorate.
calculation.phaseAfterMonthsnumberNo
calculation.tierobjectNo
calculation.customTermsobjectNo
calculation.uncappedCentsnumberYes
calculation.customerCapCentsnumberNo
calculation.partnerCapCentsnumberNo

calculation.compensation

Variant 1

FieldTypeRequiredDetails
calculation.compensation.type"percentage"Yes
calculation.compensation.rateBpsnumberYes
calculation.compensation.phasesarrayNo

calculation.compensation.phases[]

FieldTypeRequiredDetails
calculation.compensation.phases.rateBpsnumberYes
calculation.compensation.phases.afterMonthsnumberYes

Variant 2

FieldTypeRequiredDetails
calculation.compensation.type"fixed"Yes
calculation.compensation.amountCentsnumberYes

calculation.milestoneRewards

FieldTypeRequiredDetails
calculation.milestoneRewards.eachReportobjectNo
calculation.milestoneRewards.atCountobjectNo

calculation.milestoneRewards.eachReport

FieldTypeRequiredDetails
calculation.milestoneRewards.eachReport.compensationunionYes
calculation.milestoneRewards.eachReport.limitnumberNoAbsent means every counted report. Reversed reports do not count toward the limit.

calculation.milestoneRewards.eachReport.compensation

Variant 1

FieldTypeRequiredDetails
calculation.milestoneRewards.eachReport.compensation.type"fixed"Yes
calculation.milestoneRewards.eachReport.compensation.amountCentsnumberYes

Variant 2

FieldTypeRequiredDetails
calculation.milestoneRewards.eachReport.compensation.type"percentage"Yes
calculation.milestoneRewards.eachReport.compensation.rateBpsnumberYes

calculation.milestoneRewards.atCount

FieldTypeRequiredDetails
calculation.milestoneRewards.atCount.amountCentsnumberYes
calculation.milestoneRewards.atCount.countnumberYes

calculation.fixedRefundMode

Variant 1

Type: string.

Variant 2

Type: string.

calculation.tier

FieldTypeRequiredDetails
calculation.tier.namestringYes
calculation.tier.minValuenumberYes
calculation.tier.bonusBpsnumberYes
calculation.tier.valuenumberYes

calculation.customTerms

FieldTypeRequiredDetails
calculation.customTerms.targetunionYes
calculation.customTerms.targetIdstringYes

calculation.customTerms.target

Variant 1

Type: string.

Variant 2

Type: string.

Response schema

json
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string"
    },
    "companyId": {
      "type": "string"
    },
    "orderId": {
      "type": "string",
      "description": "The order that earned the reward. Absent on milestone rewards."
    },
    "milestone": {
      "type": "string",
      "description": "The milestone that earned the reward. Absent on order rewards. Exactly one of the two is set."
    },
    "reportEventId": {
      "type": "string",
      "description": "Each-report rewards name their source. Absent on at-count bonuses."
    },
    "milestoneReportReversed": {
      "anyOf": [
        {
          "type": "boolean",
          "const": false
        },
        {
          "type": "boolean",
          "const": true
        }
      ]
    },
    "valueCents": {
      "type": "number"
    },
    "milestoneCount": {
      "type": "number",
      "description": "Milestone rewards: the person's reports of the milestone that count for this program now,\nthose at or after the referral minus reversed ones. Grizzlee updates it with every report,\nreversal, revocation and reinstatement for the person and milestone. Absent on rewards no\nmilestone event has touched since milestones were counted."
    },
    "milestoneRevoked": {
      "anyOf": [
        {
          "type": "boolean",
          "const": false
        },
        {
          "type": "boolean",
          "const": true
        }
      ],
      "description": "Milestone rewards: true while the milestone is revoked for the person. Updated with\nmilestoneCount. Absent when not revoked, and on rewards no milestone event has touched since\nmilestones were counted."
    },
    "programId": {
      "type": "string"
    },
    "partnerId": {
      "type": "string"
    },
    "customerId": {
      "type": "string"
    },
    "currency": {
      "anyOf": [
        {
          "type": "string",
          "const": "CAD"
        },
        {
          "type": "string",
          "const": "USD"
        },
        {
          "type": "string",
          "const": "EUR"
        },
        {
          "type": "string",
          "const": "GBP"
        }
      ]
    },
    "rewardType": {
      "anyOf": [
        {
          "type": "string",
          "const": "offer"
        },
        {
          "type": "string",
          "const": "cash"
        },
        {
          "type": "string",
          "const": "credit"
        }
      ]
    },
    "offer": {
      "type": "object",
      "properties": {
        "terms": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "percent"
                },
                "rateBps": {
                  "type": "number"
                },
                "orders": {
                  "type": "number",
                  "description": "How many of the friend's orders get the incentive."
                },
                "expiresAfterDays": {
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "number"
                    }
                  ],
                  "description": "Days after the referral was captured, claimed or entered. null means it never expires."
                },
                "returnOnFullRefund": {
                  "type": "boolean",
                  "description": "true: a full refund gives the use back, so the customer can get the offer again."
                },
                "maxDiscountCents": {
                  "type": "number",
                  "description": "Largest discount for one order."
                },
                "minOrderCents": {
                  "type": "number",
                  "description": "The friend's order total before the discount must reach this amount. Checked by the merchant's checkout."
                },
                "orderCategories": {
                  "type": "object",
                  "properties": {
                    "include": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "exclude": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "description": "Order categories that get the discount. Checked apart from the program's own orderCategories,\nwhich decide rewards. Absent means every order qualifies."
                }
              },
              "required": [
                "type",
                "rateBps",
                "orders",
                "expiresAfterDays",
                "returnOnFullRefund"
              ]
            },
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "fixed"
                },
                "orders": {
                  "type": "number",
                  "description": "How many of the friend's orders get the incentive."
                },
                "expiresAfterDays": {
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "number"
                    }
                  ],
                  "description": "Days after the referral was captured, claimed or entered. null means it never expires."
                },
                "returnOnFullRefund": {
                  "type": "boolean",
                  "description": "true: a full refund gives the use back, so the customer can get the offer again."
                },
                "amountCents": {
                  "type": "number"
                },
                "minOrderCents": {
                  "type": "number",
                  "description": "The friend's order total before the discount must reach this amount. Checked by the merchant's checkout."
                },
                "orderCategories": {
                  "type": "object",
                  "properties": {
                    "include": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "exclude": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "description": "Order categories that get the discount. Checked apart from the program's own orderCategories,\nwhich decide rewards. Absent means every order qualifies."
                }
              },
              "required": [
                "type",
                "orders",
                "expiresAfterDays",
                "returnOnFullRefund",
                "amountCents"
              ]
            }
          ]
        },
        "expiresAt": {
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "string"
            }
          ]
        }
      },
      "required": [
        "terms",
        "expiresAt"
      ],
      "description": "Offer rewards only. Terms copied when earned. Later program edits leave them alone."
    },
    "originalCents": {
      "type": "number",
      "description": "What the reward earned when it was created. Never changes."
    },
    "adjustedCents": {
      "type": "number",
      "description": "Signed total that order adjustments added to or removed from originalCents. Absent until the\norder is adjusted. The reward is worth originalCents + adjustedCents - reversedCents."
    },
    "reversedCents": {
      "type": "number",
      "description": "Reversed by refunds, a rejection or a milestone revocation."
    },
    "status": {
      "anyOf": [
        {
          "type": "string",
          "const": "pending"
        },
        {
          "type": "string",
          "const": "reversed"
        },
        {
          "type": "string",
          "const": "approved"
        }
      ]
    },
    "selfReferral": {
      "type": "object",
      "properties": {
        "action": {
          "anyOf": [
            {
              "type": "string",
              "const": "blocked"
            },
            {
              "type": "string",
              "const": "review"
            },
            {
              "type": "string",
              "const": "flagged"
            }
          ]
        },
        "signals": {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "type": "string",
                "const": "email"
              },
              {
                "type": "string",
                "const": "phone"
              },
              {
                "type": "string",
                "const": "card"
              },
              {
                "type": "string",
                "const": "device"
              },
              {
                "type": "string",
                "const": "ip"
              },
              {
                "type": "string",
                "const": "customer_id"
              }
            ]
          }
        }
      },
      "required": [
        "action",
        "signals"
      ],
      "description": "Present when the customer's identity signals matched the partner's. With action review the\nreward started pending and waits for someone to approve or reject it, and automatic approval\nskips it. With action flagged it follows the program's usual approval."
    },
    "fraud": {
      "type": "object",
      "properties": {
        "action": {
          "anyOf": [
            {
              "type": "string",
              "const": "blocked"
            },
            {
              "type": "string",
              "const": "review"
            },
            {
              "type": "string",
              "const": "flagged"
            }
          ]
        },
        "rules": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "action": {
                "anyOf": [
                  {
                    "type": "string",
                    "const": "blocked"
                  },
                  {
                    "type": "string",
                    "const": "review"
                  },
                  {
                    "type": "string",
                    "const": "flagged"
                  }
                ]
              },
              "rule": {
                "anyOf": [
                  {
                    "type": "string",
                    "const": "duplicate_accounts"
                  },
                  {
                    "type": "string",
                    "const": "rapid_repeats"
                  },
                  {
                    "type": "string",
                    "const": "repeat_customer"
                  },
                  {
                    "type": "string",
                    "const": "disposable_email"
                  }
                ]
              },
              "signals": {
                "type": "array",
                "items": {
                  "anyOf": [
                    {
                      "type": "string",
                      "const": "email"
                    },
                    {
                      "type": "string",
                      "const": "phone"
                    },
                    {
                      "type": "string",
                      "const": "card"
                    },
                    {
                      "type": "string",
                      "const": "device"
                    },
                    {
                      "type": "string",
                      "const": "ip"
                    }
                  ]
                },
                "description": "Matching signal types, never values. Empty for disposable_email."
              },
              "count": {
                "type": "number",
                "description": "Customers counted, this one included when referred inside the window. Velocity rules only."
              }
            },
            "required": [
              "action",
              "rule",
              "signals"
            ]
          }
        }
      },
      "required": [
        "action",
        "rules"
      ],
      "description": "Present when fraud rules fired. rules lists each rule ID with its signal types, never values.\nWith action review the reward started pending, waits for someone to approve or reject it, and\nautomatic approval skips it. With action flagged it follows the program's usual approval."
    },
    "rejectedAt": {
      "type": "string",
      "description": "When someone rejected the pending reward. A rejected reward is reversed for good."
    },
    "rejectionReason": {
      "type": "string",
      "description": "Why it was rejected, as entered."
    },
    "statusBeforeReversal": {
      "anyOf": [
        {
          "type": "string",
          "const": "pending"
        },
        {
          "type": "string",
          "const": "approved"
        }
      ],
      "description": "Status the reward had when a refund fully reversed it. A later restoration returns it to this status."
    },
    "deliveryMode": {
      "anyOf": [
        {
          "type": "string",
          "const": "grizzlee_wallet"
        },
        {
          "type": "string",
          "const": "merchant"
        }
      ],
      "description": "Delivery mode when earned. Absent on older money rewards, which use the Grizzlee wallet. Absent on offer rewards. Readers ignore delivery for offers."
    },
    "createdAt": {
      "type": "string"
    },
    "availableAt": {
      "type": "string",
      "description": "Rewards no longer have a hold, so new rewards use createdAt. Older rewards keep their original date."
    },
    "programSnapshot": {
      "type": "object",
      "properties": {
        "currency": {
          "anyOf": [
            {
              "type": "string",
              "const": "CAD"
            },
            {
              "type": "string",
              "const": "USD"
            },
            {
              "type": "string",
              "const": "EUR"
            },
            {
              "type": "string",
              "const": "GBP"
            }
          ],
          "description": "Must match the company currency."
        },
        "name": {
          "type": "string"
        },
        "kind": {
          "anyOf": [
            {
              "type": "string",
              "const": "referral"
            },
            {
              "type": "string",
              "const": "affiliate"
            },
            {
              "type": "string",
              "const": "both"
            }
          ]
        },
        "rewardType": {
          "anyOf": [
            {
              "type": "string",
              "const": "offer"
            },
            {
              "type": "string",
              "const": "cash"
            },
            {
              "type": "string",
              "const": "credit"
            }
          ]
        },
        "attributionWindowDays": {
          "anyOf": [
            {
              "type": "null"
            },
            {
              "type": "number"
            }
          ],
          "description": "Days after a referral that a first purchase, or a milestone, still counts. The latest\nreferral always wins until one qualifies. Only milestone programs may use null, which means\nthe referral never expires."
        },
        "active": {
          "type": "boolean"
        },
        "orderCategories": {
          "type": "object",
          "properties": {
            "include": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "exclude": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          "description": "Order categories that earn rewards. Order programs only. The friend incentive has its own\norderCategories. Absent means every order can earn."
        },
        "compensation": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "percentage"
                },
                "rateBps": {
                  "type": "number"
                },
                "phases": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "rateBps": {
                        "type": "number"
                      },
                      "afterMonths": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "rateBps",
                      "afterMonths"
                    ]
                  }
                }
              },
              "required": [
                "type",
                "rateBps"
              ]
            },
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "fixed"
                },
                "amountCents": {
                  "type": "number"
                }
              },
              "required": [
                "type",
                "amountCents"
              ]
            }
          ]
        },
        "tracking": {
          "type": "object",
          "properties": {
            "links": {
              "anyOf": [
                {
                  "type": "boolean",
                  "const": false
                },
                {
                  "type": "boolean",
                  "const": true
                }
              ]
            },
            "qrCodes": {
              "anyOf": [
                {
                  "type": "boolean",
                  "const": false
                },
                {
                  "type": "boolean",
                  "const": true
                }
              ]
            },
            "attributionCodes": {
              "anyOf": [
                {
                  "type": "boolean",
                  "const": false
                },
                {
                  "type": "boolean",
                  "const": true
                }
              ]
            },
            "providerPromoCodes": {
              "anyOf": [
                {
                  "type": "boolean",
                  "const": false
                },
                {
                  "type": "boolean",
                  "const": true
                }
              ]
            }
          },
          "description": "Tracking methods are independent of kind. Provider discounts require a connected provider."
        },
        "destinationUrl": {
          "type": "string",
          "description": "The page partner links and QR codes open. A published signup page's destination takes\nprecedence. Without either, partners have no link."
        },
        "display": {
          "type": "object",
          "properties": {
            "en": {
              "type": "object",
              "properties": {
                "publicName": {
                  "type": "string",
                  "description": "The name partners and customers see. Falls back to the program name."
                },
                "headline": {
                  "type": "string",
                  "description": "Replaces the generated headline, such as \"Give 20%, get $10\"."
                },
                "milestoneLabel": {
                  "type": "object",
                  "properties": {
                    "one": {
                      "type": "string"
                    },
                    "other": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "one",
                    "other"
                  ],
                  "description": "Milestone programs only. What one report counts, such as one: \"lesson\", other: \"lessons\".\nIn Russian, other is the genitive plural, such as \"уроков\", which reward terms put after\n\"число\"."
                }
              }
            },
            "fr-CA": {
              "type": "object",
              "properties": {
                "publicName": {
                  "type": "string",
                  "description": "The name partners and customers see. Falls back to the program name."
                },
                "headline": {
                  "type": "string",
                  "description": "Replaces the generated headline, such as \"Give 20%, get $10\"."
                },
                "milestoneLabel": {
                  "type": "object",
                  "properties": {
                    "one": {
                      "type": "string"
                    },
                    "other": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "one",
                    "other"
                  ],
                  "description": "Milestone programs only. What one report counts, such as one: \"lesson\", other: \"lessons\".\nIn Russian, other is the genitive plural, such as \"уроков\", which reward terms put after\n\"число\"."
                }
              }
            },
            "hy": {
              "type": "object",
              "properties": {
                "publicName": {
                  "type": "string",
                  "description": "The name partners and customers see. Falls back to the program name."
                },
                "headline": {
                  "type": "string",
                  "description": "Replaces the generated headline, such as \"Give 20%, get $10\"."
                },
                "milestoneLabel": {
                  "type": "object",
                  "properties": {
                    "one": {
                      "type": "string"
                    },
                    "other": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "one",
                    "other"
                  ],
                  "description": "Milestone programs only. What one report counts, such as one: \"lesson\", other: \"lessons\".\nIn Russian, other is the genitive plural, such as \"уроков\", which reward terms put after\n\"число\"."
                }
              }
            },
            "ru": {
              "type": "object",
              "properties": {
                "publicName": {
                  "type": "string",
                  "description": "The name partners and customers see. Falls back to the program name."
                },
                "headline": {
                  "type": "string",
                  "description": "Replaces the generated headline, such as \"Give 20%, get $10\"."
                },
                "milestoneLabel": {
                  "type": "object",
                  "properties": {
                    "one": {
                      "type": "string"
                    },
                    "other": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "one",
                    "other"
                  ],
                  "description": "Milestone programs only. What one report counts, such as one: \"lesson\", other: \"lessons\".\nIn Russian, other is the genitive plural, such as \"уроков\", which reward terms put after\n\"число\"."
                }
              }
            }
          },
          "description": "Optional public name, headline and milestone label for partner and customer screens."
        },
        "trigger": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "order"
                }
              },
              "required": [
                "type"
              ]
            },
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "milestone"
                },
                "milestone": {
                  "type": "string"
                }
              },
              "required": [
                "type",
                "milestone"
              ]
            }
          ],
          "description": "What earns a reward. Defaults to completed orders."
        },
        "milestoneRewards": {
          "type": "object",
          "properties": {
            "eachReport": {
              "type": "object",
              "properties": {
                "compensation": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "fixed"
                        },
                        "amountCents": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "type",
                        "amountCents"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "percentage"
                        },
                        "rateBps": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "type",
                        "rateBps"
                      ]
                    }
                  ]
                },
                "limit": {
                  "type": "number",
                  "description": "Absent means every counted report. Reversed reports do not count toward the limit."
                }
              },
              "required": [
                "compensation"
              ]
            },
            "atCount": {
              "type": "object",
              "properties": {
                "amountCents": {
                  "type": "number"
                },
                "count": {
                  "type": "number"
                }
              },
              "required": [
                "amountCents",
                "count"
              ]
            }
          }
        },
        "fixedRefundMode": {
          "anyOf": [
            {
              "type": "string",
              "const": "prorate"
            },
            {
              "type": "string",
              "const": "full_refund_only"
            }
          ],
          "description": "How fixed rewards change after a partial refund."
        },
        "duration": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "only_order"
                }
              },
              "required": [
                "type"
              ]
            },
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "first_order"
                }
              },
              "required": [
                "type"
              ]
            },
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "first_n_orders"
                },
                "count": {
                  "type": "number"
                }
              },
              "required": [
                "type",
                "count"
              ]
            },
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "days"
                },
                "days": {
                  "type": "number"
                }
              },
              "required": [
                "type",
                "days"
              ]
            },
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "months"
                },
                "months": {
                  "type": "number"
                }
              },
              "required": [
                "type",
                "months"
              ]
            },
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "lifetime"
                }
              },
              "required": [
                "type"
              ]
            }
          ]
        },
        "delivery": {
          "type": "object",
          "properties": {
            "cash": {
              "anyOf": [
                {
                  "type": "string",
                  "const": "grizzlee_wallet"
                },
                {
                  "type": "string",
                  "const": "merchant"
                }
              ]
            },
            "credit": {
              "anyOf": [
                {
                  "type": "string",
                  "const": "grizzlee_wallet"
                },
                {
                  "type": "string",
                  "const": "merchant"
                }
              ]
            }
          },
          "description": "Who delivers approved rewards of each type. Defaults to the Grizzlee wallet for both."
        },
        "reviewRewards": {
          "anyOf": [
            {
              "type": "boolean",
              "const": false
            },
            {
              "type": "boolean",
              "const": true
            }
          ],
          "description": "When true, new rewards wait as pending until someone approves them. Otherwise they start approved."
        },
        "fraudChecks": {
          "type": "object",
          "properties": {
            "selfReferral": {
              "type": "object",
              "properties": {
                "action": {
                  "anyOf": [
                    {
                      "type": "string",
                      "const": "review"
                    },
                    {
                      "type": "string",
                      "const": "block"
                    },
                    {
                      "type": "string",
                      "const": "flag"
                    },
                    {
                      "type": "string",
                      "const": "off"
                    }
                  ]
                }
              }
            },
            "duplicateAccounts": {
              "type": "object",
              "properties": {
                "action": {
                  "anyOf": [
                    {
                      "type": "string",
                      "const": "review"
                    },
                    {
                      "type": "string",
                      "const": "block"
                    },
                    {
                      "type": "string",
                      "const": "flag"
                    },
                    {
                      "type": "string",
                      "const": "off"
                    }
                  ]
                },
                "accounts": {
                  "type": "number",
                  "description": "Customers sharing one card or device that trigger the rule. This one counts when referred inside the window."
                },
                "windowDays": {
                  "type": "number"
                },
                "ipAccounts": {
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "number"
                    }
                  ],
                  "description": "Customers sharing one IP address that trigger the rule. null leaves IP addresses out."
                }
              }
            },
            "rapidRepeats": {
              "type": "object",
              "properties": {
                "action": {
                  "anyOf": [
                    {
                      "type": "string",
                      "const": "review"
                    },
                    {
                      "type": "string",
                      "const": "block"
                    },
                    {
                      "type": "string",
                      "const": "flag"
                    },
                    {
                      "type": "string",
                      "const": "off"
                    }
                  ]
                },
                "referrals": {
                  "type": "number",
                  "description": "Referrals from one device that trigger the rule. This one counts when referred inside the window."
                },
                "windowMinutes": {
                  "type": "number"
                },
                "ipReferrals": {
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "number"
                    }
                  ],
                  "description": "Referrals from one IP address that trigger the rule. null leaves IP addresses out."
                }
              }
            },
            "repeatCustomer": {
              "type": "object",
              "properties": {
                "action": {
                  "anyOf": [
                    {
                      "type": "string",
                      "const": "review"
                    },
                    {
                      "type": "string",
                      "const": "block"
                    },
                    {
                      "type": "string",
                      "const": "flag"
                    },
                    {
                      "type": "string",
                      "const": "off"
                    }
                  ]
                }
              }
            },
            "disposableEmail": {
              "type": "object",
              "properties": {
                "action": {
                  "anyOf": [
                    {
                      "type": "string",
                      "const": "review"
                    },
                    {
                      "type": "string",
                      "const": "flag"
                    },
                    {
                      "type": "string",
                      "const": "off"
                    }
                  ],
                  "description": "A disposable address does not show a second person, so this rule cannot block."
                }
              }
            }
          },
          "description": "Self-referral and other fraud rules. Absent means every rule uses its default."
        },
        "performance": {
          "type": "object",
          "properties": {
            "metric": {
              "anyOf": [
                {
                  "type": "string",
                  "const": "orders"
                },
                {
                  "type": "string",
                  "const": "new_customers"
                }
              ]
            },
            "tiers": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "minValue": {
                    "type": "number"
                  },
                  "bonusBps": {
                    "type": "number"
                  }
                },
                "required": [
                  "name",
                  "minValue",
                  "bonusBps"
                ]
              }
            },
            "windowDays": {
              "type": "number"
            }
          },
          "required": [
            "metric",
            "tiers"
          ]
        },
        "limits": {
          "type": "object",
          "properties": {
            "customerCapCents": {
              "type": "number"
            },
            "partnerCapCents": {
              "type": "number"
            }
          }
        },
        "customTerms": {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "target": {
                    "type": "string",
                    "const": "partner"
                  },
                  "targetId": {
                    "type": "string"
                  },
                  "compensation": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "const": "percentage"
                          },
                          "rateBps": {
                            "type": "number"
                          },
                          "phases": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "rateBps": {
                                  "type": "number"
                                },
                                "afterMonths": {
                                  "type": "number"
                                }
                              },
                              "required": [
                                "rateBps",
                                "afterMonths"
                              ]
                            }
                          }
                        },
                        "required": [
                          "type",
                          "rateBps"
                        ]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "const": "fixed"
                          },
                          "amountCents": {
                            "type": "number"
                          }
                        },
                        "required": [
                          "type",
                          "amountCents"
                        ]
                      }
                    ]
                  },
                  "milestoneRewards": {
                    "type": "object",
                    "properties": {
                      "eachReport": {
                        "type": "object",
                        "properties": {
                          "compensation": {
                            "anyOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "fixed"
                                  },
                                  "amountCents": {
                                    "type": "number"
                                  }
                                },
                                "required": [
                                  "type",
                                  "amountCents"
                                ]
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "percentage"
                                  },
                                  "rateBps": {
                                    "type": "number"
                                  }
                                },
                                "required": [
                                  "type",
                                  "rateBps"
                                ]
                              }
                            ]
                          },
                          "limit": {
                            "type": "number",
                            "description": "Absent means every counted report. Reversed reports do not count toward the limit."
                          }
                        },
                        "required": [
                          "compensation"
                        ]
                      },
                      "atCount": {
                        "type": "object",
                        "properties": {
                          "amountCents": {
                            "type": "number"
                          },
                          "count": {
                            "type": "number"
                          }
                        },
                        "required": [
                          "amountCents",
                          "count"
                        ]
                      }
                    }
                  },
                  "customerCapCents": {
                    "anyOf": [
                      {
                        "type": "null"
                      },
                      {
                        "type": "number"
                      }
                    ]
                  },
                  "partnerCapCents": {
                    "anyOf": [
                      {
                        "type": "null"
                      },
                      {
                        "type": "number"
                      }
                    ]
                  }
                },
                "required": [
                  "target",
                  "targetId"
                ]
              },
              {
                "type": "object",
                "properties": {
                  "target": {
                    "type": "string",
                    "const": "customer"
                  },
                  "targetId": {
                    "type": "string"
                  },
                  "compensation": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "const": "percentage"
                          },
                          "rateBps": {
                            "type": "number"
                          },
                          "phases": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "rateBps": {
                                  "type": "number"
                                },
                                "afterMonths": {
                                  "type": "number"
                                }
                              },
                              "required": [
                                "rateBps",
                                "afterMonths"
                              ]
                            }
                          }
                        },
                        "required": [
                          "type",
                          "rateBps"
                        ]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "const": "fixed"
                          },
                          "amountCents": {
                            "type": "number"
                          }
                        },
                        "required": [
                          "type",
                          "amountCents"
                        ]
                      }
                    ]
                  },
                  "milestoneRewards": {
                    "type": "object",
                    "properties": {
                      "eachReport": {
                        "type": "object",
                        "properties": {
                          "compensation": {
                            "anyOf": [
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "fixed"
                                  },
                                  "amountCents": {
                                    "type": "number"
                                  }
                                },
                                "required": [
                                  "type",
                                  "amountCents"
                                ]
                              },
                              {
                                "type": "object",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "const": "percentage"
                                  },
                                  "rateBps": {
                                    "type": "number"
                                  }
                                },
                                "required": [
                                  "type",
                                  "rateBps"
                                ]
                              }
                            ]
                          },
                          "limit": {
                            "type": "number",
                            "description": "Absent means every counted report. Reversed reports do not count toward the limit."
                          }
                        },
                        "required": [
                          "compensation"
                        ]
                      },
                      "atCount": {
                        "type": "object",
                        "properties": {
                          "amountCents": {
                            "type": "number"
                          },
                          "count": {
                            "type": "number"
                          }
                        },
                        "required": [
                          "amountCents",
                          "count"
                        ]
                      }
                    }
                  },
                  "customerCapCents": {
                    "anyOf": [
                      {
                        "type": "null"
                      },
                      {
                        "type": "number"
                      }
                    ]
                  }
                },
                "required": [
                  "target",
                  "targetId"
                ]
              }
            ]
          }
        },
        "friendIncentive": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "percent"
                },
                "rateBps": {
                  "type": "number"
                },
                "maxDiscountCents": {
                  "type": "number",
                  "description": "Largest discount for one order."
                },
                "minOrderCents": {
                  "type": "number",
                  "description": "The friend's order total before the discount must reach this amount. Checked by the merchant's checkout."
                },
                "orders": {
                  "type": "number",
                  "description": "How many of the friend's orders get the incentive."
                },
                "newCustomersOnly": {
                  "anyOf": [
                    {
                      "type": "boolean",
                      "const": false
                    },
                    {
                      "type": "boolean",
                      "const": true
                    }
                  ],
                  "description": "true: use the merchant's newCustomer answer, or recorded purchases when omitted. false:\nreturning customers qualify too. A supplied answer uses the order limit after the referral."
                },
                "expiresAfterDays": {
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "number"
                    }
                  ],
                  "description": "Days after the referral was captured, claimed or entered. null means it never expires."
                },
                "returnOnFullRefund": {
                  "anyOf": [
                    {
                      "type": "boolean",
                      "const": false
                    },
                    {
                      "type": "boolean",
                      "const": true
                    }
                  ],
                  "description": "true: a full refund gives the use back, so the customer can get the offer again."
                },
                "orderCategories": {
                  "type": "object",
                  "properties": {
                    "include": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "exclude": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "description": "Order categories that get the discount. Checked apart from the program's own orderCategories,\nwhich decide rewards. Absent means every order qualifies."
                }
              },
              "required": [
                "type",
                "rateBps"
              ]
            },
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "fixed"
                },
                "amountCents": {
                  "type": "number"
                },
                "minOrderCents": {
                  "type": "number",
                  "description": "The friend's order total before the discount must reach this amount. Checked by the merchant's checkout."
                },
                "orders": {
                  "type": "number",
                  "description": "How many of the friend's orders get the incentive."
                },
                "newCustomersOnly": {
                  "anyOf": [
                    {
                      "type": "boolean",
                      "const": false
                    },
                    {
                      "type": "boolean",
                      "const": true
                    }
                  ],
                  "description": "true: use the merchant's newCustomer answer, or recorded purchases when omitted. false:\nreturning customers qualify too. A supplied answer uses the order limit after the referral."
                },
                "expiresAfterDays": {
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "number"
                    }
                  ],
                  "description": "Days after the referral was captured, claimed or entered. null means it never expires."
                },
                "returnOnFullRefund": {
                  "anyOf": [
                    {
                      "type": "boolean",
                      "const": false
                    },
                    {
                      "type": "boolean",
                      "const": true
                    }
                  ],
                  "description": "true: a full refund gives the use back, so the customer can get the offer again."
                },
                "orderCategories": {
                  "type": "object",
                  "properties": {
                    "include": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "exclude": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "description": "Order categories that get the discount. Checked apart from the program's own orderCategories,\nwhich decide rewards. Absent means every order qualifies."
                }
              },
              "required": [
                "type",
                "amountCents"
              ]
            }
          ],
          "description": "Optional offer for the referred customer."
        },
        "partnerOffer": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "percent"
                },
                "rateBps": {
                  "type": "number"
                },
                "maxDiscountCents": {
                  "type": "number",
                  "description": "Largest discount for one order."
                },
                "minOrderCents": {
                  "type": "number",
                  "description": "The friend's order total before the discount must reach this amount. Checked by the merchant's checkout."
                },
                "orders": {
                  "type": "number",
                  "description": "How many of the friend's orders get the incentive."
                },
                "expiresAfterDays": {
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "number"
                    }
                  ],
                  "description": "Days after the referral was captured, claimed or entered. null means it never expires."
                },
                "returnOnFullRefund": {
                  "anyOf": [
                    {
                      "type": "boolean",
                      "const": false
                    },
                    {
                      "type": "boolean",
                      "const": true
                    }
                  ],
                  "description": "true: a full refund gives the use back, so the customer can get the offer again."
                },
                "orderCategories": {
                  "type": "object",
                  "properties": {
                    "include": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "exclude": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "description": "Order categories that get the discount. Checked apart from the program's own orderCategories,\nwhich decide rewards. Absent means every order qualifies."
                }
              },
              "required": [
                "type",
                "rateBps"
              ]
            },
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "fixed"
                },
                "amountCents": {
                  "type": "number"
                },
                "minOrderCents": {
                  "type": "number",
                  "description": "The friend's order total before the discount must reach this amount. Checked by the merchant's checkout."
                },
                "orders": {
                  "type": "number",
                  "description": "How many of the friend's orders get the incentive."
                },
                "expiresAfterDays": {
                  "anyOf": [
                    {
                      "type": "null"
                    },
                    {
                      "type": "number"
                    }
                  ],
                  "description": "Days after the referral was captured, claimed or entered. null means it never expires."
                },
                "returnOnFullRefund": {
                  "anyOf": [
                    {
                      "type": "boolean",
                      "const": false
                    },
                    {
                      "type": "boolean",
                      "const": true
                    }
                  ],
                  "description": "true: a full refund gives the use back, so the customer can get the offer again."
                },
                "orderCategories": {
                  "type": "object",
                  "properties": {
                    "include": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "exclude": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  },
                  "description": "Order categories that get the discount. Checked apart from the program's own orderCategories,\nwhich decide rewards. Absent means every order qualifies."
                }
              },
              "required": [
                "type",
                "amountCents"
              ]
            }
          ],
          "description": "Offer programs only. What the partner earns per qualifying referred order."
        }
      },
      "required": [
        "currency",
        "name",
        "kind",
        "rewardType",
        "attributionWindowDays",
        "active"
      ]
    },
    "programVersion": {
      "type": "number",
      "description": "The program version the reward was earned under. Absent on rewards earned before programs had\nversions. programSnapshot holds their rules either way."
    },
    "historicalBasis": {
      "type": "string",
      "const": "total",
      "description": "Historical subtotal rewards keep their reporting-total basis for refunds and adjustments."
    },
    "basisCents": {
      "type": "number"
    },
    "explanation": {
      "type": "string"
    },
    "explanationParts": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "code": {
            "anyOf": [
              {
                "type": "string",
                "const": "fixed"
              },
              {
                "type": "string",
                "const": "percentage"
              },
              {
                "type": "string",
                "const": "offer"
              },
              {
                "type": "string",
                "const": "report"
              },
              {
                "type": "string",
                "const": "report_percentage"
              },
              {
                "type": "string",
                "const": "milestone_bonus"
              },
              {
                "type": "string",
                "const": "schedule_month"
              },
              {
                "type": "string",
                "const": "tier_bonus"
              },
              {
                "type": "string",
                "const": "custom_partner_terms"
              },
              {
                "type": "string",
                "const": "custom_customer_terms"
              },
              {
                "type": "string",
                "const": "capped"
              }
            ]
          },
          "params": {
            "type": "object",
            "properties": {},
            "additionalProperties": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "number"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            }
          }
        },
        "required": [
          "code"
        ]
      },
      "description": "explanation as codes. Absent on rewards earned before codes existed."
    },
    "calculation": {
      "type": "object",
      "properties": {
        "compensation": {
          "anyOf": [
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "percentage"
                },
                "rateBps": {
                  "type": "number"
                },
                "phases": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "rateBps": {
                        "type": "number"
                      },
                      "afterMonths": {
                        "type": "number"
                      }
                    },
                    "required": [
                      "rateBps",
                      "afterMonths"
                    ]
                  }
                }
              },
              "required": [
                "type",
                "rateBps"
              ]
            },
            {
              "type": "object",
              "properties": {
                "type": {
                  "type": "string",
                  "const": "fixed"
                },
                "amountCents": {
                  "type": "number"
                }
              },
              "required": [
                "type",
                "amountCents"
              ]
            }
          ]
        },
        "milestoneRewards": {
          "type": "object",
          "properties": {
            "eachReport": {
              "type": "object",
              "properties": {
                "compensation": {
                  "anyOf": [
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "fixed"
                        },
                        "amountCents": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "type",
                        "amountCents"
                      ]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "type": {
                          "type": "string",
                          "const": "percentage"
                        },
                        "rateBps": {
                          "type": "number"
                        }
                      },
                      "required": [
                        "type",
                        "rateBps"
                      ]
                    }
                  ]
                },
                "limit": {
                  "type": "number",
                  "description": "Absent means every counted report. Reversed reports do not count toward the limit."
                }
              },
              "required": [
                "compensation"
              ]
            },
            "atCount": {
              "type": "object",
              "properties": {
                "amountCents": {
                  "type": "number"
                },
                "count": {
                  "type": "number"
                }
              },
              "required": [
                "amountCents",
                "count"
              ]
            }
          }
        },
        "fixedRefundMode": {
          "anyOf": [
            {
              "type": "string",
              "const": "prorate"
            },
            {
              "type": "string",
              "const": "full_refund_only"
            }
          ],
          "description": "Saved for fixed reward refunds. Older rewards default to prorate."
        },
        "phaseAfterMonths": {
          "type": "number"
        },
        "tier": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string"
            },
            "minValue": {
              "type": "number"
            },
            "bonusBps": {
              "type": "number"
            },
            "value": {
              "type": "number"
            }
          },
          "required": [
            "name",
            "minValue",
            "bonusBps",
            "value"
          ]
        },
        "customTerms": {
          "type": "object",
          "properties": {
            "target": {
              "anyOf": [
                {
                  "type": "string",
                  "const": "partner"
                },
                {
                  "type": "string",
                  "const": "customer"
                }
              ]
            },
            "targetId": {
              "type": "string"
            }
          },
          "required": [
            "target",
            "targetId"
          ]
        },
        "uncappedCents": {
          "type": "number"
        },
        "customerCapCents": {
          "type": "number"
        },
        "partnerCapCents": {
          "type": "number"
        }
      },
      "required": [
        "compensation",
        "uncappedCents"
      ]
    }
  },
  "required": [
    "id",
    "companyId",
    "programId",
    "partnerId",
    "customerId",
    "currency",
    "rewardType",
    "originalCents",
    "reversedCents",
    "status",
    "createdAt",
    "availableAt",
    "programSnapshot",
    "explanation"
  ]
}

Errors

Failures return { "error": { "code": "...", "message": "...", "details": {} } }. Details are optional. See error statuses. Reuse an unchanged event payload when retrying.