Browse the help center

Landing-page helper reference

What the landing-page helper does after it is installed — one conversion per funnel step and per click, the payout field, how long the stored click id lasts on each browser, reading the click id from your own code, and every easq command and option.

Reference network manager advertiser Account → Advertisers → advertiser → campaign → Conversion actions → Conversion tracking code → Snippet

What the landing-page helper does once its block is on the advertiser’s pages: how each funnel step is fired and counted, how a payout from the page is priced, how long the stored click id survives on each browser, how to hand the click id to your own backend, and every command and option the runtime accepts. To get and install the block, see Install the landing-page helper; to check that it works, see Check and troubleshoot the landing-page helper.

Who this is for

The advertiser’s developer or tag-manager owner wiring conversions into the pages, and the account manager answering their questions about counting, payout and click-id lifetime.

Fire a conversion per funnel step

One easq('track', '<event>') call per step, where the step happens. The event name to fire is the exact key in the actions dictionary of your block — not the action’s name in Epom. The generator lower-cases that name and turns every space and punctuation mark into an underscore, so an action called “First Deposit” ships as first_deposit.

Case and whitespace are forgiven when the event fires: FTD, ftd and F T D all match a key of ftd. An underscore is not — easq('track', 'First Deposit') against a first_deposit key is answered unknown-event and no request is sent. Read the key out of the block rather than out of an email.

The helper counts an action once per click. Firing the same event a second time against the same stored click id is refused in the browser, before any request is sent, with the reason already-tracked. A second deposit, a repeat purchase or a page the visitor reloads does not produce a second conversion.

What still counts:

  • A different action on the same click. Each action keeps its own mark, so a registration → lead → first deposit funnel counts three conversions off one click. This is the case advertisers ask about, and it is the whole reason a funnel works.
  • The same action after a click on a different campaign. A click on another campaign is stored separately and starts fresh.
  • The same action from another browser or another device, or after the visitor clears their browser storage — the mark lives with the stored click, so it is gone with it.

What does not: clicking the same campaign’s ad again. The newer click takes the place of the older one and inherits its spent marks, so an action already credited in this browser stays credited. A visitor cannot re-open a counted conversion by clicking your ad a second time.

The rule is the track call’s default rather than a property of the action, and a single call can be written to skip the check — see once in Track options. No generated block ever writes it, so it is a hand edit to the advertiser’s page, and it changes nothing on the ad server’s side.

Note: the rule is enforced in the browser. On this path the ad server’s own duplicate check is a backstop that only runs when your network runs server-to-server duplicate detection and the action has Reject duplicate conversions ticked — off by default. Do not rely on the server to catch a repeat the browser could not.

Send a payout

When the campaign lets the page price the conversion, the generated block carries a payout on the steps you priced:

<script>easq('track', 'first_deposit', { payout: 12.5 });</script>

That line appears only in a block whose config says payoutOverride: true. The running example the install page uses — the block under Read the block — is the flag-off case: its config says false, so its track lines carry no payout and easq('debug') reports the page’s payout as ignored.

payout is not gtag’s value. It is the price of the conversion — what the advertiser is charged for it, in campaign currency — not what the order was worth. gtag('event', 'purchase', {value: 99.90}) means a 99.90 basket; easq('track', 'purchase', {payout: 99.90}) means the campaign is charged 99.90 for that conversion. They are almost never the same number, and an integrator porting a Google tag by hand is the person most likely to send the wrong one. Send the price of the conversion, or send nothing and let the campaign’s own rate apply.

Two things about the options object, both deliberate:

  • value, amount and sum are not read at all. The runtime looks at payout and nothing else, so easq('track', 'purchase', {value: 99.90}) is dropped inside the browser: no request field, no warning, and nothing in easq('debug'). Check the spelling against the generated block. (On a hand-built /at URL those three words are refused by the ad server, with an XD-warning: payout-word-refused on the response — see Get the pixel and S2S tracking code.)
  • A payout that is not a number — an empty field, a blank string, a value the page failed to read — is left off the request entirely rather than sent as zero. A page that read an empty element does not silently price the conversion at nothing.

A payout is only honoured when the campaign has Allow conversion action pricing overriding in URL switched on (campaign edit page → Basic information → Advanced settings). The Snippet tab’s own hint calls the same checkbox “Allow action pricing URL overriding” — one control, two spellings. The snippet records the flag for you as payoutOverride: true or payoutOverride: false in the config block, and easq('debug') says which way it went — see Check it with easq('debug'). When the flag is off, the payout still travels but the campaign prices the conversion itself, and the Snippet tab does not offer the field at all.

The flag is necessary and not sufficient. The payout replaces the campaign’s CPA price for that conversion, so it only does anything where the creative’s — failing that, the campaign’s — pricing type is CPA. On a CPM- or CPC-priced campaign the payout is ignored even with the flag on, and even though easq('debug') reports it as accepted — and the conversion is then recorded at zero revenue, because such a campaign has no CPA price to fall back to. Price the campaign or the creative CPA before you ask a page to override it.

If the campaign also has a Max payout per conversion, a higher payout is reduced to that ceiling and the conversion is still counted. Leave that field empty for no ceiling — a 0 in it is a real ceiling of zero, and it prices every conversion on the campaign at nothing.

The payout is read in the campaign’s currency, and the ceiling is applied before the campaign’s Exchange rate to base currency. On a campaign carrying an exchange rate the figure in your reports is therefore not the number the page sent: a payout of 12.50 on a campaign with a rate of 2 is recorded as 25.00.

How long the click id lasts

The stored click id is asked to live for 400 days, and the clock runs from the moment the ad was served — not from when this browser saw the link. A landing URL pasted into a forum a fortnight ago is already a fortnight old the instant somebody clicks it.

400 days is a ceiling on the storage, not an attribution window. The action’s own post-click window is checked on top of it only when two things are true at once: Apply attribution window to server-to-server conversions is ticked on the action, and the conversion carries a post-click or post-view classification. A conversion nothing classified is not window-checked at all — and the helper sends no attribution of its own, so on this path the classification generally comes from the action’s Default attribution type, which is Unattributed until somebody sets it. Leave it there and the storage is the only limit. See Create and edit conversion actions.

Browsers do not all honour the 400 days:

BrowserWhat it does with the stored click id
ChromeKeeps it for the full 400 days. Expiry measured.
FirefoxKeeps it for the full 400 days. Expiry measured.
SafariRecords 400 days, but the recorded figure is not the lifetime. See below.

On Safari, do not read the expiry as the lifetime. Safari records the full 400 days like the other two — that reading was taken and it is sound. What changed is that the number stopped being the field that decides. Since Safari 16, WebKit no longer enforces its seven-day rule by shortening a cookie’s expiry; it deletes script-written storage instead, on its own schedule, and the deletion leaves the expiry untouched. Cookies written by JavaScript and localStorage are swept together, after roughly seven days of browser use in which the visitor does not interact with the advertiser’s site — so the localStorage copy the helper keeps is no insurance here: on WebKit both halves are script-written storage and go in the same pass.

That is WebKit’s documented tracking-prevention behaviour rather than something measured on your network — the survival test costs eight days of not touching the browser and has not been run to a result. Treat it as the planning assumption anyway: the honest promise on Safari is the same session, and about a week, not 400 days.

Genuine interaction with the advertiser’s site resets that clock. A visitor who comes back, browses, logs in or buys keeps their click id alive. What is lost is a tail of late Safari conversions — the visitor who clicks, never engages, and converts more than a week later — not a cliff. Chrome and Firefox are unaffected and keep the full window.

A week is the upper bound, not a floor. WebKit also caps storage written after a cross-site click that carried a query string to 24 hours, where it has classified the originating domain as a tracker. We have not measured whether your ad-serving domains are classified that way, so treat the week as Safari’s best case rather than its normal one.

Plan for it rather than discovering it in a report: if the advertiser’s conversion lag runs to weeks and their Safari share is material, a server-to-server postback is the integration that survives it.

Storage ends a click id on every browser for three more reasons: the visitor clears their browser storage; the click passes 400 days; or the oldest are dropped to make room — past 25 click ids for the same ad-serving host, or sooner than that if the stored set would outgrow the browser’s ~4 KB cookie limit.

Read the click id from your own code

To forward the click id to your own backend — for a postback, a CRM record, an offline conversion:

easq('get', 'clickid', function (clickId) {
  // clickId is a string, or null when nothing is stored
});

clickid is the only thing get answers for; anything else calls back with null. When several ad-serving domains are configured on the page, the freshest stored click wins.

Options and fields

Five commands, and no others. An unrecognised command is recorded as a diagnostic and does nothing.

CommandWhat it does
easq('config', {…})Registers an ad-serving host and its event dictionary, and captures the click id from the current URL.
easq('track', '<event>'[, {…}])Fires a conversion for that event.
easq('get', 'clickid', fn)Hands the stored click id to your callback.
easq('arbitrate', 'last-click')Credits the later click when two of your ad-serving domains run on one page. last-click is the only accepted value.
easq('debug')Prints and returns the diagnostic report.

Config options, all emitted by the Snippet tab — there is nothing here an integrator is expected to set by hand:

OptionWhat it doesDefault
hostThe ad-serving origin conversions are sent to, and the identity of the account. Always written into a generated block.The origin the script was loaded from
actionsThe event dictionary: the advertiser’s word for each step, mapped to the action key it fires.{}
networkWhich network minted a click id, so one network’s block does not adopt another’s click on a shared landing page.none
payoutOverrideRecords whether the campaign accepts a payout from the page. Only ever a diagnosis — see easq('debug').not stated
clickIdParamThe parameter name the click id travels under, when the creative’s link uses one of your own.easclid

clickIdParam is a preference, not a switch: the runtime tries easclid, clickid, actionData, cid and txid regardless, and will still recognise a click id by its shape under any parameter name at all. Getting the field wrong degrades to the behaviour you had before it existed, not to nothing — and the debug output says when a click id was recognised that way.

Track options:

OptionWhat it does
payoutThe price charged for this conversion, in campaign currency. A value that is not a number is left off rather than sent as zero.
callbackfunction(result) — called once with {status, reason} after every configured account has answered.
onceDefaults to true: the already-tracked check runs. false skips it for that one call, so an event can count again on a click that has already spent it. The mark is still written, so every ordinary call after it is refused as before. Nothing in a generated block emits it.

Corner cases and gotchas

Corner case: renaming a conversion action in Epom does not break a page already running the block. The event name is the advertiser’s own word and the action key behind it does not change. Re-copy the block when you want the words to match, not to keep it working.

Corner case: several of your campaigns pointing at one landing page means several blocks — a block is always built for one campaign — and they do not add up to several accounts. Two config calls naming the same ad-serving host are one account, and their event dictionaries are merged name by name, so two blocks that both call a step registration leave only the last one pasted reachable. Where the two campaigns share the same conversion action that costs nothing — the key behind the name is the same one. Where they name different actions, the earlier action’s key is overwritten and it can never fire from this page again. Give each campaign’s steps names of their own in the Event name field on the Snippet tab.

Then fire one line — the one belonging to the campaign whose ad brought this visitor. The key in a generated block names only its action, never its campaign, so it does not decline a click from elsewhere: every line you fire is sent against whichever click is freshest, and the campaign credited is the one that click belongs to. Firing all of them books one conversion per action on a single click. Where the page cannot tell which campaign sent the visitor, give the campaigns separate landing pages rather than firing every line and expecting the mismatches to be refused.

Corner case: the same landing URL can be tagged by two networks. A block that names its network ignores a click id another network minted, with a note in the debug output. A block that names none adopts whichever click id it finds — which is what you get from a block generated before the field existed, and also from any network whose installation id has not been configured. If two networks share a landing page and neither block carries a network: line, ask Epom support or your account manager to set the installation id before re-copying both blocks.

Corner case: two ad-serving hosts configured on one page are two independent accounts with independent storage, and a track call goes to every account that knows the event name. Only the account whose ad was actually clicked holds a click id, so ordinarily one conversion is produced. If two genuinely do, the visitor clicked both ads and both conversions are real — unless the page arbitrates last-click.

Corner case: a browser holds at most 25 click ids per ad-serving host, and fewer if they would outgrow the cookie’s ~4 KB budget. An advertiser running very many campaigns at once loses the oldest. An evicted click takes its once-per-click marks with it, so a visitor who re-opens that landing URL afterwards is captured fresh and can convert on it a second time.

Corner case: a conversion the helper posts is a server-to-server conversion as far as the ad server is concerned. That is what gates the attribution window on it — see How long the click id lasts — and it gates the ad server’s duplicate rejection the same way: only when Reject duplicate conversions is ticked and your network runs duplicate detection. See Create and edit conversion actions.

Related pages

Please disable Adblock
Are you using adblock? Disable it and reload the page to proceed to the destination page.

A registration has already been submitted from this page. Please try again in 10 minutes.