IAB Content Taxonomy 3.1: classification and the 2.x cross-map, planned as a metered API
Search for an IAB 3.1 taxonomy API and the first answer back is a denial. The IAB Tech Lab does not provide a direct, official REST API for Content Taxonomy 3.1. That sentence is Google's own AI overview, read 2026-09-24, and it is correct. The taxonomy ships as data files in the official repository. The Tech Lab maintains a free open-source mapper for the 2.x to 3.x migration. The commercial wrappers that fill the gap lean on URL scraping and enterprise sales calls. No self-serve service classifies your submitted text into 3.1 codes with public terms. The research reads behind this page (August and September 2026) found none.
This page is the missing hosted answer, written ahead of its lane. It describes iab-3x, this platform's planned classification lane: submitted text in, 3.1 codes out. It also carries a cross-map endpoint that takes 2.x codes to their 3.1 equivalents with confidence scores. The output shape is the official mapper's own. The lane is pre-launch. Nothing answers under the alias today. Its row sits in the platform's model data behind the public list, and no date is promised. What is published here is the capability record and the working contract, so an integration can be written and reviewed before the lane lands.
What follows: what the taxonomy is, and where every number comes from. Then who the migration is for, the exact call shape as designed, and the benchmark record with its honesty caveats. The paths that work today close the page.
Last verified: 2026-09-25
What it is
The IAB Content Taxonomy is the standard category tree of contextual advertising. It is the label set publishers, adtech tools, and buyers use to say what a page is about. The Tech Lab's taxonomy page is the canonical home. The working files are TSV (tab-separated tables) and JSON in the repository, including the 3.1 file itself. The identity facts, each with its owner:
| Fact | Value | Where the number comes from |
|---|---|---|
| Owner | IAB Tech Lab | official standards page |
| Current point release | 3.1, December 2024 | Tech Lab release materials, read 2026-08-24 |
| 2.x status | deprecated; migration to 3.x framed as not optional | Tech Lab, read 2026-08-24 |
| Categories | the Tech Lab's framing: roughly 400 in 2.x growing to more than 1,500 in 3.x. The files count differently: the 2.2 file carries 1,196 named entries including its descriptor groups, and the 3.1 tiered file carries 704 | Tech Lab standards page (the framing, read 2026-09-24); the official TSVs counted from the repository, 2026-09-24 |
| Depth | four tiers in 3.x | the migration scale story, same reads |
| Official classification API | none | the search overview's denial, read 2026-09-24; the repository ships data only |
| Official migration tool | the open-source iab-mapper | the repository |
The count story needs both bases, because the two do not match. The Tech Lab's own materials frame the move as roughly 400 categories in 2.x growing to more than 1,500 in 3.x. That framing runs through the migration write-ups this page's research read. The repository files count differently. The 2.2 file carries 1,196 named entries once its six descriptor groups are included. The 3.1 tiered file carries 704, with the descriptor groups gone and the top-level set rebuilt. What forced the migration was the restructuring, not size alone. Version 3.0 was not a compatible update. Codes moved and some were deleted, and 3.1, the current point release from December 2024, refreshed genre coverage. Hand-mapping a corpus across that gap is why the Tech Lab shipped a mapper at all. Its own framing, via the reads behind this page, is that manual migration was taking organizations months. The search overview's scale story (read 2026-09-24) puts the hand version at weeks. Both ends of that range are real; neither is a plan.
What the market actually sells splits in two. Most surviving self-serve services classify domains and URLs, not text you submit. They answer from databases they crawled themselves. You hand them an address, and they answer from what they last saw there. Submitted-text classification is rare. The two wrappers the search overview names for 3.1 work from URL and page scraping with an enterprise sales shape. The gap is specific and verified. No self-serve submitted-text API serving IAB 3.1 with a 2.x cross-map existed as of the 2026-08-24/25 vendor sweep behind this page, and the September SERP reads changed nothing.
That gap is what iab-3x is designed to close: one lane, two operations. Text goes to 3.1 codes, and 2.x codes go to 3.1 equivalents. The output sits in the mapper's columns, so migrating teams recognize the contract. On this platform the lane's row sits in the model data behind the public list, so no route answers its model id yet, and the rate is already set. The models index carries the catalog's real state, always. This page is the contract, published first.
Use cases
The lane's profile is the migration cohort first, fresh classification second:
- Corpus re-labeling backfills. The forced move is real: 2.x is deprecated, and the first buyers of a cross-map are publisher tools and adtech shops re-classifying thousands to millions of stored pages from 2.x into 3.x. A backfill is one loop over the cross-map endpoint; a fresh corpus is one loop over classification.
- Page-level classification at volume. Adops and contextual-targeting pipelines that need an IAB label per article, at page level, from the text itself rather than from a domain average.
- OpenRTB hygiene. OpenRTB is the standard that carries a page's labels inside the bid request: your category IDs ride in
content.category, and thecattaxfield declares which taxonomy version they are. Whencattaxis absent the signal defaults to taxonomy 1.0, and Google Authorized Buyers warns that stale versions increase bid filtering. A 3.1 pipeline fixes the version drift that quietly costs impressions. - Monitoring, compliance, and agent pipelines. Any system that needs stable, versioned topic labels on flowing text: trend dashboards, brand-suitability screens, content agents that route by category.
Weeks by hand, minutes with the mapper, one call hosted
The honest progression, with the honesty kept in: the official iab-mapper is free, open source, and runs locally. It works as a CLI or UI. It matches labels deterministically first, then fuzzily. Optionally it uses embeddings, and it re-ranks candidates with a language model. It emits confidence scores and OpenRTB- and VAST-ready category IDs. It was donated to the Tech Lab by Mixpeek, and it turned a months-long manual migration into a minutes-long local job.
A hosted lane does not beat the mapper on price; the mapper is free. What it sells is the parts the mapper does not ship. There is no local runtime and no CLI babysitting. You get metered volume from a prepaid wallet, and both directions of the migration in one lane with one output shape. If you have an engineer and a quiet machine, run the mapper. The lane's contract was designed so your mapper-era pipeline recognizes its answers on sight. If you would rather point a corpus at an endpoint and get billed per page, that is the product.
Text in, or a domain database
Submitted text and domain lookup answer different questions. A domain database says what a site was last about, on average, when someone else crawled it. Submitted text says what this page, today, says. The first is a lookup commodity, served from pre-crawled domain databases in the hundred-million range. The second, page-level truth from the text itself, is the rare shape. It is the only one that follows a page through edits, rebrands, and article-level targeting. iab-3x is built on the second. The input is your text, up to full-article length on the base architecture's 8,192-token window. The answer is page-level. The public fine-tune caps inputs at 1,024 tokens, and this lane's own cap publishes with the row.
Send 2.x, 3.1, or both
The version chooser resolves to a rule: label in 3.1, keep 2.x available. Buyers and partners still live on both sides of the transition, and cattax makes the version explicit on the wire. The cross-map returns the legacy codes' 3.1 equivalents rather than forcing a cutoff. This platform's 2.x lane page covers the legacy version's own contract. The two lanes share the model pack, and a pipeline that must serve both versions calls one and cross-maps.
API usage
The lane rides a new lightweight classification route, built alongside the other planned classifier lanes. Its shape follows the platform's embeddings face. JSON goes in, and one JSON answer comes out. A Bearer key works at the door, the prepaid wallet is the spend boundary, and nothing is billed for a request refused before work starts. The two operations as designed:
| Operation | Request | Answer |
|---|---|---|
| Classify | model plus input, one text or an array | 3.1 results per text: codes, labels, confidence |
| Cross-map | model plus codes, your 2.x category codes | 3.1 equivalents per code, with confidence |
One hedge, stated plainly: the route paths below are the designed surface for this lane. The paths publish with the row. The contract that matters for planning now is the request and answer shape. It mirrors the official mapper's output columns on purpose: codes, labels, confidence. That is why mapper-era tooling recognizes it. Metering follows the plan's page unit. A page is up to 2,000 tokens of submitted text, rounded up, so a corpus prices as page count. Classification input arrays bill per text, not per request.
curl
curl -X POST "https://api.ironstratum.com/v1/classifications" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "iab-3x",
"input": [
"The midfielder returned from injury with two goals as the home side closed the season with a win."
]
}'
python
The cross-map operation, for the migration cohort. The codes are yours, as exported from the 2.x corpus:
import os
import requests
codes = ["...", "..."] # your 2.x category codes, from the corpus export
resp = requests.post(
"https://api.ironstratum.com/v1/classifications/crossmap",
headers={"Authorization": "Bearer " + os.environ["KEY"]},
json={"model": "iab-3x", "codes": codes},
timeout=120, # a batch answers in one JSON body; give it room
)
resp.raise_for_status()
for mapping in resp.json()["results"]:
print(mapping)
openai-sdk
The classification route has no native resource in the OpenAI SDK, and this tab will not fake one. The SDK's generic JSON post drives it directly. That keeps an existing SDK installation in place with a base-URL change:
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.ironstratum.com/v1",
api_key=os.environ["KEY"],
)
answer = client.post(
"/classifications",
cast_to=dict,
body={
"model": "iab-3x",
"input": [
"The midfielder returned from injury with two goals as the home side closed the season with a win."
],
},
)
print(answer["results"])
print("usage:", answer["usage"])
Each result row carries the 3.1 code, its label, and a confidence score. The cross-map answers in the same columns keyed to your submitted codes. Both operations answer in one JSON body, not a stream. Set client timeouts with the whole batch in mind, and chunk large backfills into requests sized for your own retry logic.
Benchmarks
Three layers, each labeled for what it is.
This platform has run no measurements on this lane. Nothing serves it, so there is nothing to measure against; inventing numbers would help nobody. The plan pins the eval that publishes with the row: a held-out set spot-checked against the official mapper's own output, with the method stated. A cross-map's quality claim is only meaningful against the tool migrating teams already trust.
The open-model record. The public starting point for 3.1 classification is an open fine-tune, mdonigian/modernbert-iab-classifier on Hugging Face. It is a 149M-parameter ModernBERT encoder fine-tuned to 35 of IAB 3.1's Tier 1 categories, published as Apache-2.0. Its own evaluation reports top-1 accuracy of 75.5, top-5 of 95.8, and macro-F1 of 0.71. It was trained on a 106K-article set distilled with a large language model. The card also scopes the fine-tune to English news articles (the model card, read 2026-08-24). Its base architecture reads 8,192-token contexts, but the fine-tune itself truncates inputs at 1,024 tokens, its card's own limit. The full-article window is the base architecture's capability. The public fine-tune does not carry it. Two scope limits matter: those scores cover Tier 1 only, and no public model exists for the deeper tiers. That is the open quality position this lane's build targets.
The honesty frame. Every quality number in this market, including that model card's, rests on labels from language models. No human ground truth sits under them. That is how the whole category is evaluated today. Hosted competitors work the same way. Treat any single accuracy number as a relative signal between systems, not an absolute guarantee. Test on your own corpus before you commit a backfill. That test is cheap. A backfill is not. That advice is also this platform's own rule for itself: the lane's numbers publish with the row, from the eval named above, or they do not publish.
Getting started
Two tracks, honestly separated.
Today, before the lane lands: read the taxonomy files and the Tech Lab's taxonomy page. Run the official iab-mapper on a sample of your corpus. Then write your integration against the contract above. The route paths can change when the row lands. The request and answer shapes are the design, and the mapper's output columns are the anchor.
When the row lands: join through the console's invite flow (the platform runs as an invite-only beta in this phase), create an API key, fund the prepaid wallet, and send the curl tab. The rate publishes with the listing in the catalog surfaces; this page's search listing already carries the starting rate, recorded 25 September 2026. Spend stops at the wallet, with refused requests billing nothing.
To place this lane among its siblings: the classification category covers the family it belongs to. The models index carries the catalog's current state. The API reference documents the platform's shipped routes. The 2.x lane is the legacy-version sibling, and gliner-extract is the entity-extraction lane in the same family.