Chat on WhatsApp

sellers.json, ads.txt, and SupplyChain Object: An Implementation Guide for SSP Teams

If you are running an SSP, you have probably got all three of these sitting somewhere already. ads.txt, sellers.json, and the SupplyChain Object implementation aren’t really three separate jobs though, even if it looks that way at first. ads.txt tells a buyer who’s authorized to sell. sellers.json says who that seller actually is. schain shows how the request moved hop by hop.

Here’s the part most teams miss. These three aren’t independent compliance checkboxes; they are three views of the same supply path. Get one wrong, and the whole story stops making sense to a buyer looking at your inventory.

“ads.txt establishes who is authorized to sell inventory, sellers.json identifies the entities behind those seller IDs, and SupplyChain Object shows how those entities participate in the transaction path. The three work together to give buyers a more complete view of the supply chain.”
Manoj Donga, MD, Tuvoc Technologies

1 : How ads.txt, sellers.json, and SupplyChain Object Form One Transparency Model

Three files, one supply path. That’s really the whole idea behind ads.txt, sellers.json, schain, even though most write-ups treat them like three separate homework assignments.

Each one answers a different question, though. Who’s allowed to sell? Who that seller actually is. How the request got from one place to another. Put together, they tell the buyer the whole story.

Standard Primary Role What It Answers Where It Lives
ads.txt Authorization Who is authorized to sell this publisher’s inventory? Publisher’s domain
sellers.json Seller identity Who is behind this seller ID? SSP / exchange domain
SupplyChain Object (schain) Supply-path representation Which entities are involved in the transaction path? OpenRTB bid request

1.1 : ads.txt: Establishing Authorized Seller Relationships

ads.txt answers one question only, really. Who’s allowed to sell this inventory? A publisher lists the sellers they have authorized, right there in a text file sitting on their domain. That’s the entire authorization layer, nothing more buried underneath it.

This is where supply path transparency actually starts, at the very top. Before identity, before the request even gets made. If a seller’s not listed here, a buyer’s first signal is already off.

1.2 : sellers.json: Identifying the Entities Behind Seller IDs

Now sellers.json, a different question entirely. Not who’s allowed, but who’s actually behind that seller ID showing up in a bid request. Every seller ID maps to a real entity, name, domain, and type sitting in this file.

That’s sellers.json requirements in plain terms: identity resolution for the buyer’s side. A seller ID alone means nothing without this file backing it up. This is what lets a buyer connect a number to an actual company.

1.3 : SupplyChain Object: Exposing the Transaction Path

Last piece, schain. This one’s about the path itself, not who’s allowed or who they are. The relevant entities involved in the transaction’s supply path gets recorded, right inside the bid request.

That’s how the SupplyChain Object works, in plain terms: a running record of entities the request touched. A buyer can look at this and see the actual route, not just trust that it was clean.

2 : Building the Publisher-Side Authorization Layer with ads.txt

Here’s where this stops being theory and turns into actual work. ads.txt implementation for SSPs starts with one thing, really, the record a publisher puts on their own domain, authorizing you as a seller.

We provide that ads.txt information to publishers directly; that’s just part of onboarding for us. Not a separate step tacked on afterward, it’s built into how publisher relationships start from day one.

2.1 : Structuring Seller Relationships for Publisher Inventory

Every line in that file says one of two things, basically. DIRECT, meaning the publisher’s selling straight through you. Or RESELLER, meaning someone else sits in between. That’s DIRECT vs RESELLER ads.txt, the whole distinction right there.

example-ssp.com, 12345, DIRECT, f08c47fec0942fa0
example-ssp.com, 67890, RESELLER, f08c47fec0942fa0

The publisher declares the SSP’s domain, the seller account ID, the relationship type, and the advertising-system ID. DIRECT indicates the publisher’s direct relationship with the named seller; RESELLER indicates that the seller is authorized through an intermediary relationship.

Sounds simple, but getting it wrong confuses a buyer fast. We give publishers the exact relationship to the list and the correct seller ID attached, so there’s no guessing on their end once it’s published.

2.2 : OWNERDOMAIN, MANAGERDOMAIN and Ownership Context

Two more fields matter here, from ads.txt 1.1. OWNERDOMAIN says who actually owns the inventory. MANAGERDOMAIN says who’s managing it day to day, which isn’t always the same company. That’s ads.txt OWNERDOMAIN MANAGERDOMAIN, and skipping it leaves a gap.

Why does this matter so much? Because a buyer trying to trace ownership hits a wall without these fields filled in properly. Leave them blank; the ownership chain just stops making sense partway through.

2.3 : Publisher Onboarding, Crawling, and Propagation

Getting the record right is only half of it, honestly. A publisher has to actually publish it, and then it has to get crawled, picked up, recognized as live. We provide publishers the ads.txt relationship they need; that part’s confirmed and working on our end.

Freshness is the harder piece, though, for any SSP really. Files change, crawlers run on their own schedule, and automated ads.txt validation across a large publisher base is still something mature operations have to build toward carefully, not something anyone gets fully automatic on day one.

3 : Engineering Seller Identity with sellers.json

ads.txt tells a buyer who’s allowed to sell. sellers.json answers something different: who that seller actually is behind the ID. sellers.json implementation is really an identity problem, not just a file sitting on a server.

We are actively building our own sellers.json implementation right now, worth saying plainly. Still under development on our end, not something we are claiming is live in production yet.

3.1 : Mapping Seller IDs to Verifiable Entity Records

Every seller ID needs to map to something real, a name, a domain, or an actual entity behind it. That’s sellers.json seller_id, the whole point of the file, honestly. Without this mapping, a seller ID is just a number floating with nothing attached.

Getting that mapping right from the start matters more than people think. We are working through exactly this in our own build right now, connecting seller IDs to verifiable records as part of what we are developing.

3.2 : PUBLISHER, INTERMEDIARY, BOTH, and Passthrough Relationships

Every seller record also carries a seller type: PUBLISHER, INTERMEDIARY, or BOTH. The classification indicates the seller’s role in the supply chain and helps buyers interpret who is representing the inventory. That’s PUBLISHER INTERMEDIARY BOTH, the classification layer.

There’s also something called is_passthrough, a flag showing whether a seller’s ID gets forwarded along without changes. It matters for tracing the chain accurately, though we are not claiming anything specific about how it behaves in our own setup yet.

3.3 : Keeping Seller Identity Current Across the Platform

Here’s the part nobody talks about enough. A sellers.json file isn’t something you publish once and forget, seller records change, companies merge, and relationships shift. That’s how SSPs maintain sellers.json, the ongoing side of it.

A mature SSP needs a real source of truth behind this, something that catches changes and keeps records current automatically over time. That’s where we are heading with our own sellers.json work too, as the platform keeps evolving forward.

4 : Engineering the SupplyChain Object into the OpenRTB Request Path

This is where schain actually has to work, inside a real request, in real time. OpenRTB schain implementation isn’t just a spec you read once; it’s something that has to survive every single bid request passing through.

We are actively engineering our own SupplyChain Object work right now, building it into the request path. Still under development, not something we are calling finished or fully deployed yet.

{
“ver”: “1.0”,
“complete”: 1,
“nodes”: [
{
“asi”: “ssp.example.com”,
“sid”: “12345”,
“hp”: 1
}
]
}

4.1 : Constructing the SupplyChain Object and Its Nodes

Every schain object carries a version number, a complete flag, and a list of nodes. Each node has its own fields too, asi for the domain, sid for the seller ID, rid for the request ID, hp showing if the node’s actually visible. That’s schain node construction, piece by piece.

The sid field connects straight back to seller identity; that’s not optional, it’s how a buyer ties the node to an actual seller record. Getting these fields right at construction time matters more than most teams expect going in.

4.2 : Preserving the Supply Path Across Intermediaries

Here’s where it gets harder. When a request passes through more than one company, each one’s supposed to add their node, not erase what came before. That’s the core idea behind multi-hop supply chain handling, preserving every hop, not just the last one.

The complete flag matters here too; it says whether the whole chain’s accounted for, but it doesn’t guarantee accuracy on its own. Parent-child seller setups, where one seller manages several child accounts, add another layer of complexity mature systems have to handle carefully, not something we are claiming as a solved capability on our end.

4.3 : Serializing schain Across OpenRTB Versions and Integrations

Where this actually sits in the request depends on which OpenRTB version you are running. OpenRTB 2.6 places it at Source.schain, cleanly, as its own object. OpenRTB 2.5 handles it differently, tucked inside Source.ext.schain instead.

{
“source”: {
“schain”: {
“ver”: “1.0”,
“complete”: 1,
“nodes”: []
}
}
}

That’s the OpenRTB source schain, and the difference matters if you are integrating across partners running different versions. Using the wrong placement for the OpenRTB version can prevent downstream systems from interpreting the object as intended.

5 : Making ads.txt, sellers.json and schain Agree

Having all three files in place doesn’t mean much on its own, honestly. Programmatic supply chain verification is really about something else; do these three actually tell the same story when you put them side by side?

That’s the real question underneath everything so far. Not whether each file exists, but whether a buyer looking across all three sees one consistent supply path, not three conflicting versions.

5.1 : Aligning Seller IDs, Domains, and Supply Paths

Here’s what needs to line up. The seller ID in schain should resolve to the corresponding seller record, while the relevant domains and ownership relationships across ads.txt and sellers.json should remain consistent. That’s how to validate ads.txt against sellers.json, cross-checking across all three at once.

For a mature SSP implementation, these relationships should be validated before buyer-side supply-path evaluation happens, not after. Miss a mismatch here, and a buyer’s left trying to make sense of numbers that don’t actually connect to anything real.

5.2 : Handling Multi-Hop and MCM Relationships

Things get genuinely harder once more than one company sits in the path. Each node in schain needs its own fields filled correctly, asi, sid, the rest, that’s schain node fields doing real work across multiple hops, not just one.

Parent-child seller setups add another layer too, where one account manages several smaller ones underneath it. Preserving this correctly across every hop is something a mature SSP has to build toward carefully, not something that happens automatically out of the box.

5.3 : Detecting Inconsistencies Before They Reach Buyers

So why does the complete flag even exist? Why does schain need a complete flag? Basically, it’s supposed to tell a buyer whether the whole chain got captured or whether something’s missing along the way.

But a flag alone doesn’t catch everything. Real inconsistencies, a seller ID that doesn’t match, and a domain that’s off, those need actual checking before a buyer ever sees the request. Tuvoc is developing the underlying transparency components as part of its evolving SSP architecture, working toward exactly that kind of checking over time.

6 : Designing Supply-Chain Transparency for Scale and Change

Getting all three files right once isn’t the finish line, not even close. Supply chain transparency implementation has to survive your platform actually growing, sellers changing, and inventory shifting underneath it.

This is really the maturity question. Not did you build it, but does it still hold up a year later, after a hundred more sellers got added to the mix?

6.1 : Establishing a Consistent Source of Truth

Every seller record needs one place it actually comes from, not five different spreadsheets disagreeing with each other. That’s SSP transparency compliance at its core, one authoritative source everything else pulls from.

Building platform-level systems like this is exactly the kind of work we do across our broader engineering work, not just for transparency data specifically. It’s the same discipline, just applied here.

6.2 : Managing Caching, Propagation, and Seller Changes

Seller records don’t stay still though. Someone changes domains, a company gets acquired, and a relationship shifts from DIRECT to RESELLER overnight. That’s sellers.json caching and propagation, keeping every system updated once something changes upstream.

A mature setup needs to catch these changes fast and push them out everywhere they are needed, without waiting days for stale data to work its way through. That’s the kind of operational discipline our broader production infrastructure experience has been built around.

6.3 : Moving from Manual Checks to Continuous Validation

Most teams start here with manual checks, someone looking things over by hand. That works for a while. sellers.json validation eventually needs to move past that, though, toward something that runs continuously instead of waiting for someone to notice a problem.

We don’t have that automated piece running today; it’s worth being straightforward about it. But it’s part of where our SSP architecture is heading, moving from manual review toward continuous checking as the platform keeps maturing.

 

Have an Idea? Let’s Shape It!

Kickstart your tech journey with a personalized development guide tailored to your goals.

Discover Your Tech Path →

Share with your community!

Latest Articles

Vertical Embedded Finance: Adding Payments and Lending to Your SaaS (Build vs. BaaS)
8th Oct 2026
Vertical Embedded Finance: Adding Payments and Lending to Your SaaS (Build vs. BaaS)

Your SaaS already owns the workflow. Most people talking about embedded finance for SaaS skip right past that part, but…

When to Choose a White Label Real Estate App Development Company and Why?
8th Jun 2026
When to Choose a White Label Real Estate App Development Company and Why?

Most real estate businesses we talk to aren't short on leads or deals. Even your search for a white-label real…

Real-Time Payment Infrastructure Architecture: Why Money Can No Longer Move at Yesterday's Speed
5th Jun 2026
Real-Time Payment Infrastructure Architecture: Why Money Can No Longer Move at Yesterday’s Speed

Blog Summary Money still moves through infrastructure built for another era Consumer expectations are reshaping payment system priorities Real-time payments…