Skip to main content
The Web SDK supports two redemption modes, chosen once at configure() via redemptionMode. The mode decides who fires the advertiser redirect and when:
'deferred' (default)'immediate'
Config valueredemptionMode: 'deferred'redemptionMode: 'immediate'
What show() doesPresents the carousel, records a transaction on claim, no redirectPresents the carousel, records a transaction, opens the advertiser tab inside the claim gesture
show() claim result{ status: 'claimed' }{ status: 'claimed' } — identical; the tab was also opened before resolving
Advertiser redirectLater, in redeem(), on the user’s CTA tapImmediately, inside the claim gesture
redeem() needed?Yes — phase 2 of the flowNo — already redeemed inline
Who controls redirect timingThe host appThe SDK
The config literal is 'immediate'. Use that exact string in configure()'instant' is not a valid value.

When to use which

Use 'deferred' (the default) when claiming an offer and redirecting to the advertiser are separate moments — you want to run your own conversion, navigation, or server check between the claim and the redirect. Typical cases:
  • The user accepts a retention offer mid-cancellation, and you redirect only after your own save/confirm step.
  • You present on one page or route and redeem after a navigation or reload.
  • You gate the advertiser redirect behind a server check or a real conversion.
Use 'immediate' when claiming should redirect in a single step — no host logic between claim and redirect, and no pending transaction to manage. It’s the recommended pairing for post-purchase surfaces using the thankYou layout: the claim opens the advertiser within the tap gesture, with no second host action on a page the user is about to leave. In both modes the SDK renders nothing after a claim — there is no built-in success or confirmation screen. The host owns the post-claim moment: render your own confirmation (or none), keyed off the claimed result.

Deferred mode: the two-phase flow

Two calls. show() claims; your code runs; redeem() redirects.
import Encore from '@encorekit/web-sdk';

Encore.configure({
  apiKey: 'pk_live_yourpublishablekey',
  redemptionMode: 'deferred', // default — shown for clarity
});

// Phase 1 — claim (no redirect). The SDK records the transaction internally;
// there is no handle to stash.
const shown = await Encore.placement('cancel_flow').show();
if (shown.status !== 'claimed') return; // 'dismissed' | 'unavailable'

// ... run your own conversion / save step ...

// Phase 2 — redirect, called from a user action (button click). redeem()
// renders the redemption screen; the advertiser tab opens on the CTA tap.
const redeemed = await Encore.placement('cancel_flow').redeem();
// redeemed.status === 'redeemed'
Lifecycle: show()claimed (transaction status: 'claimed') → (host work)redeem() → advertiser tab opens + provisional grant → transaction status: 'redeemed'. Two rules make the flow reliable:
  • Call redeem() within a user gesture’s reach. The advertiser tab is opened synchronously on the CTA tap to dodge popup blockers — trigger redeem() from a click handler, not a timer or background promise.
  • Identify early. Call identify() with your stable user id before presenting, so the transaction binds to an account id that survives reloads and navigations.

The pending transaction

A deferred claim records a pending transaction inside the SDK — self-contained, carrying everything redeem() needs to rebuild the advertiser redirect later. No handle is returned by show() and none is needed: redeem() resolves the pending transaction internally. Claims are stored locally with a ~7-day TTL and survive page reloads, so your code never tracks pending state — even on a fresh page, call redeem() when your flow is ready (from a click handler, e.g. your own “finish claiming your reward” button). If nothing is pending, redeem() resolves { status: 'none' } and renders no UI.

Per-placement redeem

placement(id).redeem() (as above) resolves exactly that placement’s transaction — it never crosses to another placement’s. The global Encore.redeem() resolves the pending transaction regardless of placement.

Immediate mode

One call. Claiming opens the advertiser tab inside the claim gesture; show() then resolves claimed and the SDK renders nothing further.
import Encore from '@encorekit/web-sdk';

Encore.configure({
  apiKey: 'pk_live_yourpublishablekey',
  redemptionMode: 'immediate',
});

// Single step — claim opens the advertiser tab inline
const result = await Encore.placement('post-purchase').show();
if (result.status === 'claimed') {
  // Advertiser tab already opened. The SDK renders nothing after the claim —
  // show your own confirmation here if you want one.
}
// No redeem() call needed in immediate mode.
Lifecycle: show() → opens the advertiser tab in the claim gesture → claimed (transaction status: 'redeemed').

What differs in events

Both modes record a transaction and emit the same provisional grant on redirect; the only difference is when the redirect fires. Across both:
  • sdk_offer_presentation_triggered / _success / _failed — fired when the carousel is presented (or when there are no eligible offers).
  • sdk_offer_presented — per offer impression.
  • sdk_offer_claimed — when the user claims (both modes).
  • The provisional grant signal fires at redirect time: in redeem() for deferred, inline at claim for immediate.

Gotchas

  • Mode is set once. The SDK is configure-once; redemptionMode can’t be changed after configure() without a fresh SDK instance (e.g. a page reload). Read the live value with Encore.getConfiguration().redemptionMode.
  • Don’t call redeem() in immediate mode. The transaction is already redeemed inline; redeem() resolves none.
  • Expired claims resolve as none. A pending transaction past its ~7-day TTL fails resolution — redeem() returns { status: 'none' }, meaning “nothing to redeem”.
  • claimed ≠ conversion. In either mode the result only says the user accepted an offer — advertiser conversion is asynchronous and server-authoritative. Verify conversions and entitlements server-side, by user — see server-side verification on Encore’s side.