Skip to main content
Reward for trying lets your app promise its own prize (100 coins, a free week of Premium) for trying one premium brand offer (a real perk a brand funds to acquire customers). You describe the prize on the placement. The sheet can show the promise up front, and when the user comes back from the offer it asks whether they finished. If they say yes, Encore’s server decides whether that earns the prize. When it does, the claim on the result carries userConfirmedCompletion = true, and your app grants the prize. Two settings in the Encore portal build on this. Per-offer values give each offer its own amount of your app’s currency (“1,500 tokens”), priced by Encore’s server and sent back on the offer_completed webhook. Pays on verification grants the prize only when the brand confirms the completion, never on the user’s Yes.
Requires iOS SDK 2.3.0 or Android SDK 2.3.0. Per-offer values and pays on verification require iOS SDK 2.3.1 or Android SDK 2.3.1. On React Native and Flutter, the prize and the flag need React Native SDK 2.3.0 or Flutter SDK 2.3.0, and per-offer values and pays on verification need 2.3.1. Their placement() references show the bridge signatures (React Native, Flutter).

Identify your users

Encore keeps score by the user ID your app passes to identify(), not by the device, so only identified users are promised a prize. Call it after sign in, before show():
Anonymous users still see the question, with no prize promised, and their flag stays false. A Yes they give before signing in carries over when identify() links them to an account, so signing in can’t earn that offer’s prize again.

What the flag means

userConfirmedCompletion means the user said they finished and Encore’s server granted the prize. It is still the user’s own word. It does not mean the advertiser confirmed a conversion. Encore records the answer for that user, but books no transaction, conversion, payout, or entitlement for it, and sends nothing to your server. Of the prize itself, only its id leaves the device; the title, detail, and icon stay on it. To grant only when the advertiser verifies the completion, turn on pays on verification and credit the prize from the offer_completed webhook instead. It carries the same transactionId that your app reads from result.claim.

Register the prize and grant it

Pass a PublisherReward on the placement, then read the flag on result.claim, the result show() returns. Passing a prize is a commitment: grant it whenever the flag is true.
Grant the prize from the result show() returns, or passes to its callback (show(resume:) on iOS, show(onResult:) on Android), and only from there. The same result, flag included, also reaches the outcomes stream (iOS, Android), so an app that grants from both pays twice. Use the stream to observe, not to pay.
The grant key is a second guard, not the main one: the server already grants each offer’s prize once per user. transactionId can be null, and the fallback of user ID plus campaignId matches that rule. Use the same user ID you gave identify(), so your grant key and Encore’s count belong to the same person. On Android, call showLevelReward(lifecycleScope, userId) from an Activity or Fragment. detail and iconUrl are optional, the icon shows only for an http or https URL with a host, and a blank id or title counts as no prize, so the sheet shows no promise. The builder method is listed in the placement() reference for iOS and Android.

How Encore decides the prize

A Yes is sent to Encore under the user’s ID, and Encore’s server alone decides whether it earns the prize. In the default mode, Pay when the user says Yes, it grants the prize only for:
  • The first Yes for an offer: once per user per offer, ever. This rule is fixed.
  • Within your daily limit: at most 3 prizes per user in any 24 hours by default. The window rolls; it doesn’t reset at midnight.
After any Yes, granted or not, the offer is hidden from that user’s offer lists on every device, and a new claim of it is refused. The same happens once Encore verifies that the user completed an offer. A reinstall, or a second device signed in to the same account, can’t earn the prize again. The promise comes from the server too. When the sheet opens, the SDK asks whether this user can still earn a prize today, and shows the promise only when the answer is yes and the user is identified. Once the daily limit is reached, the sheet shows no promise and asks the plain question.

Set the daily limit

You can set your own daily limit. Values are clamped to 1 through 10. Set it any time before show(); it survives reset(). The SDK sends it to the server with each presentation that passes a prize.

No answer, no prize

If the server can’t be reached when the sheet opens, there’s no promise. A Yes to a promise waits up to 5 seconds for the server’s answer. With no answer in that time (offline, slow, or a timeout), the flag stays false. The SDK sends the report again later, so the offer is still hidden once it lands, but a late answer never sets the flag.

An offer the user already completed

A user’s offer list can be older than their last Yes: they may have finished the offer on another device since it loaded. If they tap it, the server refuses the claim as already completed. The sheet drops that offer and the user picks another. When it was the last one, the sheet closes as flow completed (.flowCompleted on iOS, FlowCompleted on Android) with no claim on the result, so your app runs its original flow as for any presentation without a claim.

When the flag stays false

Only a Yes the server grants sets the flag. It stays false when the user:
  • answers No,
  • closes the sheet without answering,
  • closes the sheet while a promised Yes is still waiting for the server,
  • isn’t identified,
  • has reached your daily limit,
  • already said Yes to this offer,
  • can’t get an answer from the server in time,
  • uses an app set to pay only when the brand confirms,
  • changes while the sheet is open, because identify() switched to a different user or reset() ran.
A Yes still waiting when the sheet closes reaches the server anyway. The server grants it and counts it toward the daily limit, but the result your app receives has the flag false. The promise reflects the server’s answer when the sheet opened. A Yes on another device in the meantime can use up the daily limit, so a promised Yes can still come back false. If your app describes the prize in its own screens, say how many a day it pays. Keep the grant idempotent on user ID plus campaignId, as in the sample earlier on this page, so no other path in your app pays that offer twice. The flag never changes the claim’s stage. A confirmed claim is still claimed, and it keeps the flag when Encore verifies the claim in strict unlock mode. Reading result.claim covers both stages. A Yes that earns the prize always closes the sheet, so the result you receive is the confirmed claim.

Which users see the question

The promise and the question appear only when the served variant is built for reward for trying. Every other variant ignores the prize. Registering a prize is always safe, even for users who aren’t in that variant: their flag just stays false.

Show each offer’s own value

By default every offer promises the same prize: the PublisherReward title you pass on the placement. With per-offer values, Encore’s server prices each offer in your app’s own currency, so a card can read “1,500 tokens” for one offer and “200 tokens” for another. The same number comes back on the offer_completed webhook when the brand confirms the completion, so your server never keeps its own price list. Keep passing a PublisherReward. The per-offer value only rewords the prize the sheet already promises, so without a prize on the placement no value shows. Under Pay when the user says Yes, its title stays the fallback for any offer without a value. Under Pay only when the brand confirms, such an offer shows no prize.

Where the value shows

  • Each offer card shows that offer’s value, in place of your PublisherReward title.
  • The question after a claim names the claimed offer’s value.
  • A line that speaks for every offer, such as the promise at the top of the sheet, shows your PublisherReward title under Pay when the user says Yes. Under Pay only when the brand confirms, that line doesn’t show, so each card’s own value is the only prize on the sheet.
The result show() returns doesn’t carry the amount. It reaches your server only on the webhook’s reward field. So under Pay when the user says Yes, a grant on userConfirmedCompletion pays the fixed prize your app grants on the device, which can differ from the card’s amount, and the brand’s later confirmation still sends reward to your server. Pay each offer from one of the two, never both. To pay exactly the amount on the card, use Pay only when the brand confirms and credit reward.amount from the webhook.

Turn it on

  1. Ship your app on iOS SDK 2.3.1 or Android SDK 2.3.1, and wait until that build is the one your users run.
  2. In the Encore portal, open Settings, select the app, and fill in the Rewards section. Turn on per-offer prizes saves the form and turns per-offer values on for that app.
  3. Optionally, set a fixed amount on any offer from the Prize column on the Offers page. The column appears once the settings are saved.
Leave the settings unsaved until your users are on 2.3.1. An older SDK still shows your flat PublisherReward title on every card, and its claims store no value, so the webhook sends reward: null for them. Under Pay only when the brand confirms, a user on that build is never paid.
Only Admin and Editor members can change the settings. The form’s fields: Under the form, a preview lists every offer enabled for your app with the value it carries now and what that value rests on. An offer marked as resting on its listed price has too little payout history; it’s a good candidate for a fixed amount.

How a card’s value is computed

The server works through these rules in order and stops at the first that gives a value:
  1. An offer the brand reports in aggregate, not per user, never carries a value, whatever its fixed amount, your default prize, or your pay mode. No completion of such an offer can be credited to one user.
  2. A fixed amount you set on the offer wins, as is. Only an offer enabled for your app can take one.
  3. A calculated value, for offers that pay per completed action: the offer’s payout, times your share of it, times your rate, rounded to your step and clamped to your minimum and maximum. The payout is the median the brand actually paid per confirmed completion over the last 90 days across Encore, test and demo traffic excluded, once it has at least 5 completions. Below that, it’s the offer’s listed price. Pay-per-click and pay-per-impression offers skip this rule, as does any offer when the rate is blank or no revenue share is on record for your app.
  4. Your default prize.
  5. No value. The offer shows no per-offer amount, and its webhook sends reward: null.
Encore’s server builds the card label: the amount with comma thousands separators and your unit, for example 1,500 tokens or 1 token. The SDK shows that label exactly as sent, in every language, and never formats the amount itself. An offer with no value shows your PublisherReward title under Pay when the user says Yes. Under Pay only when the brand confirms, it shows no prize at all, because only an offer with a value has a prize to confirm.

The value is frozen at claim

The server stores a value only on a claim from a sheet that shows a per-offer reward (today, reward for trying). It decides from the sheet the SDK reports it presented, and stores that offer’s value on the claim’s transaction. That stored value is what the webhook sends, on every delivery for that transaction, whatever you change in the portal afterwards. Every other claim stores no value, so its webhook sends reward: null. That includes a claim from any other sheet, from an SDK that doesn’t report its sheet (any version before 2.3.1), from the Web SDK or the hosted /offers page, and through a click-through link or a redemption. If the user claims the same offer again before the brand confirms it, the latest sheet decides. From a sheet that shows a per-offer reward, the value is priced again to match the card they just saw. From any other sheet, the stored value is cleared, and the webhook sends reward: null.

Turn it off

Turn off per-offer prizes, under the save button, removes the app’s settings after a confirm step. Cards go back to your PublisherReward title, new claims store no value, and an app set to pay only when the brand confirms grants on a Yes again. Values already stored on claims are still sent, and your fixed amounts are kept for when you turn it back on.

Pay only when the brand confirms

When the user gets the prize decides what a Yes does: The mode lives in the per-offer reward settings, so an app without them is always in the default mode. The sheet still asks the user whether they finished. The question names the claimed offer’s value, or, for an offer with no value, promises no prize. In this mode the server answers every Yes with granted: false and the reason pays_on_verification. The SDK treats it as a refusal, and in this mode it refuses a grant whatever the server answers, so userConfirmedCompletion stays false and your device-side grant code never pays. Remove that grant, or leave it in place as dead code; either way, credit from the webhook. The daily limit you set with publisherRewardPolicy still decides the promise. The sheet promises a prize while the user’s confirmed completions that carried a value, over the last 24 hours, are under the limit. The window rolls, and completions carried onto the account when identify() links an anonymous user count too. The limit only gates the promise: a completion the brand confirms always carries its stored value, even past the limit.

Credit the webhook’s reward

Credit reward.amount of reward.unit once per transactionId. A multi-step offer can send more than one delivery for one transaction, and each carries the same reward. Encore sends no event to take a reward back.
creditOnce stands for your own wallet write, idempotent on key. Signature checks, retries, and the full handler are in the Receive Completion Events guide. The field contract is in the webhook reference.