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.
sub1 … sub5 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.