Skip to main content
What show() resolves to. Either nothing ever appeared, or the interaction ran and the record carries two independent funnels plus how the sheet went away. show() never rejects. Presentation-level failures arrive here as values.

Structure

The two funnels are independent axes, not competing cases: a single presentation can claim an offer and run a purchase, and 2.0 records both. not_attempted is a real value, meaning “the funnel was open and nothing entered it”, never a missing one.
There is no unlocked boolean, on purpose. What a claim means is a property of the variant flow that served it, so an SDK-computed verdict over app-global config could contradict the flow that actually ran. The record is facts; the policy is yours.

Reading it

When the mechanism matters, branch on the axes directly:

PublisherOutcome

Your funnel: what your purchase controller reported back.
Treat pending as neither a conversion nor an abandonment. It is Ask to Buy (parental approval) on iOS, or SCA or a pending Play transaction on Android: the user has not been charged and has not walked away, and the store’s webhook is the source of truth. Folding it into cancelled in your own reporting reproduces exactly the misreporting the 1.x boolean handler caused.

AdvertiserOutcome

Encore’s funnel: how far the offer claim got.
result.claim is shorthand for the offer behind a claimed or verified outcome, and null otherwise. Read result.advertiser directly when you need to tell the two apart.

ClaimedOffer

On iOS an offer is a campaign, so offerId equals campaignId there. transactionId joins this record to a later strict_unlock_verified outcome and to the server-side completion event that can land days afterwards; it is nullable, because the transaction write can fail while the claim still happened. userConfirmedCompletion is true when the user said they finished a reward for trying offer and Encore’s server granted your prize; it is the user’s own word, not a verified conversion. See Reward for Trying. claimUrl (2.5.0+) is the exact link the user opened for this claim, with their transaction id in it, passed through from the native SDK (claimURL on iOS, claimUrl on Android). Store it to send the user back to an offer they did not finish. It is absent for demo offers (all a pk_test_ key gets), for links with no transaction id slot (such as Amazon offers, which credit your app rather than one user), and for claims with no transaction or no link. The link carries the user’s transaction id, so whoever opens it completes the offer as this user: keep it out of logs, analytics and third-party tools. See Finish-Later Links.

DismissReason

How a presented sheet went away. These strings are the frozen cross-platform vocabulary, and the same values land in decline_reason on sdk_offer_sheet_dismissed.

NotPresentedReason

Why no sheet ever appeared.
use_case_unavailable is a correct no-op, not an error. It never falls back to the churn-intervention sheet, because putting an in-app-purchase screen in front of a user who was meant to be rewarded is worse than presenting nothing.