Over seven articles we have now described the impression: what is for sale, who is looking, on what device, under what rules, in whose shared language.
This time the question is not about the impression at all. It is about the journey it took to reach the buyer – and whether everyone along the way is who they claim to be.
There are three standards that answer that: ads.txt, sellers.json and the SupplyChain object (schain). Almost everyone puts them in the same drawer labeled "ad fraud tools". I would argue that is the wrong drawer.
They do not catch fraud. A determined fraudster can fill in a SupplyChain object too. What they do is something quieter and more useful: They make the supply path accountable. schain is not a lock on the door. It is a signed receipt for every hand the impression has passed through.
Last time I argued that OpenRTB is a contract, not a spec – and that useful ideas start life in a blank "ext" field and move up into the core. I used source.ext.schain, which became source.schain in OpenRTB 2.6, as one of the three examples. This is the article about what that promoted candidate actually does.
Four terms, quickly:
*ads.txt = "Authorized Digital Sellers". Its app and CTV sibling is app-ads.txt, which does the same job for environments that have no website root to host the file on.
That last definition is the one to hold on to. STEP Network is an intermediary. When we sell a publisher's impression, we are a node in that bid request's supply chain – a line of JSON a buyer at the other end can look up.
Here is the framework for the entire article. The three standards are not competitors, and they are not redundant. Each answers its own question, and they only work together.
Two of them are reference works, written once and read often. One is a living receipt, stamped on every single auction. The magic is that they cross-reference each other: The ad system's domain in your ads.txt is the same asi in the schain; your account ID in ads.txt is the same sid in the schain and the same seller_id in the ad system's sellers.json. Same values, three documents. A buyer can triangulate.
Visualization generated with claude.ai
We sell two kinds of inventory, and the ads.txt files reveal the difference immediately.
jv.dk is a JFM title that we at STEP Network run as owned-and-operated*. Here is an abbreviated ads.txt, but you can look up the full file at jv.dk/ads.txt:
#JFM JV.DK stepnetwork.dk, 500, DIRECT adform.com, 122, DIRECT appnexus.com, 7779, DIRECT, f5ab79cb980f11d1 google.com, pub-5204991212765133, DIRECT, f08c47fec0942fa0 omnicommediagroup.com, S012, RESELLER ... OWNERDOMAIN=stepnetwork.dk MANAGERDOMAIN=stepnetwork.dk
*STEP Network is a subsidiary of JFM, which is why we "own" the JFM domains in schain terms.
Boligsiden.dk is different. Boligsiden A/S owns that site; we represent it as an intermediary. Same ad systems, but look at what changes:
#STEP boligsiden.dk stepnetwork.dk, 9, DIRECT adform.com, 122, RESELLER appnexus.com, 7779, RESELLER, f5ab79cb980f11d1 omnicommediagroup.com, S012, RESELLER ... OWNERDOMAIN=boligsiden.dk MANAGERDOMAIN=stepnetwork.dk
Three differences carry the entire distinction between owned and represented:
No one forces that honesty. The format simply gives you room to be precise – and being precise is what gets you paid.
Look again at one line that appears in both files:
omnicommediagroup.com, S012, RESELLER
We authorize the agency group Omnicom Media Group, account S012, to resell. Now follow that ID into Omnicom's own sellers.json:
{ "seller_id": "S012", "name": "STEP Network", "seller_type": "BOTH", "domain": "stepnetwork.dk" }
There we are as STEP Network – inside the agency's identity register. And seller_type is BOTH: We are a publisher (of our owned inventory) and an intermediary (reselling into Omnicom's marketplace). And then, in our own sellers.json:
{ "seller_id": "500", "seller_type": "PUBLISHER", "name": "JFM A/S", "domain": "jv.dk" }
So a single jv.dk impression sold through the agency path reads, in supply chain terms: jv.dk, owned by JFM → sold by STEP → resold through Omnicom → bought by the advertiser. Three files, two sellers.json registers, one entity (us) appearing in both – and every hop can be checked at both ends.
That is the part people overlook about operating as a network. The moment your demand partner is an agency running its own sellers.json, you do not only appear in your own books – you appear in theirs, and seller_type: BOTH does real work. A buyer looking up "BOTH" cannot assume from the static files alone whether you own the inventory or are reselling it in a given request. Only the living schain settles that.
None of this stands still while the auction runs. The schain is assembled as the request travels: Every system that touches it – ad server, then SSP, then onward toward the DSP – adds its own node before passing it along.
"source": {
"schain": {
"ver": "1.0",
"complete": 1,
"nodes": [
{ "asi": "stepnetwork.dk", "sid": "500", "hp": 1 },
{ "asi": "omnicommediagroup.com", "sid": "S012", "hp": 1 }
]
}
}
By the time it reaches the buyer, the nodes array is the collected story of everyone who has handled it. And the receiving side is expected to check it: parse each node and confirm that asi and sid are authorized in the publisher's ads.txt and can be looked up in the ad system's sellers.json. Reference works, meet the living receipt. That round trip – the request going down the pipe and being verified back against the static files – is the entire point of the layer.
The complete flag is the honest part of the spec. complete: 1 means the chain contains every node all the way back to the inventory's owner. complete: 0 means it does not – and the rules are strict about how you admit it: If you resell inventory that arrived without a SupplyChain object, you create one, set complete: 0 and add only your own node. You are explicitly not allowed to copy the chain along and pretend you were not there.
Visualization generated with claude.ai
So what happens to an incomplete chain? Here is what surprises people: It still gets traded. Buyers can configure their DSPs to reject anything without a complete chain, and some do. But mostly they do not reject. They discount.
Trust here is priced, not enforced.
Supply path benchmarks from 2026 make it concrete: Resold ("rebroadcasting") supply now accounts for roughly 27% of all bid requests but captures only around 18% of spend – a monetization deficit of nearly 50% per bid request measured against the most direct paths. The reselling era is not over. It is just being repriced – downward.
I will be honest about our own side of this: I cannot show you a pile of messy data on "unauthorized demand", because we do not allow it at STEP Network. We run a tight ship with our partners, so our chains are complete as policy, not as hope. That discipline is not bureaucracy. It is the product itself.
As a buyer you do not write this layer, and as a reader you barely see it. But if you sell inventory, this is some of the highest-impact, lowest-glamour work in the house:
The rule of thumb I will leave you with: If a buyer cannot trace the impression back to you in three lookups, they pay you as if they cannot.
If all of the above sounds like a lot of moving parts to keep honest – that is because it is. The numbers are sobering: The top 20 publishers integrate with an average of 24.5 SSPs each, and the number of distinct paths to a single impression can run as high as 600 (according to Sincera, now part of The Trade Desk).
The industry's answer is to make the chain shorter. The clearest example is OpenPath: The Trade Desk plugging directly into a publisher's inventory through a Prebid adapter, handling the payment to the publisher itself and cutting out one or more SSP hops entirely. Fewer nodes, fewer fees, a shorter schain, a cleaner path. They have since acquired Sincera and launched OpenSincera, which scores path quality on things like ads-to-content ratio and page weight. The pitch, in their own words, is "a clean, unadulterated supply chain".
It is fundamentally a good instinct – the sell-side version of pruning your own paths. But I will hold on to one honest caveat. A DSP that pays publishers directly is, whatever it says about itself, taking on a sell-side role. And a publisher routing through one dominant "direct" path is trading intermediary jungle for platform concentration. Fewer hops, yes – but possibly also fewer owners of those hops. Whether "direct" stays clean or just relocates the gatekeeper is perhaps a topic for another time.
Three standards, three questions, one job:
They are three sides of the same problem because they only work together – they cross-reference the same values, so a buyer can trace the path back to the owner. None of them detects fraud. All three create accountability – and in a market where trust is priced rather than enforced, accountability is just another word for yield. You control more of this layer than anything else in the bid request. Filling it in completely is the cheapest revenue work in the entire stack.
This is the eighth article in the nine-part series What is actually hiding in a bid request?
Next time, part 9 – the series finale: Custom data & publisher strategy. We have spent eight parts on what the bid request says. The final question is the one only you can answer: What do you choose to reveal about your own audience and your own inventory – and what is it worth?
Next: Part 9 of 9: The one part of the bid request you write yourself →
Let us help you get the most out of your display campaigns.