Releases
0.30.0
Added
GrizzleeTrackingClientcreates a random device ID the first time it captures, keeps it in the storage you pass, undergrizzlee-device:<publishable key>, and sends it with each capture. It sets no cookie. Grizzlee keeps only a keyed hash of it, with a keyed hash of the visitor's IP address, and compares them with the fraud rules when an order or claim uses the receipt. Withoutcrypto.randomUUIDor working storage, captures go without it.
Changed
updatePayoutSchedulesaves a 30-dayholdPeriodDayswhen you leave it out. It used to save 0. Terms you already saved keep their hold period. SendholdPeriodDays: 0to keep paying rewards as soon as they are approved.
0.29.0
Read before upgrading
- Partner summaries, the dashboard and the embed now hand out links in the short form
?ref=KARL7Q. They addprogramonly when another of the partner's linkable programs uses the same page, and QR links addchannel=qr. App and website builds on SDK 0.26.0 or older read only thegrizzlee_names, so they ignore these links. Before the Grizzlee release that publishes this version deploys, every app and site that captures referrals must ship a build on SDK 0.27.0 or newer. Links made earlier keep working in every version.
Changed
createReferralLinkwrites?ref=<code>, plusprogramandchannelonly when given, and accepts a referral withoutprogramId. It first removes referral names already in the destination.createPlayStoreUrlaccepts a referral withoutprogramIdand then writesrefandchannel. With a program it keeps thegrizzlee_names, so older app builds still read it.extraskipsref,program,channeland everygrizzlee_name, even when the referral leaves them out.
0.28.0
Read before upgrading
- Workspaces are now called companies everywhere in the API, SDK and webhooks. Nothing else about them changed. Rename these in your code:
getWorkspace()isgetCompany(), andGET /api/v1/workspaceisGET /api/v1/company. The snapshot typeWorkspaceSnapshotisCompanySnapshot, and itstenantfield iscompany.- Every
tenantIdfield iscompanyId: on webhook events and every nested payload, and on rewards, partners, programs, payouts, attributions, orders, deliveries and the other records the API returns. - The error code
workspace_limitiscompany_limit. parseWebhookEventnow requirescompanyIdand rejects an event body that has onlytenantId. Process every webhook body you saved with an earlier version before you upgrade.
- Receipts and checkout references issued before this release keep working.
createEmbedSessionwithoutlocaleused to mean English. It now uses the partner's language, then the company's default language. Passlocale: "en"to keep English.- A company has
languages, and the first is its default. When it serves more than one,createProgram, andupdateProgramwithdisplay, return 400missing_translationunless each extra language has apublicName, andheadlineormilestoneLabelis set in every language or none. The message names the missing language.
Added
deleteProgram(id)callsDELETE /api/v1/programs/:idand returnsProgramDeletion,{ id, result }. A program with no history is deleted with its versions, placement keys and enrollments. A program with referrals, rewards or other history is archived instead: paused, stripped of its placement keys and kept, withresult: "archived".- Programs have an optional
archivedAt.updateProgramandsetPlacementreject an archived program with 409program_archived. - Armenian (
"hy") and Russian ("ru") join English and French ("fr-CA") wherever a locale is accepted or returned: partnerlocale, embed sessionlocale, programdisplayinput,ProgramDisplay,terms.textand the embedded dashboard.EmbedLocalecovers all four. ProgramDisplay.milestoneLabelhasfewandmanynext tooneandother, for languages such as Russian with more plural forms. Pick the form withIntl.PluralRules. Program input still takesoneandother.- Rewards have optional
explanationParts, order and milestone decisionsreasonParts, and Stripe payoutslastErrorParts: the Englishexplanation,reasonandlastErrorasTextPartsentences,{ code, params }, so you can show them in another language. The codes areRewardTextCode,DecisionTextCodeandPayoutTextCode. The English fields are unchanged. Text saved before this release has no parts, and later releases can add codes, so fall back to the English text. - The company snapshot's
company.languageslists the company's languages, default first. - The company snapshot's
companymay havedelivery: { cash, credit }, the payout method a company picked for programs created from the dashboard. Saved programs keep their owndelivery, andcreateProgramwithoutdeliverystill uses"grizzlee_wallet"for both.
0.27.0
Read before upgrading
ReferralLink.programIdis optional, since a link that carries only the partner's short code leaves it out. Code that reads it must handleundefined.createReferralLinkandcreatePlayStoreUrlstill require it.- Partner summary links,
createReferralLinkandcreatePlayStoreUrlstill writegrizzlee_ref,grizzlee_programandgrizzlee_channelwith the long code. A later release will switch generated links to the short form?ref=KARL7Q, which SDK 0.26.0 and older ignore. Ship this version in every app and site that captures referrals before then.
Added
- Partners have
alias, a short code such asKARL7Qthat is unique in the workspace and matches in any case. Captures, typed codes, checkout candidates and attributions accept it wherever they acceptreferralCode. Partner summary programs return it asalias. readReferralLink,captureFromUrl,readBranchReferral,readAppsFlyerReferralandreadInstallReferrerreadref,programandchannelafter thegrizzlee_names. Arefwithout a program counts only when it has the shape of a partner code, so?ref=producthuntis ignored.captureaccepts a link without a program, with an optionaldestinationpage that picks the program.captureFromUrlsends the page for such links and returns null whenrefnames no partner.
0.26.0
Added
- Programs accept an optional
destinationUrl, the HTTPS page partner links and QR codes open. A published signup page's destination still takes precedence.updateProgramkeeps an omitteddestinationUrl, andnullremoves it. Changing it adds no program version. createProgramacceptsProgramCreateInput, wherecurrencyis optional and defaults to the workspace currency.updateProgramkeeps an omittedcurrency.- Programs accept optional
displaycopy per language:publicName,headlineand, for milestone programs,milestoneLabelwithoneandother.updateProgramkeeps an omitteddisplay, andnullremoves it. Changing it adds no program version. The input type isProgramDisplayInput. - Capture, install claim, typed-code, incentive and placement responses include
display: ProgramDisplay, the program's public name, headline and milestone label with fallbacks filled in. Typed-code and incentive answers returnnullwhen there is no program.resolvePlacementnow returns the exportedPlacementResolutiontype.
0.25.0
Added
- Partner creation, upserts and updates accept
addProgramIdsandremoveProgramIds. These change individual enrollments and preserve the rest. - Enrollment writes reject a program on both sides with 422
conflicting_programs. Do not combine additions or removals withprogramIds, which still replaces the whole list.
0.24.0
Added
- Workspace placements map stable keys to programs. The server client lists and reads them, points a key at a program with
setPlacement, and removes one withdeletePlacement. - Embed sessions accept a placement key, enroll a partner in its active program when needed, and return the saved placement key.
- The tracking client resolves placements with a publishable key. Capture, install claim redemption, typed code and referral claim responses include the current placement keys for the captured program.
0.23.0
Added
- Optional
layout: "full" | "simple"oncreateEmbedSession. Sessions return the layout, which defaults to"full". The simple layout shows an offer, referral link, progress and Share, with lists behind a detail link.
0.22.0
Added
- Offer programs use
rewardType: "offer"andpartnerOffer. Each qualifying referred order earns a discount with frozen terms and expiry. Offers use the existing review, approval, rejection and reward webhooks. They have zero money amounts and no ledger entries, wallets or payouts. - Checkout responses add
incentiveKindand earned offers includerewardId. Holds and uses keep those fields. The existing incentive endpoints redeem earned offers through a partner's linked customer IDs. An eligible friend offer wins; earned offers use the soonest expiry first. - Partner reward reads add
offerwith status, terms, remaining uses, recorded uses, open holds and expiry, and accept arewardTypefilter. Embed rewards addrewardTypeand localized offer details. - Export
PartnerOffer,PartnerOfferInput,EarnedOfferTerms,OfferTerms,IncentiveKindandEarnedOfferStatus.
Changed
- Incentive response
termsnow use theOfferTermsunion.IncentiveIneligibleReasonaddsoffer_voided. Reward and programrewardTypecan be"offer". Update exhaustive switches for these unions. - Upgrade the SDK before enabling an offer program. Older
parseWebhookEventrejectsrewardType: "offer"in reward webhooks.
0.21.0
Added
payout.reversedandPayoutReversedWebhookPayloadreport cash returned by a Stripe transfer reversal, including partial reversals. The payload includesreversalCents, the new amount returned,reversedCents, the cumulative total,reversedAtandpartial.- Payouts can have status
reversed, withreversedCentsandreversedAt. Merchant delivery history appendsRewardDeliveryrecords with statusreversedandreversalOfId. Original deliveries and earned rewards stay intact. - Optional
customerDisplayNameon attribution creation, referral claims, code attachments and completed orders. Names accept 1 to 80 characters after trimming. Each referral keeps its latest accepted name. Customer erasure clears names and prevents later writes from restoring them. - Export
EmbedReferral,EmbedReferralPage,EmbedRewardandEmbedRewardPagefor partner-facing responses. orderCountonPartnerSummaryProgram, returned bygetPartnerSummaryand embed summaries. It totals each referral's distinct rewarded orders across the whole program without pagination. Renewals do not add orders. Reversed rewards still count; milestone rewards and orders that earned nothing do not.
Changed
- Stripe transfer reversals restore payable merchant cash or available wallet cash once, even when events repeat or arrive out of order. Subscribe to
transfer.reversedon the merchant Stripe connection and selectpayout.reversedon your Grizzlee webhook endpoint. - Partner balances, scheduled payouts and the dashboard account for returned transfers. Embed payouts expose
reversedCents, ornullwhen a mixed-program payout extends beyond the embed scope. - Embedded referral and reward responses omit merchant customer and order IDs and use opaque row keys. Referrals show the display name or a neutral label in the session language. Merchant API responses retain real IDs.
- Stripe metadata and Shopify order note attributes can supply
grizzlee_customer_display_name. Provider billing names are not shared automatically.
0.20.0
Added
deliverPartnerCredit(externalId, input)records one merchant credit entry across approved credit rewards, oldest approval first.recoverPartnerDebts(externalId, input)settles delivery debts of one currency and reward type, oldest debt first. Both userewards:deliver, return their allocations and replay the original result for the same reference. Existing per-reward calls remain available.versiononPartnerMerchantBalance. Cash, credit and program merchant balances share one partner-wide accounting history count, computed when read. Existing history contributes to the initial version. Re-read the summary after reward webhooks and ignore older versions. No new webhook type is required.- Exported types
PartnerCreditDeliveryInput,PartnerCreditDeliveryResult,PartnerDebtRecoveryInputandPartnerDebtRecoveryResult, plus the SDK input and response aliases for both calls. - Optional
programIdsoncreateEmbedSessionlimits every embed read to those partner memberships. Sessions return the selected IDs, ornullfor all programs. Scoped summaries omit partner-wide wallet balances and payout wait dates. Scoped payouts show selected merchant allocations, with a null net amount when mixed-program debt cannot be split. milestone,milestoneCountandmilestoneThresholdon milestone partner referrals, including progress before earning. Partner rewards expose their saved count and threshold. ExportEmbedSummary,EmbedPayoutandEmbedPayoutPage.- Embed hosts can opt in to
grizzlee:sharewith program ID, referral URL and localized invitation text. The embed shows milestone progress in English and French Canadian. - Milestone programs can pay on each report, as a fixed amount or a percentage of optional
valueCents, with an optional report limit. They can also pay a fixed bonus at a count. ExportedMilestoneRewards; each-report rewards carryreportEventIdand the reported value. Reversing a report takes back its reward and rechecks the bonus. - Partner promo code methods
listPartnerPromoCodes,createPartnerPromoCode,renamePartnerPromoCodeanddeactivatePartnerPromoCode, with typesProviderPromoCode,ProviderPromoCodeInputandRenameProviderPromoCodeInput. Stripe and Shopify orders attribute applied partner discounts through code candidates. - Per-program
trackingswitches for links, QR codes, typed attribution codes and provider promo codes, with theTrackingMethodstype. Partner summary programs exposetracking,attributionCode,promoCodesandqrLink. Provider code candidates and selection winners carryproviderPromoCodeId. - Exported types
ReferralCandidate,ReferralSelection,ReferralSkipReason,ClaimReferralInputandClaimReferralResult. Order webhooks includereferralSelectionwhen checkout supplied candidates. - Optional
newCustomeronReferralIncentiveInput,ReserveIncentiveInputandOrderEvent. Your server supplies newness from its own history, including placed but unpaid orders. Send it on referred purchases and skip unrelated orders and past order-count imports. - Reservations, orders and
order.completedwebhook payloads keep the supplied answer. Reservation and order replays reject a changed answer with their existing conflict errors. Reservation replays can omit the answer to keep the saved value. - When an order supplies
newCustomer,first_orderandfirst_n_orderscount purchases after the referral. Returning customers can earn partner rewards.newCustomer: falseblocks only friend offers withnewCustomersOnly: true. Omitting the field preserves the workspace-count fallback.
Changed
-
Reports for erased customer IDs remain accepted and keep normal referral, reward and refund behavior. Grizzlee discards identity signals, customer emails and personal reasons. Partner erasure removes the partner's personal data and customer ID links, and suppresses its identity signals from later reports. Linked customer records stay. Queued Stripe and Shopify reports for erased customers clear their raw bodies and mappings when processing finishes, so merchants no longer need a second erasure after late reports.
-
Breaking: milestone programs use
milestoneRewards.eachReportandmilestoneRewards.atCount. The milestone trigger no longer takescount. Omit order-onlycompensationandduration; custom milestone terms usemilestoneRewardstoo. Existing stored programs and reward snapshots retain their original fixed bonus and count through migration. -
Program kind no longer restricts tracking methods. New programs enable links, QR codes and typed codes by default. Existing affiliate programs migrate with typed codes off. Provider promo codes start off and require a connected provider. Provider discounts keep their original friend incentive after program edits.
-
Breaking: checkout inputs on
getReferralIncentive,reserveIncentive,claimReferralandcompleteOrderusecandidatesinstead of onereceipt,referralCodeorreferralReceipt. The newest valid receipt or typed code wins while attribution is open, or for an order-only program. Qualified customer attributions keep their partner. Skipped candidates reportcustomer_already_referred. Invalid candidates are skipped, and checkout continues when none wins.referralSelectionreports the winner and a reason for every skipped index.claimReferralreturns{ attribution, referralSelection }. Empty or invalid-only lists without a retained qualified attribution return no referral, with null program, partner and terms in incentive responses. Omit candidates to use recorded referrals. Holds and completed orders keep their selection on retries. -
Breaking:
reserveIncentiverequiresorderIdinstead ofcheckoutId. CallgetReferralIncentiveat quote time and reserve only when the order is placed. Holds last until completion or release, with no timer or maximum duration. Completion can find the hold by order ID. -
Remove
lockIncentive,LockIncentiveInput,IncentiveReservationLock,maxIncentiveLockDays,reservationMinutes, reservationexpiresAtand theexpiredreservation status. Historical expiry flags on completed orders remain readable. -
listIncentiveReservationstakes an optional object withcustomerIdandolderThanDays. The age filter lists open holds only. A competing hold returnseligible: falsewith reasonreservation_openinstead of throwing 409. Reserve replays reject a changed suppliednewCustomerwithorder_conflictand keep the saved value when omitted. -
Breaking: partners use optional
customerIdsto link their own merchant customer accounts.externalIdno longer identifies self-referral or supplies customer identity signals. Supplied lists replace the links, and[]clears them. Partner erasure removes the links. -
Replace
selfReferralCheckandSelfReferralCheckwithfraudChecks.selfReferral.action, usingblock,review,flagoroff. The default isblock, andoffdisables customer-link checks too. Orders, checkout checks, direct attribution and milestones use the same action policy. -
Self-referral responses and webhooks accept
customer_idinsignals. ExportSelfReferralSignalType. Update webhook consumers before using customer links. Existing partners gain no implicit links, and earned rewards and saved rules stay intact. -
Breaking: orders require
commissionableCents, the merchant-selected amount percentage rewards use. OptionaltotalCentsreports what the customer paid. These replace orderamountCentsandsubtotalCents. -
Remove program
commissionBaseand theCommissionBasetype. Every new percentage reward uses the commissionable amount. Earned rewards and their saved rules stay intact. Historical subtotal rewards carryReward.historicalBasis: "total"for later refunds and adjustments. -
Refunds use
refundedCommissionableCentsand optionalrefundedTotalCents. Fixed rewards prorate on the commissionable ratio. Only explicitfullRefund: truemarks an order fully refunded. -
Order adjustments use
commissionableCents,totalCents,adjustedCommissionableCents,adjustedTotalCents,previousCommissionableCentsandpreviousTotalCents. Reporting totals never change new rewards. -
Stripe charge metadata uses
grizzlee_commissionable_centsand optionalgrizzlee_total_cents, with matching cumulative refund keys. Shopify and Stripe invoice reporting totals now include the customer's full payment.
0.19.0
Added
duration: { type: "months", months }on programs, from 1 to 1,200 months. Orders earn until the same calendar date that many months after the customer's first rewarded order in the program, in UTC, so 12 months pays 12 monthly subscription invoices.ReferralReceipt.durationand the capture response'sdurationcan be"months".checkoutReferenceonCaptureReferralResponseand onReferralReceipt: a short signed reference to the capture that fits a Stripe Checkout Session'sclient_reference_id. Capture andredeemInstallClaimreturn it, and the tracking client stores it with the receipt. Receipts stored before this version leave it out.adjustOrder(input)and theorder.adjustedevent onsendEvent: set a completed order's newamountCents,subtotalCentsor both, with an optionalreason. Rewards are recalculated under the rules they were earned with. TheOrderAdjustmentEventandOrderAdjustmenttypes.adjustedCents?: numberonReward, the signed total of order adjustments. A reward is worthoriginalCents + (adjustedCents ?? 0) - reversedCents.adjustedCentsonPartnerRewardand on reward webhook payloads.adjustedSubtotalCents,adjustedAmountCents,lastAdjustedAtandadjustmentsonOrder,increasedCentsonEventResult, and theadjustmentledger entry kind.- The
order.adjustedandreward.adjustedwebhooks, with theOrderAdjustedWebhookPayloadandRewardAdjustedWebhookPayloadtypes.
Changed
- Program terms text describes
monthsdurations in English and Canadian French, such as "20% of each order your friend places in their first 12 months". - Refunds after an order adjustment measure against the adjusted totals.
amountCentson reward webhooks and partner reads includes adjustments. - Upgrade the SDK on every webhook endpoint before you subscribe to
order.adjustedorreward.adjusted. Older versions throw on these types.
0.18.0
Added
- Counted milestones. A milestone trigger takes an optional
count, from 1 to 10,000:{ type: "milestone", milestone: "task_completed", count: 10 }. Report each occurrence withreportMilestoneunder a neweventId, and the program pays once the person's reports since their referral reachcount. Withoutcount, or with 1, the first report pays, as before. Merchants changecountin the dashboard without a code change. A change creates a new program version, and earned rewards keep the count they were earned under. reverseMilestoneReport(input), forPOST /api/v1/milestones/reverse, takes back one report, for example a job cancelled after it was reported. TypeReverseMilestoneReportInput,{ eventId, reportEventId, reason? }. A reward whose count falls below its threshold is reversed with areversalledger entry andreward.reversed, and a delivered merchant reward becomes partner delivery debt, as after a refund. A later report that brings the count back restores it withreward.restored.- The
milestone.reversedwebhook, withreportEventId,reversalCents,reversedAtand an optionalreason. TypeMilestoneReversedWebhookPayload. countonMilestoneResultand on every milestone webhook: the person's reports of the milestone that are not reversed.reportEventIdonMilestoneResultfor reversals.milestoneCountandmilestoneThresholdon milestoneDecisions,milestoneCountandmilestoneRevokedon milestoneRewards, andrestoredCentson report results andmilestone.reported.MilestoneStatusgainsreversed, andLedgerEntry.kindgainsreversal.missingStripeAccount?: "manual" | "wait"onPayoutScheduleInputandPayoutSchedule."wait"creates no scheduled payout for a partner without astripeAccountId. Its rewards roll over and the first due date after it gets an account pays them by Stripe transfer."manual", the default, keeps today's manual payout."wait"needsstripeIntegrationId.- The
payout.account_requiredwebhook and thePayoutAccountRequiredWebhookPayloadtype. A scheduled run sends it once per wait, when it first holds a partner's payout for a missing Stripe account. It also sends the partner's payout details needed email. payoutAccountRequired,awaitingPayoutAccountandawaitingPayoutAccountSinceonPartnerSummary.
Changed
updatePayoutSchedulereplaces every term, so a call withoutmissingStripeAccountsaves"manual". Send it on every save once you use"wait".- A report while the milestone is revoked now counts toward the person's count. It still earns nothing until a reinstatement.
- A reinstatement leaves a reward reversed when its count is below its threshold. It comes back when reports bring the count back.
parseWebhookEventaccepts unknown fields in a reward'sprogramSnapshot.trigger. Older SDK versions reject reward webhooks from a program with acount, so update before you set one. They also throw onmilestone.reversed, which new webhook endpoints do not subscribe to unless you add it.
Documentation
- Public merchant help center with dashboard instructions for setup, partner invitations, rewards, payouts, refunds and troubleshooting.
0.17.0
Added
- Per-program
earnedCents,reversedCents,referrals,payoutsandbalancesinPartnerSummaryProgram. Merchant balances keep the partner-wide shape. Program wallet balances expose pending and approved rewards only, because wallet operations have no program allocations. Paid merchant payouts contribute each program's gross reward allocations. - Optional
expectedProgramIdonclaimReferral. A receipt from another program fails before mutation with 409program_mismatchanddetails: { expectedProgramId, programId }. localeonPartnerInput,PartnerUpsertInput,PartnerUpdateInputandPartner: the language of the partner's emails,"en"or"fr-CA". Without it, partner emails use the workspace's default language.nullremoves it.partnerEmailsonErasureCounts: partner email log rows whose address a partner erasure removed, plus queued emails it skipped.categories?: string[]onOrderEvent, forcompleteOrder,sendEventandsimulate, and onReferralIncentiveInput,ReserveIncentiveInputandLockIncentiveInput. Slugs of 1 to 40 letters, digits, hyphens or underscores, up toMAX_ORDER_CATEGORIES(20). Grizzlee lowercases, deduplicates and sorts them.orderCategories?: OrderCategoryRulesonProgramInput,ProgramandFriendIncentive, withincludeandexcludelists of up toMAX_CATEGORY_RULES(50) slugs. The program's rules decide rewards. The friend incentive's rules decide the discount.ProgramUpdateInputkeeps omitted rules and removes them withnull.- The
category_not_eligiblereason onIncentiveIneligibleReasonandIncentiveFlagReason. categories?: string[]onIncentiveReservation, the categories sent when it was made.orderCategoryMismatch(rules, categories), which trims and lowercases both sides before comparing,normalizeOrderCategory(value), theMAX_ORDER_CATEGORIESandMAX_CATEGORY_RULESconstants, and theOrderCategoryRulesandOrderCategoryRulesInputtypes.
Changed
- Partner summaries keep programs with past rewards, referrals, payout allocations or debt after the partner leaves. Each program has
memberto distinguish current and former memberships. Former programs return no referral link or friend incentive, and both dashboards label them as former programs. partner.createdpayloads carrylocalewhen the partner has one. Older SDK versions keep extra partner fields, so they still parse these payloads.- An order whose categories fail a program's
orderCategoriesis skipped in that program. It still counts as a purchase, so it takes a purchase number and counts against first-order rules and new-customer offers. parseWebhookEventis more forgiving from this version on. It acceptsincentiveFlag.reasonvalues it does not know, extra fields in a reward'sprogramSnapshot.friendIncentiveandprogramSnapshot.orderCategories, and any strings inorder.completedcategories, so later additions to these do not break it.- Upgrade the SDK on every webhook endpoint before you set
orderCategorieson a friend incentive. Older SDK versions throw onorder.completed,incentive.flaggedand reward events that carrycategory_not_eligibleor a friend incentive withorderCategories. A program's ownorderCategoriesand an order'scategoriesstill parse in older versions. - An empty
categorieslist ongetReferralIncentive,reserveIncentiveorlockIncentivemeans the checkout has no categories. Leaving the field out on a reservation replay or lock checks the categories the hold was made with. On an order event an empty list is stored as no categories.
Documentation
- Public developer docs with a first-referral and first-order walkthrough, HTTP and SDK references generated from the code, searchable guides, and a validated example for every webhook event.
0.16.0
Added
fraudChecksonProgramInputandProgram: per-program fraud rules beyond self-referral.duplicate_accounts(customers a partner referred share a card or device),rapid_repeats(several referrals within minutes from one device),repeat_customer(the customer shares a phone, card or device with another customer already rewarded in the program) anddisposable_email. Each rule takesactionblock,review,flag(the default) oroff, and the velocity rules take thresholds from 2 toFRAUD_THRESHOLD_MAX(200) and windows. IP addresses are left out unlessipAccountsoripReferralsis set.fraud?: FraudMatchonReward,Decision,ReferralIncentiveandIncentiveReservationResult.- The
fraudincentive ineligibility reason, returned bygetReferralIncentive,reserveIncentiveandlockIncentivewhen a blocking rule fires. - The
fraud.flaggedwebhook and theFraudFlaggedWebhookPayloadtype. - Types
FraudChecks,FraudChecksInput,FraudMatch,FraudRuleAction,FraudRuleIdandFraudRuleMatch, and thefraudRuleIdsandFRAUD_THRESHOLD_MAXconstants. rewardStatus: "review"ongetWorkspace, andreport.heldRewardsonWorkspaceSnapshot.
Changed
- Every program now runs the fraud rules with their defaults. Each rule defaults to
flag: the reward follows the usual approval, recordsfraudand sendsfraud.flagged. Nothing is held or blocked until you set a rule torevieworblock. Rewards held for review are skipped by automatic approval. Approve them withapproveRewardor reject them withrejectReward. parseWebhookEventacceptsfraud.flaggedand rewards withfraud. Older SDK versions throw on the new type, so update before you add it to an endpoint. Reward webhooks withfraudstill parse in older versions.
0.15.0
Added
- Install claims carry a web capture into a freshly installed app without fingerprinting.
capture({ ..., installClaim: true })returnsinstallClaim: { code, expiresAt }, andredeemInstallClaim(code)exchanges the code for the visit's receipt throughPOST /api/tracking/:publishableKey/install-claims/redeem. A code works once and for at most 7 days. Unknown, used or expired codes throw 404install_claim_unavailable. captureInstallReferrer(referrer)handles the Android Play Install Referrer at first launch. It redeemsgrizzlee_claimor capturesgrizzlee_refandgrizzlee_program, and remembers the referrer so later launches do nothing. It never replaces a receipt already stored for the same program, because the referrer's visit came before the install.createPlayStoreUrl({ packageName, installClaim?, referral?, extra? })builds a Play Store link with that referrer.readInstallReferrer(referrer)reads one.readBranchReferral(payload)andreadAppsFlyerReferral(payload, { keys })read a referral from Branch and AppsFlyer deep link payloads, including deferred deep links after install, and return the same shape asreadReferralLink.isInstallClaimCode(value),normalizeInstallClaimCode(value),INSTALL_CLAIM_PARAMand the typesInstallClaim,InstallReferrerandAppsFlyerReferralKeys.CaptureReferralResponsehas an optionalinstallClaim.
Changed
@grizzlee/sdk/trackingalso exportsreadReferralLink, so a landing page needs one import.readReferralLinkandcaptureFromUrlread the query by hand whenURLSearchParams.getis missing, as in React Native. Values are trimmed, and values longer than 120 characters are ignored, matching what capture accepts.
0.14.0
Added
reinstateMilestone(input), forPOST /api/v1/milestones/reinstate. It undoes a revocation: every reward the revocation reversed is restored with arestorationledger entry andreward.restored, a delivered reward reduces the partner's delivery debt, and the milestone can earn again. TypeReinstateMilestoneInput,{ eventId, customerId, milestone, reason? }.restoredCentsonMilestoneResult, set on reinstatements.- The
milestone.reinstatedwebhook, withrestoredCents,reinstatedAtand an optionalreason. TypeMilestoneReinstatedWebhookPayload.
Changed
MilestoneStatusadds"reinstated", which reinstatements return.- A revocation is no longer permanent. A revoked milestone earns nothing until it is reinstated, and it can be revoked again after that.
milestone.revokedfires for each revocation that revokes the milestone, so one person and milestone can send it more than once. Use a new event ID for every revocation and reinstatement. parseWebhookEventacceptsmilestone.reinstated. Older SDK versions throw on it, so update before you add it to an endpoint.
0.13.0
Added
erasePartner(partner)anderaseCustomer(customerId), forPOST /api/v1/partners/:id/erase,POST /api/v1/partners/by-external-id/:externalId/eraseandPOST /api/v1/customers/:customerId/erase. They erase a person's personal data and keep amounts, dates, statuses, IDs and the ledger.- Types
PartnerErasureResult,CustomerErasureResultandErasureCounts, and constantsERASED_PARTNER_NAMEandERASED_TEXT. erasedAtonPartner.- The
partner.erasedandcustomer.erasedwebhooks. TypesPartnerErasedWebhookPayloadandCustomerErasedWebhookPayload.
Changed
parseWebhookEventaccepts the two erasure event types, and apartner.createdpayload with an emptyemail, which a partner erased before delivery has. Older SDK versions throw on the new types, so update before you add them to an endpoint.- Registering, upserting or updating an erased partner throws 409
partner_erased. - A
failRewardDeliveryretry with anexternalReferencealready recorded matches any reason once erasure replaced the stored reason.
0.12.0
Added
stripeAccountIdonPartner,PartnerInput,UpsertPartnerInputand the partner update inputs: the partner's Stripe connected account (acct_...). Setting it needs a key withpayouts:writeas well aspartners:write.nullremoves it.stripeIntegrationIdonPayoutScheduleInputandPayoutSchedule. When set, scheduled payouts to partners with astripeAccountIdare sent as Stripe transfers from your Stripe balance, and end withpayout.paidorpayout.failed. Defaults tonull, which keeps every scheduled payout manual.cancelPayout(payoutId, { confirmNoTransfer: true })releases a Stripe payout held inneeds_actionafter you checked Stripe and found no transfer. It works only 24 hours after the last transfer request, when no worker holds the payout, and after Grizzlee's own complete search of Stripe finds nothing. Otherwise it throws 409transfer_recentortransfer_found. TypeCancelPayoutRequest.transferGrouponPayoutand payout webhooks: the Stripetransfer_groupGrizzlee sets on a transfer,grizzlee_payout_<payout ID>.provider,integrationIdanddestinationon merchant payouts increatePartnerPayout. Withprovider: "stripe", Grizzlee sends the net amount through the named Stripe connection.
Changed
-
recoverPartnerDebt,deliverRewardwithnettedDebtCentsand new merchant payouts withnettedDebtCentsthrow 409debt_in_payoutwhen they would settle cash debt that an open merchant payout already nets. -
destinationis optional on Stripe payouts increatePartnerPayout, wallet or merchant. It defaults to the partner'sstripeAccountId. -
Payouts can now combine
mode: "merchant"withprovider: "stripe". Apayout.createdhandler should send money only whenprovideris"manual". -
getPartnerByExternalId,upsertPartner,updatePartnerandupdatePartnerByExternalIdleave outstripeAccountIdfor keys withoutpayouts:write. -
Once Grizzlee has sent a Stripe transfer request, it never fails or cancels the payout on its own. A refusal, including insufficient funds, now holds the payout in
needs_actionwith the reason inlastError. Before, a wallet payout refused for insufficient funds on its first attempt failed and released its reservation. Look in Stripe for transfer groupgrizzlee_payout_<payout ID>, then callmarkPayoutPaidwith thetr_ID orcancelPayoutwithconfirmNoTransfer. -
PUT /payout-schedulestill replaces all the terms. Saving terms withoutstripeIntegrationIdturns Stripe payouts off.
0.11.0
Added
lockIncentive(reservationId, { orderId, expiresAt?, signals? })forPOST /api/v1/referrals/incentive/reservations/:id/lock. It locks an open friend-incentive hold to the order placed with it, so the hold lasts until that order completes or you release it, up to 180 days after the first lock. Only that order's completion consumes it, and the completion can leave outreservationId.lockonReserveIncentiveInput, to reserve and lock in one call.lock?: IncentiveReservationLock(orderId,lockedAt) onIncentiveReservationandIncentiveReservationResult.maxIncentiveLockDays, the 180-day limit.- Types
LockIncentiveInputandIncentiveReservationLock. - The
reservation_lockedincentive flag reason, for an order that sends a hold locked to another order.
Changed
IncentiveFlagReasonand the webhook schemas acceptreservation_locked.parseWebhookEventin older SDK versions throws on anincentive.flagged,order.completedor reward webhook that carries it, so update before you lock holds.
0.10.0
Added
clicks.totalandclicks.last30DaysonPartnerSummaryand eachPartnerSummaryProgram, returned bygetPartnerSummary. Counts include recordedlinkandqractivity, including code attachments marked with either channel.couponandin_apprecords are excluded. Repeat visits count separately.- Type
PartnerClickCounts.
0.9.0
Added
versionandupdatedAtonProgram. A new program is version 1, and every saved change except a rename adds 1.programVersiononReward,IncentiveReservation,IncentiveReservationResult,PartnerRewardand everyreward.*webhook payload. It names the program version the reward or reservation was made under. Older rewards and reservations have none, andPartnerReward.programVersionisnullfor them.listProgramVersions(programId)andgetProgramVersion(programId, version), forGET /api/v1/programs/:id/versionsandGET /api/v1/programs/:id/versions/:version.- Types
ProgramVersion,ProgramVersionDetailandProgramVersionList.
Changed
webhookPayloadSchemasacceptprogramVersionon reward payloads and on the nestedreward.updateProgramrejectsversionandupdatedAt, as it already rejectsid,tenantIdandcreatedAt. Remove them when you send a fetched program back.
0.8.0
Added
- The
milestone.reportedwebhook, sent for each new milestone report, rewarded or not. TypeMilestoneReportedWebhookPayload. - The
milestone.revokedwebhook, sent the first time a milestone is revoked for a person. TypeMilestoneRevokedWebhookPayload. - Type
MilestoneWebhookFields, the fields both milestone webhooks share.
Changed
parseWebhookEventaccepts the two milestone event types. Older SDK versions throw on them, so update before you add them to an endpoint.
0.7.0
Added
- The
reward.debt_recordedwebhook, sent when a refund, a milestone revocation or a refund before a payout was paid leaves a partner owing part of a delivered reward. TypeRewardDebtRecordedWebhookPayload. - The
reward.debt_settledwebhook, sent once for each recovery, netting or restoration of that debt. TypeRewardDebtSettledWebhookPayload. - The
referral.displacedwebhook, sent when another partner's referral takes a customer over. TypeReferralDisplacedWebhookPayload. incentiveAppliedCentsandincentiveFlagon reward webhooks for orders that reported a friend discount.IncentiveFlaggedWebhookPayloadandSelfReferralDetectedWebhookPayloadare now exported from the server import too, as the webhook import already did.
Changed
parseWebhookEventaccepts the three new event types. Older SDK versions throw on them, so update before you add them to an endpoint.
0.6.0
Added
signalsonattachReferralCode,getReferralIncentive,reserveIncentive,completeOrder,upsertPartner,registerPartner,updatePartnerandupdatePartnerByExternalId. Grizzlee keeps keyed hashes of the email, phone, card fingerprint, device ID and IP address and uses them to catch self-referrals.selfReferralon referral incentive lookups, reservations, code attachments, order decisions and rewards. It names the matching signal types and whether Grizzlee blocked the referral, held the reward for review or only flagged an IP match.selfReferralCheckon programs:block,revieworoff.rejectRewardto reject a pending reward, including one held for a self-referral review.- The
self_referral.detectedwebhook and theSelfReferralDetectedWebhookPayloadtype. - Types
IdentitySignals,IdentitySignalType,SelfReferralAction,SelfReferralCheck,SelfReferralMatchandRejectRewardInput.
Changed
getReferralIncentiveandreserveIncentivereturneligible: falsewith reasonself_referralwhen a program blocks a match.attachReferralCodethrowsself_referralwithdetails.signals.- A customer whose
customerEmailmatches the partner's email follows the program'sselfReferralCheck. Programs without the setting still block it.
0.5.0
Added
getPayoutScheduleandupdatePayoutScheduleto set workspace payout terms: weekly or monthly due dates, a minimum payout and a hold period. Grizzlee creates merchant payouts on each due date and sendspayout.created.scheduleon payouts and payout webhooks, withdueOnandapprovedBefore, on payouts the schedule created.- Types
PayoutSchedule,PayoutScheduleInput,PayoutScheduleRun,PayoutWeekday,GetPayoutScheduleResponse,UpdatePayoutScheduleInputandUpdatePayoutScheduleResponse.
0.4.0
Added
- First public npm release, with ESM and CommonJS entry points and matching TypeScript declarations.
reserveIncentive,releaseIncentiveandlistIncentiveReservationsto hold friend offers during checkout.importCustomersto record existing customers' prior order counts.reportMilestoneandrevokeMilestoneto reward and reverse referral milestones.- Types for milestone triggers, readable reward terms and reward webhook sources.
FixedRefundModeto choose whether fixed rewards survive partial refunds.
Changed
completeOrderacceptsreservationIdand returns customer order counts and incentive flags. Report every completed order, including orders without referrals.getReferralIncentiveis a preview. UsereserveIncentiveto price a checkout.updateProgramkeeps omittedfixedRefundModeunchanged.
0.3.0 and earlier
Earlier versions were shipped as tarballs and are not on npm.