ctx.*, plus a match policy. A card serves only where what
you accept overlaps the page. Serving is that intersection; the policy is your lever.
Two sides meet at serving
Think of it as two sides that have to agree. On the supply side, your fragment declares what it accepts, including its match policy (match_mode). On the demand side, each card carries its own
targeting (its advertiser_id, the page topics it is for). A card is eligible only when you accept it
on the fragment and it clears that policy. The page context, meaning a brand detected on the page and your
ctx.* values, then helps pick which eligible card serves.
The hard gate is what the publisher accepts (and the match policy): only brand_only returns no-fill. Page context and ctx.* are soft signals that pick which eligible creative serves.
match_mode=brand_only returns no-fill ()
when no eligible card matches a detected brand. Page context and ctx.* are soft preferences layered on
top: they shape which eligible card is chosen, but on their own they never force a no-fill.
1. What you accept: key-values → ctx.* params
The key-values you define on a fragment are the parameters you accept on that fragment. Each becomes actx.<key>=<value> query parameter your edge appends to the fragment URL, passing page
context to doubleshift to help it pick the most relevant card.
Key-values → ctx.*
ctx.section from the page’s section. On the endpoint, each non-empty ctx.* value
is matched against the candidate cards (their brand and keywords) to prefer the most relevant one. It
is a soft preference, not a filter: a ctx.* value that no card matches is simply ignored, and it never
forces a no-fill on its own. Because they live in the URL, the response stays cacheable by URL.
2. Your policy: match_mode (per fragment)
Each fragment carries a card matching policy,match_mode, your lever for how tightly serving is
tied to a brand actually detected on the page:
The policy tightens the supply side from the most permissive (open) to the most selective (brand
only). It never overrides eligibility: a card still has to be one you accept and one the page context
matches.
How a brand match is resolved
Whenmatch_mode is not open, doubleshift matches the page against your eligible cards by
advertiser_id: a card matches a page when its advertiser_id equals a brand on that page.
advertiser_id is the join key between a brand and a creative. The policy only controls the fallback:
brand first falls back to any eligible card; brand only returns no-fill instead.
Roadmap: accepting external creativesToday the creatives are your own cards (or platform-wide cards), so the demand side is yours. In the
future, a publisher will be able to accept external creatives supplied by separate advertiser
accounts onto a fragment, and the same controls on this page (what you accept and your
match_mode
policy) decide what you let onto your inventory. The model does not change; only the source of the demand
widens.