Tracking links

How a user gets from the wall to your product, and how we keep hold of the thread that lets us prove they did.

The click URL

https://trovewall.com/go/{app_key}/{offer_id}?user_id=USER_ID

Hitting it does four things and then redirects:

  1. Re-checks that the offer is still eligible for this user, device and country.
  2. Mints a 32-character click_id from random_bytes.
  3. Records the click with IP, country, device, OS, referrer and your sub values.
  4. Substitutes the macros in the advertiser's tracking URL and sends a 302.
A click URL is not idempotent — each hit creates a click. Never prefetch it, and do not put it in an <img> or a link preview.

Macros in your tracking URL (advertisers)

Put {click_id} in the URL you give us. Everything else is optional.

https://you.example/lp?utm_source=trovewall&aff_sub={click_id}
    &geo={country}&device={device}
MacroSubstituted with
{click_id}The click identifier. Required — without it no conversion can be attributed.
{offer_id}Numeric offer id
{app_id}Numeric app id of the placement
{publisher_id}Numeric publisher id — useful for your own source reporting
{country}ISO 3166-1 alpha-2, or empty if unknown
{device} · {os}Detected device class and operating system
{ip}Click IP address
{timestamp}Unix seconds at click time
{sub1}{sub5}Publisher-supplied values, URL-encoded
Pass {click_id} back verbatim. It is already URL-safe hex. Truncating it to 20 characters, lower-casing it or re-encoding it are the three reasons a postback comes back UNKNOWN_CLICK.

The conversion window

A click is valid for the offer's conversion_window_hours — 30 days by default. A postback after that is recorded with EXPIRED rather than silently dropped, so a dispute can be investigated with evidence rather than memory.

Sub IDs (publishers)

Attach up to five of your own values to a click by adding sub1sub5 to the wall or click URL. They are stored, returned on the postback and reportable — the usual use is your own placement or campaign identifier so you can see which of your surfaces performs.

https://trovewall.com/wall/pk_live_a1b2c3?user_id=abc123
    &sub1=sidebar&sub2=variant-b

Two formats are redirected to us, not to the advertiser

Five of the seven formats send the user on to the advertiser. ptc and video do not: for both, the thing being bought is attention rather than an action on somebody else's server, so there is nobody to hear a postback from and we are the only party who can measure it. The same click_url lands on a Trovewall page instead — a countdown above a frame of the advertiser's site for ptc, and a video player for video.

Publishers need do nothing differently. Send the user to click_url exactly as for any other format and wait for the postback — it arrives when the timer completes, through the same queue, signed the same way. There is no separate endpoint and no client-side callback to handle.

The timer is counted on our server and only advances while the page is the visible tab, so a user who opens ten offers in ten background tabs completes none of them. That is deliberate, and it is the reason neither format can be completed faster than the time it actually asks for, whatever the browser claims. For video that time is the creative's own duration, read from the VAST document.

The VAST complete beacon is forwarded to the advertiser so their reporting matches ours, but it does not decide anything. A beacon is something a browser sends, which makes it something anything can send; the conversion is decided by the same server-side clocks that decide a PTC one.

Advertisers, for ptc: your landing page has to permit framing. A destination sending X-Frame-Options: DENY, or a Content-Security-Policy whose frame-ancestors excludes trovewall.com, renders as an empty panel and converts nobody.

Advertisers, for video: your VAST tag must be reachable over HTTPS from our servers and must offer a progressive video/mp4, video/webm or video/ogg media file. HLS and DASH are skipped rather than half-played. Wrapper chains are followed up to four deep and every level's beacons are fired. A tag that resolves to no ad, or to no playable media, serves nobody and credits nobody — the offer simply shows an unavailable message, so check the tag before you go live.

Why a redirect and not a direct link

Linking the advertiser directly would be faster by roughly 40 milliseconds and would make the whole marketplace unworkable: there would be no record that the user was ever sent, no identifier for the advertiser to quote back, and no way to tell a real conversion from an invented one. The redirect is the product.