Publisher Independence

    ads.txt generator: build a valid ads.txt or app-ads.txt file from your seller list

    Published · Last updated
    Next scheduled review:

    This ads.txt generator turns your list of authorized sellers into a valid ads.txt or app-ads.txt file under the IAB Tech Lab ads.txt 1.1 specification. It fixes field order and case, removes duplicates, writes the five variables correctly and checks each seller against the exchange's sellers.json. Nothing you enter is stored.

    Generate ads.txt or app-ads.txt

    Enter rows individually

    Paste the lines your exchanges sent you, or your current file, and the generator rebuilds it cleanly. When it is live, run the ads.txt and sellers.json validator on your domain to confirm that buyers can read it.

    Contents

    Key facts

    • ads.txt 1.1 is the current version. Its change log dates the final release to July 2022 and lists OWNERDOMAIN and MANAGERDOMAIN as the 1.1 additions (ads.txt 1.1, section 2.1). The specification says there have been no breaking changes since 2017.
    • The specifications moved to GitHub. IAB Tech Lab now publishes ads.txt, app-ads.txt and sellers.json in its Supply Chain Validation repository (IAB Tech Lab, ads.txt page, last updated 14 September 2026).
    • An empty file says nothing. Consumers should ignore empty ads.txt files after 1 March 2020. A publisher with no authorized sellers publishes the placeholder record instead (ads.txt 1.1, section 3.2.1).
    • Changes take up to a week to land. Without cache headers, crawlers keep a copy for 7 days (ads.txt 1.1, section 3.6). App store listings are crawled "no more frequently than weekly" (app-ads.txt specification).
    • app-ads.txt is the same format with one exception. The SUBDOMAIN directive is unused in app-ads.txt and crawlers ignore it (app-ads.txt specification).
    Jump to the table

    How to use the generator

    1. Choose the file. Pick ads.txt for a website or app-ads.txt for an app, and enter the domain that will host it. For an app, enter the developer website URL from your store listing; the generator shows the exact URL where crawlers will look.
    2. Add your sellers. Type one row per account: the exchange's domain, your account ID, DIRECT or RESELLER, and the certification ID if the exchange gave you one. You can also paste lines from an exchange's onboarding email or from your current file.
    3. Set the variables. OWNERDOMAIN is pre-filled with your root domain. Add contacts, managers, subdomains or inventory partners only if they apply.
    4. Read the notes. Each change the generator made, and each problem it found, appears next to the row it concerns. Rows with errors are left out of the file until you fix them.
    5. Download and publish. Download ads.txt or app-ads.txt, upload it to the root of the domain, then check the live file with the validator.

    If you have no authorized sellers, tick "No authorized sellers" and the generator writes the placeholder record. It never writes the placeholder on its own: a file full of typos produces no file at all, not a file that de-authorizes everyone.

    ads.txt format: four fields per line

    An ads.txt file is plain text. Each line is a record of up to four comma-separated fields, a variable in the form NAME=VALUE, or a comment that starts with # (ads.txt 1.1, section 3.2). Here is the specification's simplest example, a site with one direct relationship:

    greenadexchange.com, XF7342, DIRECT, 5jyxf8k54

    4 of 4 rows

    Columns (5)

    1

    Domain of the advertising system

    Yes

    The canonical domain the exchange or SSP publishes for bidders

    Lower case, no scheme, path or port; non-ASCII names in punycode

    2

    Seller account ID

    Yes

    Your account ID in that system, usually the value sent as publisher.id in OpenRTB

    As typed; spaces, tabs, commas and # are URL-encoded

    3

    Relationship

    Yes

    DIRECT if you control the account, RESELLER if another company does

    Upper case; anything else is refused

    4

    Certification authority ID

    No

    The exchange's TAG ID, if it has one

    As typed; omitted when empty

    1

    Name

    Domain of the advertising system

    Required

    Yes

    What goes in it

    The canonical domain the exchange or SSP publishes for bidders

    How the generator writes it

    Lower case, no scheme, path or port; non-ASCII names in punycode

    2

    Name

    Seller account ID

    Required

    Yes

    What goes in it

    Your account ID in that system, usually the value sent as publisher.id in OpenRTB

    How the generator writes it

    As typed; spaces, tabs, commas and # are URL-encoded

    3

    Name

    Relationship

    Required

    Yes

    What goes in it

    DIRECT if you control the account, RESELLER if another company does

    How the generator writes it

    Upper case; anything else is refused

    4

    Name

    Certification authority ID

    Required

    No

    What goes in it

    The exchange's TAG ID, if it has one

    How the generator writes it

    As typed; omitted when empty

    Download JSON

    Table by AdSovereign, CC BY 4.0.

    Sources for the table: ads.txt 1.1, sections 3.3 and 3.4.

    Three rules from sections 3.3 and 3.4 of the specification shape most of the generator's fixes. Field 3 is case-insensitive, so direct is legal, but upper case is what every example uses. No field may contain a comma, tab or space unless it is URL-encoded. And anything after a # on any line is a comment, so a # inside an account ID or a contact URL silently cuts the line short. The specification also notes that field 4 "may be deprecated", because sellers.json now carries certification IDs.

    The five ads.txt variables, and when to use each

    Variables tell crawlers who owns the inventory, who manages it, where else to look and whom to contact. The specification recommends declaring them at the end of the file (ads.txt 1.1, section 3.5), and the generator does so.

    5 of 5 rows

    Columns (6)

    CONTACT

    1.0.1, August 2017

    Email, phone, URL or other contact

    Yes

    Yes

    Any number; a value containing # is refused

    SUBDOMAIN

    1.0.1, August 2017

    A subdomain of the root domain that has its own file

    Root-domain file only

    Ignored by crawlers

    Offered only when the host is a root domain

    INVENTORYPARTNERDOMAIN

    1.0.3, March 2021

    Domain of a partner that owns some of the content

    Yes

    Yes

    Crawlers follow it one hop, to the partner's ads.txt

    OWNERDOMAIN

    1.1, July 2022

    Registrable domain of the business that owns the site or app

    Yes, recommended on every file

    Yes

    Pre-filled; reduced to the registrable domain; first one only

    MANAGERDOMAIN

    1.1, July 2022

    Registrable domain of an exclusive monetization partner, with an optional two-letter country code

    Yes

    Yes

    One global entry and one per country

    CONTACT

    Added in

    1.0.1, August 2017

    Value

    Email, phone, URL or other contact

    ads.txt

    Yes

    app-ads.txt

    Yes

    SUBDOMAIN

    Added in

    1.0.1, August 2017

    Value

    A subdomain of the root domain that has its own file

    ads.txt

    Root-domain file only

    app-ads.txt

    Ignored by crawlers

    INVENTORYPARTNERDOMAIN

    Added in

    1.0.3, March 2021

    Value

    Domain of a partner that owns some of the content

    ads.txt

    Yes

    app-ads.txt

    Yes

    OWNERDOMAIN

    Added in

    1.1, July 2022

    Value

    Registrable domain of the business that owns the site or app

    ads.txt

    Yes, recommended on every file

    app-ads.txt

    Yes

    MANAGERDOMAIN

    Added in

    1.1, July 2022

    Value

    Registrable domain of an exclusive monetization partner, with an optional two-letter country code

    ads.txt

    Yes

    app-ads.txt

    Yes

    Download JSON

    Table by AdSovereign, CC BY 4.0.

    Source for versions and dates: the change log in ads.txt 1.1, section 2.1.

    OWNERDOMAIN deserves a default. The specification asks for it "even if the OWNERDOMAIN is the same as the domain on which the ads.txt file is found". Buyers compare it with the domain in each publisher's sellers.json entry and with the first node of a complete SupplyChain object. How those three records fit together is explained in SupplyChain, ads.txt and sellers.json together.

    MANAGERDOMAIN needs the most care. It names a company that sells your inventory exclusively, globally or in one country. IAB Tech Lab's guidance warns that buyers may treat other sellers of the same inventory as resellers once a manager is declared (ads.txt implementation guidance, section 5). Leave it empty unless one partner really manages most of your sales.

    ads.txt example files for common setups

    Each file below is the generator's exact output for the input shown, built from the examples in section 4 of the specification. Our test suite reproduces them line for line.

    A site with three exchanges, two of them resellers, typed with mixed case and a pasted URL. The generator lower-cases the domains, upper-cases the relationships, strips https:// and the trailing slash, and adds OWNERDOMAIN:

    # ads.txt file for example.com:
    greenadexchange.com, 12345, DIRECT, d75815a79
    silverssp.com, 9675, RESELLER, f496211
    blueadexchange.com, XF436, DIRECT
    orangeexchange.com, 45678, RESELLER
    silverssp.com, ABE679, RESELLER
    OWNERDOMAIN=example.com

    A site owned by a media group, sold by one manager in France and another in the United States (specification example 4.8):

    greenadexchange.com, XF7342, DIRECT, 5jyxf8k54
    OWNERDOMAIN=mediacompany.com
    MANAGERDOMAIN=yellowmediamanager.com, FR
    MANAGERDOMAIN=bluemediamanager.com, US

    A site with no authorized sellers at all (specification example 4.9):

    placeholder.example.com, placeholder, DIRECT, placeholder
    OWNERDOMAIN=example.com

    A streaming app whose content partner sells some of its inventory (specification example 4.6), written as app-ads.txt:

    ssp.com, vwxyz, DIRECT
    INVENTORYPARTNERDOMAIN=programmera.com

    Two details differ from the printed examples on purpose. The generator places variables last, as section 3.5 recommends, while examples 4.7 and 4.8 put them first. And it writes programmerA.com as programmera.com, because domain names are case-insensitive and lower case avoids two spellings of one partner.

    app-ads.txt generator: what changes for apps

    An app-ads.txt file uses the same records and variables. What changes is how crawlers find it. They read the developer website URL from the app's store listing, reduce the host name by fixed rules, and look for /app-ads.txt there (app-ads.txt specification, "Translate developer URL to an app-ads.txt path"). The generator applies the same rules and shows you the result.

    4 of 4 rows

    Columns (3)

    https://www.example.com/test

    https://example.com/app-ads.txt

    (none)

    https://m.example.com/test

    https://example.com/app-ads.txt

    (none)

    https://subdomain.example.com/test

    https://subdomain.example.com/app-ads.txt

    https://example.com/app-ads.txt

    https://another.subdomain.example.co.uk/test

    https://subdomain.example.co.uk/app-ads.txt

    https://example.co.uk/app-ads.txt

    https://www.example.com/test

    Crawler looks first at

    https://example.com/app-ads.txt

    Then, if nothing is found

    (none)

    https://m.example.com/test

    Crawler looks first at

    https://example.com/app-ads.txt

    Then, if nothing is found

    (none)

    https://subdomain.example.com/test

    Crawler looks first at

    https://subdomain.example.com/app-ads.txt

    Then, if nothing is found

    https://example.com/app-ads.txt

    https://another.subdomain.example.co.uk/test

    Crawler looks first at

    https://subdomain.example.co.uk/app-ads.txt

    Then, if nothing is found

    https://example.co.uk/app-ads.txt

    Download JSON

    Table by AdSovereign, CC BY 4.0.

    Two app-specific rules matter. SUBDOMAIN does nothing in app-ads.txt, so the generator leaves it out and tells you why. INVENTORYPARTNERDOMAIN does work in app-ads.txt, and the specification's own example uses it there, but crawlers follow it to the partner's ads.txt, never to its app-ads.txt, and only one hop. Bid requests must also carry the partner's domain in app.inventorypartnerdomain for the check to apply; you can see where that field sits in the OpenRTB bid request builder.

    When you change the developer URL, keep the old file online for a while. The app-ads.txt specification suggests 30 days where possible, so that buyers never find a gap between the old and new locations.

    How the generator cleans your list

    The generator reads each row the way a careful crawler would, then writes it back in one consistent style. The rules come from sections 3.3 to 3.5 of the specification, plus a few safety choices of our own.

    10 of 10 rows

    Columns (3)

    https://www.redssp.com/ in field 1

    Reduces it to www.redssp.com and asks you to check the exchange's documented domain

    Note, then warning

    direct or Reseller

    Writes DIRECT or RESELLER

    Note

    RESELER

    Leaves the row out and suggests RESELLER

    Error

    pub 57013 in field 2

    Writes pub%2057013

    Warning

    The same row twice, one with a TAG ID

    Keeps one row with the TAG ID

    Note

    The same account as DIRECT and RESELLER

    Keeps both and flags the contradiction

    Warning

    Account IDs that differ only by case

    Keeps both and asks which one the exchange issued

    Warning

    OWNERDOMAIN=https://www.MediaCompany.com/about

    Writes OWNERDOMAIN=mediacompany.com

    Note

    A second MANAGERDOMAIN for the same country

    Keeps the first, leaves out the second

    Error

    CONTACT=https://example.com/#adops

    Leaves it out, because crawlers would cut it at #

    Error

    https://www.redssp.com/ in field 1

    What the generator does

    Reduces it to www.redssp.com and asks you to check the exchange's documented domain

    Severity

    Note, then warning

    direct or Reseller

    What the generator does

    Writes DIRECT or RESELLER

    Severity

    Note

    RESELER

    What the generator does

    Leaves the row out and suggests RESELLER

    Severity

    Error

    pub 57013 in field 2

    What the generator does

    Writes pub%2057013

    Severity

    Warning

    The same row twice, one with a TAG ID

    What the generator does

    Keeps one row with the TAG ID

    Severity

    Note

    The same account as DIRECT and RESELLER

    What the generator does

    Keeps both and flags the contradiction

    Severity

    Warning

    Account IDs that differ only by case

    What the generator does

    Keeps both and asks which one the exchange issued

    Severity

    Warning

    OWNERDOMAIN=https://www.MediaCompany.com/about

    What the generator does

    Writes OWNERDOMAIN=mediacompany.com

    Severity

    Note

    A second MANAGERDOMAIN for the same country

    What the generator does

    Keeps the first, leaves out the second

    Severity

    Error

    CONTACT=https://example.com/#adops

    What the generator does

    Leaves it out, because crawlers would cut it at #

    Severity

    Error

    Download JSON

    Table by AdSovereign, CC BY 4.0.

    The generator keeps rows in the order you entered them, so related accounts stay together. Lines end with a line feed, the file ends with one, and it is saved as UTF-8 without a byte-order mark.

    Checking each seller against sellers.json

    Every exchange named in field 1 should publish a sellers.json file at the root of its domain (sellers.json 1.0, "Implementation"). When the cross-check is on, the generator looks up each of your account IDs there and gives each row a status. The file is generated either way.

    6 of 6 rows

    Columns (3)

    Verified

    The ID is listed and its seller type agrees with your relationship

    Nothing

    Not listed

    The exchange's sellers.json does not contain the ID

    Confirm the ID with the exchange; the validator will report it as an error once the file is live

    Type mismatch

    DIRECT on an account the exchange lists as INTERMEDIARY, or RESELLER on one listed as PUBLISHER

    Ask which relationship is true

    Domain differs

    A DIRECT, PUBLISHER account whose sellers.json domain is not your OWNERDOMAIN

    Ask the exchange to correct the domain, or fix OWNERDOMAIN

    Confidential

    Listed with is_confidential set to 1

    Nothing to compare

    Not checked

    The file was unreachable, not JSON, or had no sellers array

    Retry later

    Verified

    What it means

    The ID is listed and its seller type agrees with your relationship

    What to do

    Nothing

    Not listed

    What it means

    The exchange's sellers.json does not contain the ID

    What to do

    Confirm the ID with the exchange; the validator will report it as an error once the file is live

    Type mismatch

    What it means

    DIRECT on an account the exchange lists as INTERMEDIARY, or RESELLER on one listed as PUBLISHER

    What to do

    Ask which relationship is true

    Domain differs

    What it means

    A DIRECT, PUBLISHER account whose sellers.json domain is not your OWNERDOMAIN

    What to do

    Ask the exchange to correct the domain, or fix OWNERDOMAIN

    Confidential

    What it means

    Listed with is_confidential set to 1

    What to do

    Nothing to compare

    Not checked

    What it means

    The file was unreachable, not JSON, or had no sellers array

    What to do

    Retry later

    Download JSON

    Table by AdSovereign, CC BY 4.0.

    Sources: sellers.json 1.0 and the ads.txt implementation guidance, which asks that DIRECT accounts marked PUBLISHER carry a sellers.json domain matching OWNERDOMAIN.

    A "Not checked" status does not always mean the exchange is offline. Even the sample file in the sellers.json specification fails to parse as printed: on line 16, the value "PUBLISHER” closes with a typographic quote instead of a straight one. A strict JSON parser stops there. Which companies end up in field 1, and why some of them resell rather than sell direct, follows from the roles described in ad exchange vs ad network vs SSP.

    Publishing the file so buyers can read it

    A perfect file still fails if it is served wrongly. These rules come from section 3.1 of the ads.txt specification.

    1. Put it at the root. Publish https://example.com/ads.txt on the root domain, plus a file on each subdomain you declared with SUBDOMAIN.
    2. Serve plain text. The response must carry Content-Type: text/plain; adding charset=utf-8 is advisable. Crawlers treat any other content type as an error and ignore the content.
    3. Keep redirects short. Redirects inside your root domain are fine. One redirect to another domain is allowed; a second one is an error.
    4. Prefer HTTPS. Crawlers prefer HTTPS when both versions exist.
    5. Set cache headers if you update often. Without them, buyers may keep the old file for 7 days.

    Header bidding setups need care here, because every exchange that bids through your wrapper needs its own line. Header bidding explained covers how those partners reach your page. The wider question of who controls your supply path is collected in the publisher independence hub.

    Methodology and limits

    The generator follows ads.txt 1.1, the app-ads.txt specification and sellers.json 1.0 as published on GitHub on 9 November 2026. Registrable domains come from the Public Suffix List, refreshed weekly. The app-ads.txt path rules reproduce every test case in the specification's appendices.

    It cannot tell you which exchanges you should authorize, whether an account ID is really yours, or whether a reseller is reputable. It checks form, consistency and what the exchanges publish about themselves. Browsers cannot read another site's sellers.json directly, so the cross-check asks our validator service to fetch those files. That request carries the exchange domains and account IDs, which become public anyway once your file is live, and nothing is stored.

    FAQ

    What is the ads.txt format?
    Each line is either a record of up to four comma-separated fields (exchange domain, account ID, DIRECT or RESELLER, optional certification ID), a variable such as OWNERDOMAIN=example.com, or a comment after #. The file is plain text, served as text/plain at /ads.txt on the root domain (ads.txt 1.1).
    Where do I put the ads.txt file?
    At the root of the domain that serves your pages, for example https://example.com/ads.txt. Subdomains with different sellers get their own file only if the root file points to them with SUBDOMAIN. For apps, the file goes on the domain derived from the developer URL in your store listing.
    Do apps need app-ads.txt as well as ads.txt?
    Apps distributed through app stores use app-ads.txt; websites use ads.txt. A company with both publishes both, and the two files can list different sellers. The only cross-over is INVENTORYPARTNERDOMAIN, which points from either file to a partner's ads.txt.
    Should a line say DIRECT or RESELLER?
    DIRECT means you control the account in field 2 yourself, usually under your own contract with the exchange (ads.txt 1.1, section 3.3). RESELLER means another company controls that account and resells your inventory through it. If an exchange's sellers.json lists the account as INTERMEDIARY, a DIRECT line is probably wrong.
    What does the placeholder line mean?
    placeholder.example.com, placeholder, DIRECT, placeholder tells buyers, on purpose, that no one is authorized to sell your inventory. It replaced the empty file, which consumers should ignore after 1 March 2020 (ads.txt 1.1, section 3.2.1).
    How long until buyers see my changes?
    Up to 7 days if your server sends no cache headers, because that is the default expiry in section 3.6 of the specification. For apps, add up to a week for crawlers to re-read the store listing if you changed the developer URL.

    How this works on owned infrastructure

    Every line this generator writes points at someone else's system: the exchange's domain in field 1, the account ID it issued in field 2, and the sellers.json it publishes about you. When a publisher or retailer runs its own exchange, it becomes the advertising system in field 1. AdSovereign is an enterprise RTB stack, including an SSP and exchange, designed to run on infrastructure you control, so the seller table behind your sellers.json, the canonical domain buyers see and the lines your partners publish come from one source you manage. The integrations page lists the supply-side connectors, and the architecture page shows where seller records live.

    Sources

    1. IAB Tech Lab, "Ads.txt Version 1.1" (final release July 2022; repository file updated 26 March 2026; accessed 9 November 2026). https://github.com/InteractiveAdvertisingBureau/Supply-Chain-Validation/blob/main/ads.txt%20v1.1.md
    2. IAB Tech Lab, "Authorized Sellers for Apps (app-ads.txt)" (accessed 9 November 2026). https://github.com/InteractiveAdvertisingBureau/Supply-Chain-Validation/blob/main/app-ads.txt.md
    3. IAB Tech Lab, "Sellers.json" version 1.0 (July 2019; accessed 9 November 2026). https://github.com/InteractiveAdvertisingBureau/Supply-Chain-Validation/blob/main/sellers-json.md
    4. IAB Tech Lab, "Ads.txt Implementation Guidance" (accessed 9 November 2026). https://github.com/InteractiveAdvertisingBureau/Supply-Chain-Validation/blob/main/Implementation%20Guidance.md
    5. IAB Tech Lab, "Authorized Digital Sellers with ads.txt and app-ads.txt" (last updated 14 September 2026; accessed 9 November 2026). https://iabtechlab.com/ads-txt/
    6. Public Suffix List, maintained by the Mozilla Foundation and contributors (accessed 9 November 2026). https://publicsuffix.org/list/
    Changelog
    • 9 November 2026. First edition: generator for ads.txt and app-ads.txt under ads.txt 1.1, five variables, sellers.json cross-check, 18 test cases. Next review 9 February 2027.