Browse the help center

Daisy chaining and passbacks reference

Every control, grid column and fallback field of daisy chaining, when the default code is returned, how passbacks are counted and paid, the re-selection cap and the REST calls — the companion to the Set up daisy chaining and passbacks guide.

Reference network manager Account → Publishers → site → zone → placement → Daisy chaining

The companion to Set up daisy chaining and passbacks, which has the steps, the caveats and the fix-it checklist.

Daisy chaining controls

ControlRange / valuesWhat it does
Card switchon / offOn creates the chaining record and auto-populates the chain in Banner mode. Off deletes the record, the order and every setting below, after a confirmation.
Lookup depth1–100, network default 5The walk gives up once this many excluded chain entries have been skipped, so it steps over at most depth − 1 of them and still serves the next one. Also raises the per-request reselection cap (see The reselection cap).
View 1-N per banner / per campaigncheckbox + 1–10 000 000, default 1Serve each entry this many times to the same visitor before moving down. Counted in a per-placement cookie.
Rotate 1-N timescheckbox + 1–10 000 000, default 1Caps how many times the exhausted chain restarts for one visitor. Disabled until view-per-entity is on.
Apply prioritiescheckboxGroups the chain by delivery priority and adds a per-tier enable + country list.
Per-tier checkbox + Countryone row per delivery priority; * = GlobalWhich delivery tiers take part, and in which countries.
TypeBanner / CampaignWhether chain entries are banners or whole campaigns. Changing it rebuilds the chain.
Top / Up / Down / Bottom—Move the selected row. Enabled only with exactly one row ticked.
Refresh—Re-reads the chain from the server.

The six delivery-priority tiers, strongest first: Premium, Standard High, Standard Medium, Standard Low, Non-guaranteed, House ads.

The network default for a new chain’s Lookup depth is set under Admin → Ad serving → Inventory & campaigns settings → Daisy chaining lookup depth (5 unless changed).

Chain grid columns

ColumnNotes
PriorityDisplay position, renumbered from 1 within each group when Apply priorities is on
AdvertiserMasked for users with the campaign-masking permission unless they own the advertiser
CampaignAs above
BannerOnly in Banner mode
Priority (group)Only with Apply priorities on — shows the tier name plus the row’s country

Fallback fields outside the card

FieldWhereWhat it does
Default codeplacement → Basic info → Advanced settings (Site, Mobile site and Non-standard site placements; needs Placement Default Code)Markup returned when nothing filled. Macros are substituted with the same processor as banner markup: $$RANDOM$$, $$TIMESTAMP$$, $$PAGE_URL$$, $$COUNTRY$$, $$PLACEMENT_ID$$, $$CHANNEL$$, custom parameters and the rest of the request, page and placement set. Banner, campaign and advertiser macros and the click URLs come out empty; a recognised macro that cannot resolve is removed, an unrecognised token is left as written.
Third-Party lookup limit (thirdPartyNetworkLookupLimit)Deprecated. REST API only — the placement form no longer shows it0–10; a new placement starts at 5. Caps how many times one request may drop the chosen banner and re-select — the loop that recovers an impression a third-party tag passed back. It was the lookup budget of the server-side mediation that has since been removed; leave it alone.
Enable passback functionalitybanner → Basic informationLets this banner’s tag hand the impression back to Epom. Offered for a Code banner on a Standard / Non-standard / Mobile site placement, or a Template banner on a Standard / Non-standard site placement, to a role holding the Ajax invocation-code permission of that placement type, on a network with an AJAX invocation-code domain configured.
Banner passback codebanner → Basic information, after savingThe generated one-line <script> snippet to give the third party. It postMessages {by: <serving domain>, bId: <banner id>, pb: true} up the frame chain to the Universal JS loader, which re-requests the ad; it works with the Universal JS tag only. With more than one AJAX invocation-code domain, a Domain picker rebuilds the snippet for the chosen domain (the first is preselected); the choice is not saved with the banner.
$$PASSBACK_INFO$$ / $$PASSBACK_INFO_ESC$$a fallback URL in tag or redirect flows that cannot post a messageExpands to `pb=customwl.unipass.p:

When a request arrives carrying that passback value, Epom excludes the named banner from selection for this request, writes a passback log record for it, and re-runs banner selection.

A default code stored on a placement type the console does not draw the field on — the REST API accepts defaultCode for a role holding Placement Default Code — is never returned for an Application placement, never for a VAST/video request, and never from the native JSON endpoint; a Video or Native placement only sees it on the request paths listed below.

When the default code is returned

The default code is not tied to any particular failure. Every reason a request ends without a banner funnels through the same “no banner” branch, so all of these reach it:

Reason the request did not fillReaches the default code
No banner linked / campaign empty / no banner left in campaignyes
Targeting or pre-targeting mismatchyes
Frequency, click, action, no-click, IP or proxy cappingyes
Volume limits or per-action limits exhaustedyes
Size mismatch, placement type unsupported, in-stream type mismatchyes
Page competitor / same-campaign exclusionyes
Native creative missing required fields, or no native adapteryes
DSP did not bid, timed out, or bid below the site CPM thresholdyes
DSP excluded: second-price only, empty DSP UID, traffic tier, minimum marginyes
GDPR mediation restrictedyes
Banner excluded by exclude parameter, or by an inbound passbackyes
Every chain entry over its view limit and rotations exhaustedno — the last chain entry is put back and serves
A banner was selected but produced empty markupyes

What decides whether you actually get it is how the request arrived, not why it failed. Each entry point has its own no-fill response, and only some of them carry the default code:

How the request arrivesReturns the default code?
Universal JS / AJAX / the standard ad API — Standard, Non-standard, Mobile, Video, Email, Click-through, Native placementsyes
Iframe tagyes
Universal JS / AJAX / the standard ad API — Application placementno — empty response, no-impression logged
VAST / video requestno — an empty VAST document with an <Error> node
Native JSON endpointno — a native “no ads” JSON carrying a no-impression beacon
Video overlay requestno — empty response
Ad API v4no — JSON/XML/JSONP carrying only NO_IMPRESSION_BEACONS
Server-to-server call carrying a no-ads tokenno — only the no-impression marker
Unknown or deleted placement keyno — empty response

The site CPM threshold does not “trigger a passback”. It is a bid floor: DSP bids under it are rejected, and only if nothing else fills does the default code get its turn. See Set a site CPM threshold.

If Refresh after (sec) is set, the iframe tag’s no-fill response carries the same <meta http-equiv="refresh"> as a filled one, so a placement that never fills keeps re-requesting on that interval. The Universal JS / API no-fill response does not carry it.

How to confirm it fired

Two different mechanisms, two different metrics — and they live in different reports.

An unfilled request (default code returned, or nothing returned) is counted by the No ads column, which comes from the no-impression event. That event is fired by a no-impression.gif beacon embedded in the response, so it is only counted if the caller actually loads the returned markup.

A passback is counted by five Advanced-report columns. The first four are gated by the Impressions report-column permission:

ColumnMeans
Valid passbacksA passback that matched an impression of the same banner in the same transaction, neither side flagged as fraud
Rejected passbacksA passback with no matching impression, or with either side flagged as fraud
Fraud passbacksThe fraud subset of the row above — chiefly passbacks arriving from a blacklisted address
Rejected passbacks, %The second row as a share
Unique passbacksDistinct transactions with a valid passback; needs the Conversions and Unique report-column permissions instead

Alongside them, Eligible impressions, Fill rate, % and Effective fill rate, % all account for passbacks.

Those four columns come from a merge that joins passback records against impressions. They exist only in the Advanced report. The General report has no passback column at all — there, a passback shows up as a missing impression, because each passback’s count, gross and net are subtracted from the matching impression figures.

Is a passback counted and paid?

A passback carries a price: the ad server prices the banner at CPM for the placement and country and stores gross and net on the passback record. What happens next depends on the report:

  • General report — the passback’s impression, gross and net are subtracted from that banner’s impression aggregate. Net effect: the impression is undone and not paid.
  • Advanced report — both events are kept, so you can see how many impressions were handed away and what they would have been worth.

If the passback record cannot be matched to an impression (they can be recorded by different ad servers), the subtraction is skipped and a negative row is written instead — but only when the network runs Advanced reporting, so that negative impressions never reach the General report.

Passbacks from blacklisted addresses are recorded as fraud and excluded from the impression subtraction, so the original impression stands.

The reselection cap

When the banner Epom picked cannot produce a usable response, the request drops it and re-selects — at most max(thirdPartyNetworkLookupLimit, daisy-chaining Lookup depth) times. Raising the chain’s depth silently raises that cap too, and passback logging is suppressed on the retries so one passback is not counted twice. RTB (OpenRTB DSP) banners are never retried this way, except on Native placements.

The placement’s own number is no longer on the form: read it with GET /rest-api/placements/{placementId}.do and change it with the thirdPartyNetworkLookupLimit parameter of POST /rest-api/placements/update/<type>.do (0–10; a console save leaves it alone). The parameter is deprecated: a creative that cannot render is a bad pick, and the reselection hides it. One such case is gone — on the native ad endpoint, a Native placement with no native preferences of its own can build no response for any creative, and selection used to hand it one creative after another until the budget ran out; it now offers none, so the request answers no-fill once. The cases that remain (a template that produces nothing, code that is empty after macro substitution, a missing file) are counted per reason and named in the troubleshooting log, which is what has to reach zero before the budget can go.

Over the API

POST /rest-api/placements/{placementId}/chaining.do switches daisy chaining on (enabled=true, or a type: BANNER or CAMPAIGN) or off (enabled=false), and sets lookupDepth, viewPerEntityEnabled / viewPerEntityCount, rotatingEnabled / rotatingCount and groupByDeliveryPriority — only those you send. lookupDepth is 1–100, as in the console, and the two counts 1–10000000; a value outside is a 400 that names the range. enabled=false drops the chain, so sending it together with a type or an option is refused (400) rather than answered as if the option had been set.

GET /rest-api/placements/{placementId}/chaining.do reads the chain together with those same options and placementId / enabled (switched off, it answers {"placementId":…,"enabled":false,"daisyChains":[]}; a missing or deleted placement is a 404), and POST /rest-api/placements/chaining/update-priority.do reorders it. Reading needs the Daisy Chaining permission enabled or read-only; changes need it enabled, and update rights on the site.

GET /rest-api/placements/{placementId}/daisy-chain.do answers the order the ad server currently walks — as it holds it, so a change shows up after its next reload, within a few minutes — with names only for advertisers you may view, and null while chaining is off. A chain that is on but empty, without Apply priorities, comes back with an empty order: the placement serves nothing. It needs the same permission and view rights on the site. See the Placements API reference.

The per-tier country filters of a grouped chain are POST /rest-api/placements/{placementId}/chaining/delivery-priority-filter.do with deliveryPriority (PREMIUM, STANDARD_HIGH, STANDARD_MEDIUM, STANDARD_LOW, NON_GUARANTEED or HOUSE_ADS), enabled and countries (ISO alpha-2 codes, repeat the parameter; * or none sent means worldwide). enabled=true replaces the tier’s countries, enabled=false leaves the tier out of the chain. The chain must already be grouped (groupByDeliveryPriority=true), and an unknown country code refuses the call. Both the chain read and the setup answer list the tiers kept in the chain under deliveryPriorityFilters, each with its countries; right after grouping is switched on that is every tier with *.

Per-role notes

  • Publisher — once granted Daisy Chaining, the chain is one of the few delivery controls that is genuinely theirs: they decide the order their demand is tried in.
  • Network manager — the same card on the same placements, once granted.
  • Read-only grant or Can View share — the chain and its settings are visible but cannot be changed; where chaining is off, the card does not appear. Changes need Can Edit or Is Owner.

Exact grants: see User roles.

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.