LabArticleSeat-verified

Why an empty allowlist serves nothing

inventory_source is an allowlist. An empty list compiles to an expression that matches no inventory. The apply path returns 409 rather than shipping a campaign that cannot serve.

Published 2026-09-09 · Search job: inventory source allowlist

An inventory source allowlist is a list of exchanges you will buy, not a list of exchanges you will skip. On this seat, inventory_source has no exclude form. If the compiled list is empty, the expression matches no inventory and the next campaign will not serve. The Supply Audit apply path returns HTTP 409 in that case on purpose.

If you emptied the list thinking "block everything bad," you built a campaign that bids on nothing.

Allowlist versus blocklist

Excluding one exchange means restating every other exchange you still want. When the buyer already sent an explicit allowlist, subtract from that list. When they did not, the fallback universe is supply_audit_runs.observed_inventory_sources from the latest covered run. That fallback genuinely reduces future reach. The product reports narrowed_from_unrestricted because the campaign used to accept every source the seat can see, and now it does not.

Never build that fallback from a no_account_rows run. A run that saw no delivery has no observed universe. Subtracting from an empty observation invents a list.

Placement and site are the opposite semantics. They are blocklists: adding a key only ever removes inventory. There is no universe, no narrowing caveat, and no way for a placement exclude to stop a campaign serving. Those keys live in a different planner. Mixing the two refusals is how a domain finding once got the old wrong custom_list message. See Placement vs site vs domain.

Why 409 is the correct refusal

An apply that shipped an empty allowlist would look successful. Targeting would exist. The campaign could be pointed at it. Delivery would then go to zero with no error at auction time that names the empty list. We have already lived through silent stops on lifetime budgets. We will not add another.

409 tells the caller the exclude would remove every remaining source. The fix is to keep at least one source, or to decide the campaign should be paused in the product, not compiled into a match-nothing expression.

What this is not

This is not a private marketplace. This is not QPS. Front-end QPS filters decide which auctions enter the bidder. An inventory_source allowlist decides which already-received requests may bid. Tightening the allowlist does not free contracted QPS. QPS is not targeting.

This is also not a scan. You still cannot name the waste exchanges before a flight that has delivery. Scan then exclude remains the order. The allowlist rule is only about how the exclude compiles after you have something to subtract.