Requires iOS SDK 2.0.0, Android SDK 2.0.2, React Native SDK 2.0.2, or Flutter SDK 2.0.1. There is no setup step before this guide: your app is granted its use cases when the app is created, and a reward placement needs no subscription product and no purchase controller.
The complete pattern
Identify the user, then present the placement at the moment your app detects the achievement. Select therewardUsers use case, and set headline and subheadline to name the moment:
placement() for iOS, Android, React Native, and Flutter · PresentationResult for iOS, Android, React Native, and Flutter.
show() never throws (on React Native, its promise never rejects) and resolves exactly once. On iOS call it from a main-actor context; on Android it is a suspend function, so call it from a coroutine such as lifecycleScope; on React Native and Flutter, await it. iOS and Android also take a callback form for call sites that can’t await: show(resume:) on iOS and show(onResult:) on Android.
A reward placement is claim-only: it runs no in-app purchase, so your purchase controller is never called.
Where the copy comes from
headline and subheadline take the finished string for one presentation, and Encore never translates it, so localize it yourself. Pass nothing and the sheet still renders, with the copy Encore resolved for your app or the copy shipped with the screen. The full chain is on Where the copy comes from.
Read the result
result.claim is the offer the user claimed, or empty when they didn’t claim one. On React Native it exists only on a presented result, so check result.status first. It means the user tapped through to the brand, not that they finished the offer. Keep claim.transactionId when it is present; it carries the attribution.
When no sheet appeared, the result says why. No offers matching this user, an error (which arrives as a value on the result), and useCaseUnavailable (use_case_unavailable on React Native) are the common reasons. useCaseUnavailable means nothing resolved for this use case, which includes a user in the holdout group of an Encore sheet experiment that shows its holdout group no sheet. A reward placement never returns experimentControl (experiment_control on React Native); that reason belongs to the Reduce Churn control cohort. Treat each of these as a normal outcome for a reward moment: show your own celebration without the offer and carry on.
Gotchas
- You pass the finished string. There is no streak-count or milestone-count parameter; Encore never assembles a sentence out of a count.
- A blank override is not an override. An empty or whitespace-only value falls through to the next source rather than clearing the line. To show less, omit the call.
- A claim is not a conversion. The bounty is earned only when the brand-side completion is verified on Encore’s servers. Never pay out or grant access on a claim alone; the offer_completed webhook reports the verified completion, joined on
transactionId. - Omitting the use case selects Reduce Churn. A placement without
useCasepresents the Reduce Churn sheet, which can run a purchase. SelectrewardUserson every reward placement.
Related
- Reward Users: the canonical description of this use case.
- The
placement()reference for iOS, Android, React Native, and Flutter: every builder method, including the use case and copy overrides.