IAB content taxonomy migration 2.x to 3.1, without the weeks
Migrating a corpus from IAB Content Taxonomy 2.x to 3.1 is a real project, not a relabel. Version 3.0 deleted parent categories and restructured the file. This guide walks the whole jump. It covers what changed between the official files. It shows where specific codes moved. It gives the honest timeline ladder: weeks by hand, minutes with the free local mapper, or one call at scale. And it lists the planning steps no tool runs for you.
Everything below stands on the primary record. The record is the IAB Tech Lab's taxonomy page, the official taxonomy files, the mapper repository the Tech Lab hosts, and the Tech Lab's 3.0 implementation guide. Where a number is a quoted line rather than a count from a file, the text says so. One posture note up front: this platform's classification lanes are planned but pre-launch. No row exists for them in the platform's model data. Nothing answers a call under their names, no rate exists, and no date is promised here. The migration guidance stands on its own and works today without any of it.
Why the jump is real work
The Content Taxonomy is the advertising industry's shared category set. Publishers label content with its codes. Exchanges carry them in bid requests, and buyers target or avoid them. Version 3.0, released June 2022, is where the pain originates, because it was not a compatible update. The Tech Lab's version table says 3.0 "includes some deletions which make this version of the taxonomy non-backwards compatible with previous releases". A 2.x corpus cannot simply be re-tagged. Some categories no longer exist. Some moved. And the file is organized differently.
| Version | Released | State |
|---|---|---|
| 1.0 | deprecated | should not be used without sensitive-content flags |
| 2.0 | November 2017 | legacy |
| 2.1 | October 2020 | legacy |
| 2.2 | December 2020 | legacy, still demanded by many running stacks |
| 3.0 | June 2022 | breaking update: deletions of parent categories |
| 3.1 | December 2024 | current release |
The scale of the jump, in the Tech Lab's own quoted line, is roughly 400 content categories in the 2.x line against more than 1,500 in 3.x, across four tiers. That number is release framing, not a row count. Counted from the official file itself, Content Taxonomy 2.2 carries 1,196 named entries across 37 top-level groups. Six of those groups are descriptors rather than topics. They are content language (185 entries), source geography (262), media format, source, channel, and type. Both numbers are true and measure different things. That is the first thing a migration plan must get straight. Counted from the file, 715 of the 1,196 entries are topic categories that say what content is about. The other 481 are descriptors that say what it is in, where it is from, and what language it speaks. Roughly 400 is the Tech Lab's framing, not a row count from either file. The 3.1 file the migration lands on counts differently again: 704 entries, with the descriptor groups gone and the top-level set rebuilt. That is why the jump is a restructure rather than growth.
The urgency is the Tech Lab's, not this page's. Its page says the migration from 2.x "is not optional" for SSPs, DSPs, publishers, and brand-safety vendors. It also says 2.x is being deprecated. Meanwhile 2.x codes still flow through real traffic, and mixed deployments coexist. Version confusion is common enough that articles asking which taxonomy version you are actually using rank on the classifier queries. That mixed state is why a migration is a project with a window in it, not a switch.
Where the codes actually moved
The Tech Lab's Content Taxonomy 3.0 Implementation Guide, from September 2021, explains the structure. Its framing is the key to the migration. The taxonomy has two parts. One is a set of categories that describe the topic, the "aboutness". The other is a set of orthogonal attributes called vectors, such as language, format, source, and media type. Version 3.0 "does not introduce new concepts", the guide says. But it broke compatibility "due to removal of parent categories" while reorganizing to better support video, news, podcasts, games, and app categories.
Concrete examples, because they are what a hand-mapper hits:
- News and Politics, a top-level aboutness category in 2.x, was removed. News became part of the Content Purpose vector, which gained an Informational category with child nodes News and Opinion & Op-Ed, and the guide recommends combining any aboutness category with those vectors. A 2.x news label does not map to a single 3.x news category, because there is no single one.
- Television and Movies were re-scoped to mark content about television and movies, not content that is a TV show or movie. A new Content Form Factor vector (Video, Show, Event, Clip, Movie) took over the shape-of-content job, and an Entertainment Genres group was added.
- The genre line kept moving after 3.0: version 3.1, the current release, refreshes genre coverage, adding Thriller, and was open for public comment until January 24, 2025.
- The safety block carries over as a structure: 2.2's Sensitive Topics group holds exactly 11 categories, and its Brand Suitability and Risk group holds exactly four levels, Floor, High Risk, Medium Risk, and Low Risk. The 3.0 guide keeps risk as a vector dimension that associates dynamically with topics, which means a naive code-to-code conversion can silently drop your risk annotations.
The last bullet is the trap. If your 2.x corpus carries sensitive-topic and risk labels, those are columns you keep and re-join, not values you convert. Nothing in the rewrite does that join for you.
Why hand-mapping breaks, in the prior migration's own numbers. When the Tech Lab released the official 1.0-to-2.0 mapping, reporting counted 14 categories out of roughly 400 in version 1.0 with no direct counterpart in 2.0. Nine of those matched in 2.2, and five could be retained. Most rows mapped one-to-one. A small number mapped many-to-one. Deletions, splits, and orphans are the normal shape of a taxonomy jump. That is why a hand migration is a per-code review exercise rather than a spreadsheet drag.
Three ways to run the migration
The honest framing is a ladder. It runs from weeks by hand, to minutes with the free local mapper, to one call at scale if and when a hosted lane exists. Each rung is real. None makes the others dishonest.
Weeks by hand
The manual route is a mapping spreadsheet. Export your distinct 2.x codes. Sit with both taxonomy files open and decide each code's 3.x home. Handle the splits and orphans one by one, then re-tag the corpus through your table. The Tech Lab's own page says the mapper saves "weeks of manual work". Press coverage of the donation put the manual process at weeks to months for organizations holding large labeled corpora. The cost is not the join, it is the review. Every deleted parent, every many-to-one case, and every risk-bearing label needs a human decision. A corpus with tens of thousands of pages has a long tail of both.
Minutes with the mapper, on your machine
The tool that changed this task is the open-source taxonomy mapper in the IAB Tech Lab's GitHub organization. Its identity, stated precisely because the market is loose with it: it was built and donated by Mixpeek. It is BSD-2-Clause licensed and free. Its license section carries a required attribution line stating that it is an independent utility built by Mixpeek for interoperability with IAB Content Taxonomy standards. It is the Tech Lab's mapper in the sense that the Tech Lab hosts and points to it. It is not an official IAB product, and no certification program exists either way.
What it does: you feed it your existing 2.x codes or labels as CSV or JSON. It maps them into the 3.0 ID space through a phased pipeline. The phases: deterministic and alias-based exact matching first. Fuzzy matching comes next. Optional semantic stages follow, using local embeddings and an optional local language-model re-rank. All of it runs on your machine. The output is a mapped file with codes, labels, confidence scores, and the method used per row. It also emits OpenRTB- and VAST-ready category IDs with a configurable version field. Sensitive-content flags are surfaced, with an option to exclude them. Where the automatic answer is wrong or arguable, it supports manual overrides. That is how a reviewed migration stays reproducible. Its documentation describes processing as local-first with no external APIs needed, and capable of running air-gapped.
Two honest notes on the free path. First, it demands what local tools demand: a Python or Node environment, your data in CSV or JSON shape, threshold tuning, and a review pass on low-confidence rows. Second, its vendor's own page scopes it as a batch migration tool. It is not a runtime service. It converts a label table. It does not sit in your serving path classifying new content. And it does not classify text into codes at all; it maps codes you already have.
One version nuance, because coverage is loose with it too. The mapper's documentation describes output in the 3.0 ID space. Press coverage calls the donation a 2.x-to-3.1 accelerator. Both describe the same route. Version 3.1 is the current point release on the 3.0 structure, and its notable change is the genre refresh. A team that runs the mapper is migrating into the 3.x structure. Checking genre-adjacent labels against the 3.1 file is the extra step.
One call at scale, when the lane lands
The hosted rung is what this platform is building for the cohort that wants neither the spreadsheet nor the environment. Its planned shape is two lanes on one classifier card. The iab-3x lane takes submitted text in and returns 3.1 codes with confidence. It also offers a cross-map operation that carries 2.x codes to their 3.x equivalents in the mapper's own output columns. The iab-2x lane serves stacks that still need legacy labels during the transition window. What hosted buys is exactly the parts the free path demands. There is no Python environment, no CSV wrangling, no model babysitting. You make one API call over a corpus. Metering is by the page, against a prepaid wallet. The balance is the hard stop, and a request refused at the door bills nothing. It does not buy better truth than the mapper; it buys the work not being yours.
The pre-launch law, again, because this is where a vendor page would slide into a pitch: no row exists for either lane in the platform's model data. Nothing answers a call under their aliases, no rate exists, and no date is promised. The working contract below is the design, published so an integration can be written before anything ships. If your migration cannot wait, the two rungs above work today.
The plan no tool runs for you
No page ranking for this query gives the migration plan. Here it is, in the order that keeps labels, buyers, and weeks intact.
- Inventory what you hold. Which version your labels are actually in (mixed deployments are common), where the labels live, how many distinct codes and how many pages, and whether risk and sensitivity annotations ride alongside.
- Pick the primary and keep the secondary. Label into 3.1 as the primary set and keep 2.x available on demand; the two-version posture is the point of a cross-map, and buyers sit on both sides of the transition.
- Make the version explicit on the wire. OpenRTB's category fields carry your IDs and the cattax field declares which taxonomy they are in; the OpenRTB 2.6 specification defines cattax with a default of 1, meaning an absent field silently declares the deprecated 1.0 line.
- Ask your buyers what they accept. The concrete example is Google: its Authorized Buyers guide states it uses Content Taxonomy 1.0 as the default ad category taxonomy for its accounts and warns that using it can increase bid filtering where categories have no equivalent. Version drift costs impressions quietly; the fix starts with asking each demand partner what they read.
- Set a confidence floor and review under it. The mapper returns confidence and method per row. Decide the threshold, review what falls under it, and write overrides for the rows you settle, so the decision is recorded and the run is repeatable.
- Carry risk and sensitivity columns through, do not convert them. Re-join them to the new codes and verify on a sample that nothing silently dropped.
- Keep the mapping table versioned. The migration is a table plus a re-run script, not a one-time edit. Genre coverage moved as recently as December 2024; a re-runnable table is the difference between a migration and an archaeology dig.
What a hosted lane is, and is not
Said plainly, because the honesty is the product: the official route to this migration is free. The mapper is open source, free, and runs on your own machine. If you have an engineer and a quiet machine, that is the correct answer at no cost, and this guide has nothing to sell you. The same local-versus-hosted arithmetic that governs speech models applies here. The TTS local versus API break-even guide works that decision shape in the open.
A hosted lane sells convenience, never necessity. You get no environment to run, no wrangling, one call over a corpus. Per-page metering comes from a prepaid wallet that bounds what a runaway backfill can spend. The failure mode is covered separately in how to avoid API bill shock. If those conveniences are not worth metered spend to you, run the mapper. The lanes are being built for the teams for whom they are.
The working contract, written down
The designed surface for the migration cohort is the cross-map: your 2.x codes in, 3.x equivalents with confidence out, one request.
curl -X POST "https://api.ironstratum.com/v1/classifications/crossmap" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "iab-3x",
"codes": ["1-4", "2-12"]
}'
The classify operation answers the other half of the window, fresh text into 3.1 codes:
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."]
}'
Three design facts for planning. The output columns mirror the mapper's own: codes, labels, confidence. A pipeline built on mapper output recognizes the answers. Metering is by the page. A page is up to 2,000 tokens of submitted text, rounded up, so a backfill prices as page arithmetic. No rate is quoted here because none exists. The lanes ride the platform's OpenAI-compatible endpoint family, covered in the OpenAI-compatible API guide. The same card carries the gliner-extract lane for zero-shot entity extraction, the who-and-what alongside the what-it-is-about. These are designs pinned ahead of their rows, per the posture note that opened this guide. The catalog, not this page, carries each lane's state the day a row lands.
Questions the migration cohort asks
How long does the 2.x to 3.1 migration take?
By hand, weeks. The Tech Lab's page credits the mapper with saving "weeks of manual work". Coverage of the donation described the manual process as weeks to months. With the local mapper, the mapping step runs in minutes on a label table. Install it, point it at a CSV, read the confidence column. The full project takes longer than either number. Inventory, buyer coordination, the review pass, and risk-label verification are human work no tool compresses. Plan the tool in minutes and the project in weeks.
Do we have to migrate at all?
The Tech Lab's framing leaves less room every year. Version 2.x is deprecated, the migration is called not optional, and the current release is 3.1. In practice the forcing function is your buyers. While demand partners still accept 2.x codes, a dual-version posture works. The cross-map exists so one corpus can serve both. The version you declare in bid requests matters even when you change nothing else. An absent version field defaults to the deprecated 1.0 taxonomy.
Is the official mapper really free?
Yes. It is BSD-2-Clause, open source, in the IAB Tech Lab's GitHub organization. It processes locally with no external API calls. The optional embeddings and language-model re-rank stages also run locally. The one obligation its license states is attribution in anything you deploy that uses it. The line notes it is an independent utility built by Mixpeek. Free does not mean it runs itself. Budget the environment, the data shaping, and the review pass.
What happens to brand-safety and risk labels?
They survive as a structure and must be carried deliberately. The 2.2 file's Sensitive Topics group (11 categories) and Brand Suitability and Risk group (four levels, Floor through Low Risk) map onto the 3.x vector model. There, risk associates with topics dynamically rather than living in the topic codes. Convert the topic codes. Keep your risk annotations as their own columns. Re-join them, and verify on a sample that the join lost nothing. What a demand partner screens against is their call. Ask, then send what they require.
Which version should bid requests send?
Send 3.1 labels with the cattax field explicitly set. Keep 2.x available for partners that still require it. The failure mode is silence. OpenRTB's cattax defaults to taxonomy 1.0 when absent. Google's Authorized Buyers documentation is explicit that default taxonomy use increases bid filtering where categories lack equivalents. An explicit version costs one integer. It removes an assumption the whole downstream chain would otherwise make.
Per-unit rates for every lane this platform runs or plans sit on the pricing page, which is also where any future classification-lane rate publishes first. To be ready with a wallet and a key for the day a row lands: sign up.
Last verified: 2026-09-25