Appearance
Falcon Rewarded Perks
Overview
Falcon Rewarded Perks are offers that unlock an additional reward once the user claims them. The user claims the perk, and a second gift is unlocked on top of it.
Example: the user claims a 60-day free trial, which is the first perk shown in the unit, and that unlocks a free $10 donation gift for a cause of their choice. The donation gift is one reward type; other reward types are also available.
Why turn this on
- Higher user engagement with the offers in the unit, since there is a reason to claim rather than skip.
- A better experience for the user, who gets something back for engaging.
- Stronger monetization performance across every offer in the unit, not just the perk itself.
What the integration involves
This supports adding an extra, Falcon-funded perk that we append to an ad response. When one applies, it arrives as an additional offer on top of the normal offer count requested or returned.
Supporting it is additive. If you already render offers from POST /api/odata, the perk itself renders like any other offer. The one piece of real integration work is the tease bar: when a perk is present, you display a teaser on every preceding offer so the customer knows the reward is coming.
This guide is for publishers and partners that render OData offers directly via the API. If you use a Falcon SDK or one of the pre-built ad units, Shopify Ad Unit (1.x) or the Android / iOS SDK, this is already handled for you and there's nothing to do here.
What it looks like
One example of a Rewarded Perk. The reward shown here is a donation gift; other reward types are available.
Detect that a perk is present
The /api/odata response is { offers: [...], templateData: {...}, template, ... }. Read templateData:
json
"templateData": {
"hasRewardedPerk": true,
"teaseMessage": "A free $10 donation gift to the cause of your choice is included when you claim this offer"
}hasRewardedPerk === truemeans a perk is present. It is always the last element ofoffers,offers[offers.length - 1].teaseMessageis the exact copy for the tease bar. Render it verbatim, don't write your own.hasRewardedPerkabsent orfalsemeans nothing extra to do, render offers exactly as you do today.
It adds one offer beyond the count you requested. The perk is appended on top of your requested offers, so if you request the default of
4you'll get5; request10, you'll get11. Always size your UI and loops off the actualoffers.length, not thecountyou asked for.
The main task: show the tease bar on every offer except the perk
This is the part that's different from a normal integration. When a perk is present, show a tease bar carrying templateData.teaseMessage on every offer except the perk itself, that is, on offers[0] through offers[offers.length - 2]. The bar teases the upcoming reward while the customer moves through the ranked offers. Once they reach the perk (the last one), it disappears because the reward is now shown directly.
Offers are typically presented one at a time in a carousel, and you already track which offer is active. Tease-bar visibility is just derived state off that index. There's no separate API call, nothing to re-fetch, and no per-offer request. Recompute one boolean whenever the active offer changes:
js
const perkPresent = !!templateData.hasRewardedPerk && !!templateData.teaseMessage;
const isLastOffer = currentIndex === offers.length - 1;
const showTeaseBar = perkPresent && !isLastOffer;
// when showTeaseBar, render templateData.teaseMessage in the footerThis mirrors Falcon's own ad-unit implementation. If your placement instead renders all offers at once as a list, the rule is identical: show the bar on every offer whose index isn't offers.length - 1.
Placement: the tease bar lives in the offer's footer, at the bottom, below the offer body and the redeem / "No thanks" (decline) actions, grouped with the terms / privacy-policy links. Render teaseMessage verbatim. Falcon's templates pair it with a small gift icon.
On click, jump straight to the perk
The tease bar promises a reward, so a click has to deliver it, otherwise the tease doesn't make sense. Implement this in your click handler: when a perk is present and the customer claims an offer that showed the tease bar (any offer before the last), don't advance to the next offer in sequence. Skip the intermediate offers and jump directly to the perk (offers.length - 1) so they can claim the reward.
Only the redeem / claim action jumps. "No thanks" (decline) still advances sequentially to the next offer as usual, and once the customer is already on the perk there's nowhere left to jump.
js
function onClickOffer() {
// ... your normal click tracking (fire clickUrl) ...
const lastIndex = offers.length - 1;
// Already on the perk (last offer) — end of the flow.
if (currentIndex >= lastIndex) {
onEndOfOffers();
return;
}
// Teased offer was claimed → jump straight to the reward.
if (templateData.hasRewardedPerk) {
setCurrentIndex(lastIndex);
return;
}
// Default: advance one offer.
setCurrentIndex(currentIndex + 1);
}This mirrors Falcon's own ad-unit flow. Without it, a customer who claims a teased offer would never reach the reward you promised.
Render the perk like any other offer
Nothing special here. The perk follows the standard offer contract, so render it from its own title, description, and ctaText just as you render every other offer. Two small things to be aware of:
- Some fields (
header,shortDescription,disclaimer,value,termsUrl) may be empty ornull. Render what's present and lettitlestand as the heading. - For the banner image, grab the first
icon-type image from theimagesarray, the same array you already use for every offer:
js
const bannerUrl = offer.images.find((img) => img.type === 'icon')?.publicUrl;json
{
"bannerId": "FAL_1",
"title": "Here's a free $10 donation gift",
"description": "Send this $10 donation gift to a cause you love, at no cost to you.",
"ctaText": "Select your cause",
"clickUrl": "https://pr-api.falconlabs.us/click?...",
"beaconUrl": "https://pr-api.falconlabs.us/vdata?...",
"closeUrl": "https://pr-api.falconlabs.us/close?...",
"images": [
{ "publicUrl": "https://images.falconlabs.us/demand/.../icon-d48829ca7a9a.jpg", "type": "icon", "tags": [] },
{ "publicUrl": "https://images.falconlabs.us/demand/.../icon-b7fe552349e5.png", "type": "icon", "tags": ["SPECIAL"] }
]
}Tracking beacons, same as any offer
Every offer, perk or not, ships with the same pre-built tracking URLs. Fire them with a plain GET. Do not construct or modify them.
| Field | When to fire |
|---|---|
beaconUrl | when the offer becomes visible (impression / view), see Impression API |
clickUrl | when the user claims / clicks it, this is also the navigation target, see Click API |
closeUrl | when the user dismisses it |
Summary
- Call
POST /api/odata, unchanged. - Read the perk flag on
templateData. Iffalseor absent, you're done, render offers as today. - If
true, rendertemplateData.teaseMessageas a tease bar on every offer except the last, and hide it on the perk itself. - When a customer claims a teased offer, jump straight to the perk (
offers.length - 1) instead of advancing one step. - Expect one more offer than you requested, drive off
offers.length. - Render the perk like any other offer, and fire its
beaconUrl/clickUrl/closeUrlas usual.