Adskeeper buys clicks across a wide pool of native widgets, so two clicks from the same campaign can come from very different publishers. Appending these macros to your landing-page URL lets ValidVisit attribute every visit back to its exact widget, then judge each visit Valid or Invalid, with its evidence so you can see which widgets are sending real readers and which are sending invalid traffic.
Cross-check any macro against the network’s official documentation. Adskeeper official docs →
On Adskeeper, attribution rides on a handful of URL parameters the platform fills in at click time. The one that matters most for sourcing is {widget_id}, the publisher widget the click came from, and you'll usually pair it with {campaign_id} and {teaser_id} so you can split performance by campaign and creative too. The required token is {click_id}, Adskeeper's auto-generated unique id for each click, which gives ValidVisit a stable key to tie a click to its widget even when everything else looks identical. These are plain query parameters in curly-brace format, no funnel hop or extra hop needed; Adskeeper substitutes the real values as the visitor lands.
Per-widget granularity is the whole point, because Adskeeper's value lives at the widget level, not the campaign level. Once every click is tied to its {widget_id}, ValidVisit reports an invalid share for each widget so you can see exactly which publishers are padding your numbers with bots and IVT. The verdict comes after the visit has landed and never stops a widget from serving. Acting on it is a manual step you take in Adskeeper: open the campaign's Widgets tab and Stop / Block the widgets with a high invalid share, or blacklist the whole site if it's a repeat offender.
| Token | Adskeeper macro | ValidVisit param | Example |
|---|---|---|---|
| Campaign IDcampaign | {campaign_id} | vv_campaign_id | 55501 |
| Teaser (Creative)creative | {teaser_id} | vv_creative_id | 99012 |
| Widget (Publisher)publisher | {widget_id} | vv_publisher_id | 33044 |
| Click ID *click | {click_id} | vv_click_id | ck_77 |
{campaign_id}vv_campaign_id{teaser_id}vv_creative_id{widget_id}vv_publisher_id{click_id}vv_click_id* required for Adskeeper attribution.
https://yoursite.com/landing?utm_source=adskeeper&utm_medium=native&vv_campaign_id={campaign_id}&vv_creative_id={teaser_id}&vv_publisher_id={widget_id}&vv_click_id={click_id}Append these params to your landing-page URL — Adskeeper fills the macros at click time, so every visit arrives attributed and ready to judge. No funnel hop.
Carries a per-click id, stored with each visit so a verdict traces back to the click.
Tokens last verified against Adskeeper’s docs on 2026-10-02.
The buyer pastes/sets bad widget UIDs into the campaign’s widget filter (block/stop the widget in the Widget Optimization interface, or set widgetsFilterUid="except" + the UID list via API), or creates an auto-blocking rule that disables widgets/sub-sources meeting loss thresholds.
{widget_id}. It maps each click to the specific publisher widget that served your teaser, which is the unit you can actually act on in Adskeeper. {campaign_id} and {teaser_id} add campaign- and creative-level context, but {widget_id} is what ties a verdict to a sub-source you can stop.
No. These are ordinary URL query parameters in Adskeeper's curly-brace format, like {widget_id} and {click_id}. You add them to your destination URL and Adskeeper replaces them with the real values on each click. There's no funnel hop, no extra hop, and {click_id} is required so every click carries a unique id.
No. ValidVisit attributes each visit to its {widget_id} and reports a verdict after the click arrives. Excluding traffic stays in your hands: open the campaign's Widgets tab in Adskeeper and Stop / Block the widgets with a high invalid share, or blacklist the whole site if needed.
See which Adskeeper publishers and placements send real buyers vs. bots.
Join the waitlist with just your email · 7-day trial at launch
One script · no cookies · no device IDs · raw IP never stored