Ad Specs Part 2: Sellers and Supply Chains

This is part 2 in a series on IAB Tech Lab adtech standards. Read part 1 here.

In the previous post I covered the ads.txt standard, proposing that the account relationship field be re-defined so that DIRECT accounts could only be used on a single site. This change would enable the industry to clean up mislabelled accounts and help tackle domain spoofing.

But it’s been over 4 years since ads.txt was released, and in the meantime it’s been joined by a pair of newer standards — sellers.json and SupplyChain object. Let’s take a look at these standards, and how they fit in with the proposed ads.txt update.

The Sellers.json Specification

Ads.txt exposes what accounts are authorized to sell a site’s inventory, but very little about the accounts themselves.

In July 2019 the IAB Tech Lab released the sellers.json standard. Where ads.txt is quite limited in its focus — tackling domain spoofing — sellers.json has more nebulous goals. It exposes extra information about the accounts used to sell ad inventory, in service of a “transparent marketplace”.

Screenshot of a paragraph under the title "Abstract". Paragraph reads: "As part of a broader effort to eliminate the ability to profit from counterfeit inventory in the open digital advertising ecosystem, Sellers.json provides a mechanism to enable buyers to discover who the entities are that are either direct sellers of or intermediaries in the selling of digital advertising."
The abstract section of the sellers.json spec.
Screenshot of a paragraph under the title "Audience". Paragraph reads: "Advertising systems, whether they are sellers or buyers of programmatic advertising both benefit from a transparent marketplace where all parties to the transaction are well understood. This document serves to define the information that sellers will provide to both downstream sellers and buyers of programmatic inventory."
The audience section of the sellers.json spec.

Sellers.json files are hosted by “ad systems” (sales houses, SSPs, ad exchanges, etc.), and list details of all the accounts used to sell ad inventory via each system.

These accounts are the same as the accounts listed in ads.txt files. In theory, the details for any account in an ads.txt should be able to be looked up in the relevant ad system’s sellers.json file.

The core information provided is the name of the company that is paid when inventory is sold via the account, along with its domain if it has one. Accounts can be marked as “confidential”, in which case these fields are omitted.

Screenshot of the definitions of the "name" and "domain" fields. Name: "The name of the company (the legal entity) that is paid for inventory that is transacted under the given seller_id. Can be omitted only when is_confidential is set to 1." Domain: "The business domain name of the company (the legal entity) that is paid for inventory that is transacted under the given seller_id. When the seller_type property is set to INTERMEDIARY or BOTH, this should be the root domain name of the seller’s Sellers.json file. Can be omitted when is_confidential is set to 1 or when the seller doesn’t have a web presence."
The definitions of the name and domain fields in the sellers.json spec.

Each account also has a “type”. If the company getting paid by the ad system (i.e. listed in the name and domain fields) owns the inventory being sold, it’s a PUBLISHER account. If the inventory is owned by a different company, it’s an INTERMEDIARY account. BOTH accounts sell both types of inventory.

Screenshot of the definition of the "seller_type" field. "An enumeration of the type of account, either PUBLISHER, INTERMEDIARY, or BOTH. A value of "PUBLISHER" indicates that the inventory sold through this account is on a site, app, or other medium owned by the named entity and the advertising system pays them directly. A value of “INTERMEDIARY" indicates that the inventory sold through this account is not owned by the named entity or the advertising system does not pay them directly. 'BOTH' indicates that both types of inventory are transacted by this seller. Note that this field should be treated as case insensitive when interpreting the data."
The definition of the seller_type field in the sellers.json spec.

PUBLISHER and INTERMEDIARY seem quite similar to DIRECT and RESELLER from ads.txt, but the definitions are based on different concepts — payment vs. control — so they don’t always align.

A small example sellers.json file for a fictional ad exchange:

{
    "contact_email": "admin@exchange1.com",
    "contact_address": "Exchange One Inc., 1 Queen St, London, United Kingdom",
    "version": "1.0",
    "sellers": [
        {
            "seller_id": "foo",
            "name": "Publisher One",
            "domain": "publisher1.com",
            "seller_type": "PUBLISHER"
        },
        {
            "seller_id": "bar",
            "name": "Sales House One",
            "domain": "saleshouse1.com",
            "seller_type": "INTERMEDIARY"
        },
        {
            "seller_id": "baz",
            "name": "SSP One",
            "domain": "ssp1.com",
            "seller_type": "INTERMEDIARY"
        },
        {
            "seller_id": "ekki",
            "name": "Exchange Two",
            "domain": "exchange2.com",
            "seller_type": "INTERMEDIARY"
        }
    ]
}

The SupplyChain Object Specification

Ad buyers have traditionally only been able to see the account they are buying off — the “last seller”. When buying direct, it’s this last seller account that needs to be DIRECT.

The SupplyChain object OpenRTB extension was released alongside sellers.json. It adds a list of upstream accounts to bid requests, enabling buyers to see the other accounts the inventory has passed through. For “complete” SupplyChains, this list starts all the way back at the “first seller” — the account of the site owner.

Screenshot of a paragraph under the title "Introduction". Paragraph reads: "Ads.txt has been extremely successful in allowing publishers and app makers to define who is authorized to sell a given set of impressions via the programmatic marketplace. Ads.txt does not however make any attempt at revealing or authorizing all parties that are part of the transacting of those impressions. This information can be important to buyers for a number of reasons including transparency of the supply chain, ensuring that all intermediaries are entities with which the buyer wants to transact and that inventory is purchased as directly as possible. The implementation should be as transparent as possible to buyers. It should enable them to easily understand who it is that is participating in the sale of any piece of inventory."
The introduction section of the SupplyChain object spec.

Once again, these are the same accounts as those in ads.txt and sellers.json files. Any account in a SupplyChain object should be authorized in the site’s ads.txt, and be listed in a sellers.json file.

An example SupplyChain object for an RTB request on our fictional ad exchange:

{
    "ver": "1.0",
    "complete": 1,
    "nodes": [
        {
            "asi": "ssp1.com",
            "sid": "123",
            "hp": 1
        },
        {
            "asi": "exchange1.com",
            "sid": "bar",
            "hp": 1
        }
    ]
}

Scenarios

Now we’ve covered what sellers.json and SupplyChain objects are, let’s take a look at how they interact with the proposed ads.txt update. I’ll focus on two scenarios that are affected by the new definition of DIRECT.

Sales Houses

Sites that use a sales house to sell their inventory often list all the sales house’s accounts with downstream ad systems as DIRECT. This wouldn’t be allowed under the updated definition.

The site must list the sales house’s accounts with downstream ad systems as RESELLER. The sales house should create a dedicated PUBLISHER account for the site in its sellers.json, with the domain set to the site domain. The site can then list their account with the sales house as DIRECT.

saleshouse1.com/sellers.json:

{
    "contact_email": "admin@saleshouse1.com",
    "version": "1.0",
    "sellers": [
        {
            "seller_id": "1111",
            "name": "Site One",
            "domain": "site1.com",
            "seller_type": "PUBLISHER"
        }
    ]
}

site1.com/ads.txt:

saleshouse1.com, 1111, DIRECT
exchange1.com, bar, RESELLER

Site One SupplyChain object:

{
    "ver": "1.0",
    "complete": 1,
    "nodes": [
        {
            "asi": "saleshouse1.com",
            "sid": "1111",
            "hp": 1
        },
        {
            "asi": "exchange1.com",
            "sid": "bar",
            "hp": 1
        }
    ]
}

Note that while this is a change from how many sales houses are set up currently, it’s actually what they should be doing already. This was confirmed by a representative of the IAB Tech Lab in response to the previous post. The new definition of DIRECT simply clarifies this scenario.

Screenshot of two tweets from @shails that read: "Isn’t the spec pretty clear the publisher must control the account that is as a business it must be the account owner", and "Your SSP’s account or someone exclusively managing your inventory cannot be direct is pretty clear. What’s needed is that publisher does not lie and seller due diligence about site ownership"
Tweets from the SVP, Product Management & Global Programs at IAB Tech Lab.

Multi-Site Publishers

Publishers that own multiple sites often have a single set of accounts with downstream ad systems that are listed as DIRECT by all the sites. This wouldn’t be allowed under the updated definition. To keep using these shared accounts, the publisher would need to act as an ad system.

Each site must list the publisher’s accounts with downstream ad systems as RESELLER. The publisher should create a sellers.json containing a PUBLISHER account for each site, with the domains set appropriately. The sellers.json must be hosted on the domain used in the publisher’s accounts. Each site can then list their account with the publisher as DIRECT.

publisher1.com/sellers.json:

{
    "contact_email": "admin@publisher1.com",
    "version": "1.0",
    "sellers": [
        {
            "seller_id": "aaaa",
            "name": "Site A",
            "domain": "site-a.com",
            "seller_type": "PUBLISHER"
        },
        {
            "seller_id": "bbbb",
            "name": "Site B",
            "domain": "site-b.com",
            "seller_type": "PUBLISHER"
        }
    ]
}

site-a.com/ads.txt:

publisher1.com, aaaa, DIRECT
exchange1.com, foo, RESELLER

Site A SupplyChain object:

{
    "ver": "1.0",
    "complete": 1,
    "nodes": [
        {
            "asi": "publisher1.com",
            "sid": "aaaa",
            "hp": 1
        },
        {
            "asi": "exchange1.com",
            "sid": "foo",
            "hp": 1
        }
    ]
}

site-b.com/ads.txt:

publisher1.com, bbbb, DIRECT
exchange1.com, foo, RESELLER

Site B SupplyChain object:

{
    "ver": "1.0",
    "complete": 1,
    "nodes": [
        {
            "asi": "publisher1.com",
            "sid": "bbbb",
            "hp": 1
        },
        {
            "asi": "exchange1.com",
            "sid": "foo",
            "hp": 1
        }
    ]
}

Supply Path Optimisation

These account labelling changes will reduce the number of sites with DIRECT last seller accounts. This could result in a significant shift in ad supply and demand if buyers continue to prioritise buying direct.

If these buyers legitimately don’t want to buy from any intermediary, then this would simply be buyers actually getting what they thought they were buying all along. But it’s possible many buyers would be OK with certain indirect paths, if they could target them.

Buying direct is effectively using the ads.txt relationship field for a type of Supply Path Optimisation (SPO). But it’s a binary field — paths are direct or indirect. It just isn’t a good tool for the job, regardless of how it’s defined.

The SupplyChain object is clearly a better tool for SPO. With it, a buyer can check that all the accounts are authorized in the site’s ads.txt, not just the last seller. They can check the first seller is DIRECT. They can look them up in sellers.json files to see who the intermediaries are, who the first seller was, and determine whether they trust them.

You get the picture. SupplyChain objects, combined with data from sellers.json and ads.txt files, enable far more sophisticated SPO than the ads.txt relationship field ever could. With this kind of SPO, the importance of the last seller account being DIRECT is significantly reduced. A valid SupplyChain with trustworthy intermediaries could be just as valuable as a DIRECT account, depending on the buyer.

We should be aiming to get buyers using SupplyChain, rather than worrying about whether sites can be bought direct.

Is DIRECT Needed?

At this point, you may be wondering if it’s worth updating the definition of DIRECT at all. If buyers should be checking SupplyChains rather than buying direct, does DIRECT mislabelling matter? Do we need the ads.txt relationship field?

If ads.txt was still being drafted, I think there’d be a good argument for simply not including the relationship field. But ads.txt has been in the wild for 4 years, and the relationship field is being actively used by buyers. That’s not going to change overnight.

Using SupplyChain for SPO is not something new I’m proposing — that’s what it was designed for, and it was released over two years ago. Buyers are going to keep buying direct for some time yet, and I think it’s important to make sure they start getting what they’ve been paying for.

Even once using SupplyChains is standard and the direct/indirect binary is a thing of the past, buyers will need to validate those SupplyChains against information from sellers.json and ads.txt files. With its updated definition, the ads.txt relationship field provides information that isn’t available elsewhere: whether the account is specific to a site. This information is important for assessing the risk of domain spoofing by authorized accounts.

Sellers.json focuses on who gets paid for inventory, not what site it’s from. It could be updated to incorporate this information — something I think we should consider — but that is a much bigger change.

A Way Forward

DIRECT mislabelling has been a long standing issue with ads.txt. Cleaning it up is essential to weeding out fraud, and building a level playing field for legitimate publishers.

Narrowing the definition of DIRECT to enable this clean-up will impact some sites, but only while buying direct remains a prominent strategy. SupplyChain objects, paired with sellers.json and ads.txt, give buyers the data required to move away from this reliance.

Transparent, accurate supply chains are better for both advertisers and publishers. If you’re an advertiser, talk to your agency/DSP about utilizing SupplyChain object data in your campaigns. If you’re a publisher, check your ads.txt for mislabelled accounts and develop a plan for correcting them.

Changes like this won’t happen overnight, but the sooner we start, the better.