Blocking ad categories in OpenRTB with bcat, acat, and cattax

bcat lists advertiser categories the seller refuses, acat lists the only categories it accepts, and cattax names the IAB taxonomy both lists are written in. The buyer declares its creative's categories in Bid.cat under Bid.cattax. When a cattax is missing, the field it governs is read as Content Category Taxonomy 1.0.

The three request fields

FieldTypeSinceWhat it does
bcatstring array2.0Block list. A bid in a listed category is not eligible.
acatstring array2.6-202309Allow list. Only bids in a listed category are eligible.
cattaxinteger, default 12.6The taxonomy used to read bcat or acat.

Send one list or the other. The specification says only one of acat and bcat should be present, and RTBlint reports a request carrying both with openrtb.fields.mutually_exclusive. An allow list is the stricter tool: a creative in a category nobody thought to list is out. A block list is the common choice, because a publisher usually knows what it refuses and accepts the rest.

Both lists are string arrays, including for taxonomies whose IDs look like numbers. Ad Product Taxonomy 2.0 code 1002 (Alcohol) travels as "1002". A bare integer in the array is a type error, which RTBlint reports as openrtb.type.mismatch.

cattax picks the code list

The values of cattax come from AdCOM List: Category Taxonomies. The integer does not describe a category. It says which code list the strings in the neighbouring array belong to.

cattaxTaxonomyClassifies
1IAB Tech Lab Content Category Taxonomy 1.0Content. The default when cattax is absent; AdCOM marks it deprecated.
2IAB Tech Lab Content Category Taxonomy 2.0Content. AdCOM marks it deprecated.
3IAB Tech Lab Ad Product Taxonomy 1.0What an ad promotes.
4IAB Tech Lab Audience Taxonomy 1.1Audience segments.
5IAB Tech Lab Content Taxonomy 2.1Content.
6IAB Tech Lab Content Taxonomy 2.2Content.
7IAB Tech Lab Content Taxonomy 3.0Content.
8IAB Tech Lab Ad Product Taxonomy 2.0What an ad promotes.
9IAB Tech Lab Content Taxonomy 3.1Content.
500+Vendor-specificWhatever the two parties agreed in advance.

AdCOM advises against values 1 and 2 because those taxonomies lack SCD flags. That matters here, because 1 is also the default. A request that sends Ad Product Taxonomy 2.0 IDs in bcat and leaves cattax out asks the buyer to read "1361" as a Content Category Taxonomy 1.0 code. That list uses codes such as IAB25-3, so nothing matches and the block list blocks nothing.

The spec does not require a particular taxonomy for bcat. It calls the entries advertiser categories, and the Ad Product taxonomies (3 and 8) are the ones built to classify what an ad sells. The content taxonomies classify pages, apps, and media, which is what the inventory fields below describe.

A request with a typed block list

{
  "id": "6f1c2a90-3d4e-4b7a-9e21-5c8d0b7f4a13",
  "at": 1,
  "tmax": 250,
  "cur": ["USD"],
  "cattax": 8,
  "bcat": ["1002", "1361", "1544"],
  "imp": [
    {
      "id": "1",
      "banner": { "format": [{ "w": 300, "h": 250 }] },
      "bidfloor": 0.8,
      "bidfloorcur": "USD"
    }
  ],
  "site": {
    "id": "site-4410",
    "domain": "trailguide.example",
    "page": "https://trailguide.example/hikes/alpine-loop",
    "cattax": 9,
    "cat": ["653"],
    "content": { "cattax": 9, "cat": ["655"] },
    "publisher": { "id": "pub-208" }
  }
}

This request blocks Alcohol (1002), Gambling (1361), and Tobacco (1544) in Ad Product Taxonomy 2.0. The site is labelled Travel (653) and the article Travel Locations (655) in Content Taxonomy 3.1. The two taxonomies coexist without conflict because each array has its own cattax.

Category fields that describe inventory

OpenRTB 2.6 gives every object that carries categories its own cattax, each defaulting to 1. Only the request-level pair filters ads. The others tell the buyer what it is bidding on.

CategoriesTaxonomy fieldDescribes
bcat, acatBidRequest.cattaxAds the seller blocks or allows
Site.cat, Site.sectioncat, Site.pagecatSite.cattaxThe website, the section, the page
App.cat, App.sectioncat, App.pagecatApp.cattaxThe app, the section, the view
Publisher.catPublisher.cattaxThe publisher
Content.catContent.cattaxThe content item, such as an article or episode
Producer.catProducer.cattaxThe producer of the content
Bid.catBid.cattaxThe creative in the bid

A buyer can use site.cat or content.cat to avoid a page it does not want, but that is the buyer's own rule. The seller's rule about ads lives only in bcat or acat.

How a bid is checked

{
  "id": "6f1c2a90-3d4e-4b7a-9e21-5c8d0b7f4a13",
  "cur": "USD",
  "seatbid": [
    {
      "seat": "agency-412",
      "bid": [
        {
          "id": "b-1",
          "impid": "1",
          "price": 1.35,
          "adm": "<div class=\"ad\">...</div>",
          "adomain": ["spinvale-casino.com"],
          "crid": "cr-8812",
          "cattax": 8,
          "cat": ["1361"],
          "w": 300,
          "h": 250,
          "mtype": 1
        }
      ]
    }
  ]
}

The exchange reads Bid.cat in the taxonomy named by Bid.cattax and compares it with the request's list. Here the creative declares Gambling (1361) in Ad Product Taxonomy 2.0, the request blocked 1361 in the same taxonomy, and the bid is not eligible. The loss reason for this outcome is 209, Creative Filtered - Category Exclusions.

The specification leaves several cases to exchange policy:

  • Different taxonomies on each side. OpenRTB defines no mapping between taxonomies. A bid labelled in Content Taxonomy 3.1 against a block list in Ad Product Taxonomy 2.0 leaves the exchange to translate or to treat the category as unknown.
  • A bid with no cat. Whether an exchange drops it is policy. Prebid Server's ORTB2 Blocking module, for example, has a block-unknown-adv-cat setting that only acts when enforce-blocks is on.
  • Parent and child codes. Lottery (1365) sits under Gambling (1361) in Ad Product Taxonomy 2.0. The spec does not say whether blocking a parent blocks its children. If you need the children blocked everywhere, list them.

Before OpenRTB 2.6

Up to 2.5, bcat and Bid.cat used the IAB content category list printed in the specification itself, with codes such as IAB25-3 (Pornography) and IAB26 (Illegal Content). There was no cattax. OpenRTB 2.6 moved enumerated lists to AdCOM and added cattax to BidRequest, Site, App, Publisher, Content, Producer, and Bid. acat arrived later, in 2.6-202309. The 2.5 to 2.6 guide covers the rest of that delta.

Mixed-version paths can strip the label. Prebid Server's auction documentation says it removes the cattax fields when it forwards a request to a bidder that supports only 2.5. A list written in Ad Product Taxonomy 2.0 then reaches that bidder without the integer that explains it. The same server's ORTB2 Blocking module, which can add an account-level bcat, documents its values only as IAB categories and has no taxonomy setting.

Mistakes that let blocked ads through

  • Newer taxonomy IDs without cattax. The list is read as Content Category Taxonomy 1.0 and matches nothing.
  • Both acat and bcat. The bidder cannot tell which rule wins.
  • Integers in the array. The type is string array.
  • A vendor taxonomy (500+) with no agreement. The codes mean nothing to a buyer who was not told what they are.
  • Expecting site.cat to filter ads. It describes the page, not the ad.
  • Bids without cat on an exchange that enforces categories. Declare cat and cattax on every bid so the check can pass.

The tester validates cattax against the AdCOM list and flags a request that sends both lists. Load the invalid enum sample, then paste your own request in its place.

Sources

Questions people ask

Which taxonomy does bcat use when cattax is missing?

Content Category Taxonomy 1.0. BidRequest.cattax defaults to 1, so a bcat list sent without cattax is read as 1.0 codes such as IAB25-3. AdCOM marks that taxonomy deprecated, so send cattax explicitly, for example 8 for Ad Product Taxonomy 2.0.

Can a bid request carry both acat and bcat?

It should not. OpenRTB 2.6 says only one of the two should be present. acat is an allow list and bcat is a block list, and sending both gives the bidder two rules for the same question. RTBlint reports the pair as openrtb.fields.mutually_exclusive.

Does site.cat block any ads?

No. Site.cat, App.cat, and Content.cat describe the inventory so a buyer can target or avoid it. Only bcat and acat on the request restrict which ad categories may bid, and the exchange compares them with Bid.cat in the response.