LabArticleSeat-verified

Placement vs site vs domain: which exclude actually works

Placement and site are direct targeting keys. Domain and app_bundle need seat-level reference lists. The old custom_list sentence blocked 59 percent of findable waste.

Published 2026-09-09 · Search job: how to exclude bad ad placements

You exclude a bad ad placement by sending the placement key, not by building a list object first. On this seat, placement and site are direct targeting keys: related_field is key, comparator equals, usage tips <exchange_handle>/<placement_id> and <exchange_handle>/<site_id>. They need no list object. domain and app_bundle still need seat-level reference lists. That split is the whole article.

The old product sentence said placement, domain, site, and app_bundle all needed Beeswax app_site lists plus a child-seat custom_list the compiler could not emit. That sentence was wrong. It blocked 59 percent of the waste the first real Supply Audit run found: $47.71 at placement plus $34.21 at site, of $138.53, versus the $7.79 the product could act on.

What we verified

GET /rest/v2/ref/targeting-keys?module=app_site is the catalog we trust. domain_list, app_bundle_list, and the other list keys point at /rest/v2/ref/lists. placement and site do not. They are direct keys.

We re-checked this after the wrong refusal had already shipped. The apply path now treats placement and site as actionable and still refuses domain names with the accurate reason: they need domain_list and /rest/v2/ref/lists, not custom_list. Do not re-block placement or site to make an older doc consistent.

Stored Supply Audit keys are composites and must be split before they are sent. A placement arrives as ${inventory_source}|${Placement}, for example OPENX|ox/558246019. A site arrives as ${inventory_source}|site:${Site ID}. The Beeswax value is the part after the pipe, because the report's Placement and Site ID columns already carry their own exchange handle. Sending the un-split key compiles to an expression that matches no inventory. The buyer then thinks the placement was excluded while it keeps serving.

Two planners, opposite semantics

inventory_source is an allowlist. Excluding one exchange means restating every other one. An empty allowlist serves nothing and returns 409. That planner is a different file from the app_site blocklist planner. Adding a placement or site key only ever removes inventory. There is no universe to compute and no "narrowed from unrestricted" caveat. Do not import one planner's refusals into the other.

Why an empty allowlist serves nothing is the allowlist article. Domain waste after we filter exchanges is the remaining honest limit.

What this does not fix by itself

A working exclude still needs a scan. The 1,073 zero-click placements on Supply Bench could not be named before the flight. Scan then exclude is the order of operations.

Apply creates new targeting. It does not pause a campaign, edit a live line item, or write to Beeswax. live_delivery_changed: false is part of the response contract. A finding marked applied can keep appearing for the whole lookback window if no campaign is pointed at the new targeting. That is not a failure of the key. It is a failure to attach the targeting you just built.