Offerwall embed

The hosted wall is one iframe. We render the offers, apply the targeting, handle the click and the redirect, and style it however you configured it.

The embed

<iframe
  src="https://trovewall.com/wall/pk_live_a1b2c3?user_id=USER_ID"
  width="100%"
  height="800"
  frameborder="0"
  allow="clipboard-write"
  referrerpolicy="origin">
</iframe>

Parameters

ParameterRequiredMeaning
user_id Yes Your identifier for the end user. Opaque to us — we never learn who they are. It comes straight back in the postback.
country No ISO 3166-1 alpha-2. Overrides our own geo detection, which is what you want if you resolve it more accurately than a request IP can.
device No desktop, android, ios, tablet. Otherwise taken from the user agent.
category No Open the wall filtered to one category slug.
sub1sub5 No Your own tracking values. Stored on the click, returned on the postback, reportable.
Pick a stable user_id. Per-user caps, duplicate detection and the reward history all key off it. If it changes between sessions the same person can complete the same offer repeatedly — and the advertiser will reverse those conversions, out of your balance.

Auto-sizing the iframe

The wall posts its height to the parent window whenever it changes, so you can grow the iframe instead of scrolling inside it.

window.addEventListener('message', (event) => {
  // Only trust messages from us.
  if (event.origin !== 'https://trovewall.com') return;
  if (event.data?.source !== 'trovewall-wall') return;

  if (event.data.type === 'height') {
    document.querySelector('#tw-wall').style.height = event.data.height + 'px';
  }
});

Clicks open in a new tab

When an offer is tapped the wall opens the tracking link in the top window rather than inside the iframe. This is deliberate: many advertisers set X-Frame-Options and would simply fail to load, and app-store links do not work framed at all. Nothing is required from you — but do not set sandbox on the iframe without allow-popups and allow-top-navigation-by-user-activation, or the click will be swallowed.

Customisation

Everything visual is configured per app in the dashboard under Apps → Customise, and previewed live as you change it. The settings are stored as JSON and compiled into CSS custom properties at render time.

GroupSettings
Identity title, logo_url, currency_name, currency_icon_url, exchange_rate, support_url
Palette color_bg, color_surface, color_surface_alt, color_text, color_muted, color_border, color_accent, color_accent_text, color_reward
Shape radius, icon_size, icon_shape, card_min, gap
Layout layout (grid · list · compact), show_tabs, default_tab, show_search, show_history, show_balance, sort
Advanced custom_css, custom_header_html (sanitised)

Reward history

With show_history enabled the wall gains a tab listing that user's recent attempts — every offer they started, whether or not it paid — and what became of each: started, clearing, credited, not eligible, or never completed. It answers "where are my coins?" without a support ticket, which is the single most common message any rewards product receives.

Listing attempts rather than conversions is deliberate. A user who did an offer and was not credited has no conversion, so a list of conversions shows them an empty page — which reads as "we have no record of you", and is the one answer guaranteed to produce a complaint.

Support

Every wall carries a Contact support link, and any attempt that did not pay carries a Missing reward? link beside it. Both open a ticket against that user, tied to the click they are asking about. They can return to it from the same wall — it is keyed to their user_id, exactly as their reward history is.

We answer inside the wall. If we uphold a claim, the conversion is recorded and your postback fires like any other — so the user is paid by your own system, on your own rules, and you never have to reconcile a credit you did not issue. A declined claim closes with a reason the user can read.

Content security

The wall sends Content-Security-Policy: frame-ancestors listing your app's configured domain, so only you can embed it. Add every host that will frame it — including staging — under Apps → Settings, or the browser will refuse to render it.