Insights ยท Data Foundations

Why creative tagging fails, and what a working ontology looks like

Sam GilยทSep 2025ยท5 min
Key takeaways
1If your best and worst ads carry nearly the same tags, creative analysis is running on noise
2Catch-all fields fail structurally: one required pick hiding 6 different questions gets applied inconsistently, then abandoned
3The fix is boring and works: one question per field, single vs multi-select declared, and "would it change a brief" as the gate
4Key:value codes (not positional underscores) carry the taxonomy in the ad name; the ad ID passed through UTMs carries the join, so renames break nothing

Two video ads for the same wallet brand are running in Meta's public Ad Library as we write this. One is a creator pitching to camera in his front yard with a tray of colorways, the other is a beach skit where the product doesn't even appear in the opening frame. Run them through a typical DTC creative taxonomy and they come out literally identical: 7 of 7 fields, same copy word for word. Whatever makes one of them win is invisible to the exact system that exists to explain wins.

This is worth dwelling on because creative analysis is the current promise of every ad platform and every AI tool: tag your assets, cut performance by attribute, learn what works, brief better creative. The whole chain runs on the taxonomy, and in our experience inside brands' own libraries the taxonomy is where it quietly dies. Not because teams don't tag, but because the fields themselves can't hold the distinctions that matter.

Ad A
A creator pitching to camera in his front yard, wallet and phone held up, a tray of colorways below frame.
Ad B
A beach skit: a woman on a towel, story captions, the product nowhere in the opening frame.
FieldAd AAd B
ProductWalletWallet
Copyโ€œSlim. Secure. Built to last.โ€โ€œSlim. Secure. Built to last.โ€
Feature tagRFIDBlockingRFIDBlocking
CTAShopNowShopNow
Destinationridge.comridge.com
OfferNoneNone
Media typeVideoVideo
Two video ads running simultaneously for the same brand (Meta Ad Library, Sept 2026), tagged the way a typical DTC naming convention would tag them: 7 of 7 fields identical, same copy word for word. A front-yard product pitch and a beach skit, and the system cannot tell them apart at all. Any report slicing by these tags averages A and B together.

The instinctive fix, and the one we watched a brand try, is to add a field that captures "what the ad looks like". Theirs was called VisualTheme: one required pick from ~25 values. It sounds reasonable until you lay the values out and notice they aren't 25 answers to one question, they're answers to 6 different questions that all got poured into the same field.

"VisualTheme"Required ยท choose 1
WideShotEditorialStyle โœ“Assembly โœ“GridRoomLifestyleLargeText โœ“CloseUp โœ“PDPCatalogCustomerTestimonialCollageLifestyleOutsideInfoGraphicDetailShot3DCGIReviewLayeringStoreSplitScreenBlackAndWhiteDetailProductComparisonWhiteSpace
โœ“ = true for one and the same ad: a close-up, editorial-style assembly demo with large text on screen. All 4 are correct picks. The field accepts 1.
The same list, sorted by the question each value actually answers
Shot scaleCloseUpWideShotDetailShotSplitScreen
Visual styleEditorialStyle3DCGIBlackAndWhiteDetailPDPCatalog
Content typeAssemblyCustomerTestimonialReviewProductComparison
LayoutGridCollageLayeringWhiteSpace
SettingRoomLifestyleLifestyleOutsideStore
Text treatmentLargeTextInfoGraphic
One field holding 6 different questions. Whichever of the 4 true values the tagger picks, the other 3 get recorded as absent, and different taggers pick differently while all following the instructions. So a later performance cut by this field compares a shot-scale answer against a layout answer against a content-type answer in one column.. no slice of it means anything. In practice it was applied to a small share of assets, inconsistently, which is how catch-all fields always end.

A close-up editorial-style testimonial has 3 correct VisualTheme values and the field allows one, so every tagger's pick is defensible and every pick is wrong. That's what "not MECE" means in practice: not a philosophical flaw, but 2 people tagging the same asset differently while both follow the instructions. Fields like this end the same way every time.. applied to a small share of assets, inconsistently, and then abandoned.

The rebuild

The rebuilt system runs on 3 rules rather than more effort:

  1. One question per field. Shot scale, visual style, setting and layout each get their own field with their own value list. A field is healthy when 2 people tagging the same asset agree without discussing it.

  2. Single vs multi-select is declared, not assumed. A modern ad rarely argues exactly one thing, so value props are explicitly multi-select, while benefit type stays a single forced call (performance-led vs brand-led) because that tension is the point of the field.

  3. Every field passes "would it change a brief". If knowing that an attribute wins wouldn't change what you ask creators to make next, the field is diligence theater and gets cut, however easy it is to tag.

Applied to a real library, that lands at roughly 29 fields across 7 groups, which sounds heavy until you run the same 2 ads from the top of this post through it:

The same 2 ads under the rebuilt ontology
FieldAd AAd B
MessageBenefit typePerformanceLedPerformanceLed
Value props +Slim|Secure|RFIDSlim|Secure|RFID
HookDirectPitchSkit
Proof typeDemonstrationLifestyleScene
VisualSettingHomeExteriorBeach
Shot scaleMidShotWideShot
Product focusOpeningFrameLateReveal
Text treatmentCaptionsStoryCaptions
ProductDepartmentWalletsWallets
Hero productClassicWalletClassicWallet
Colorways shown61
PeopleHuman modelMaleFemale
Model behaviorTalkToCameraActedScene
ProductionProduction typeCreatorUGCCreatorUGC
ProducerPartnerPartner
Motion styleLockedCameraHandheld
AudioVoiceOnCameraSpeechOnCameraSpeech
MusicNoneNone
FormatMedia typeVideoVideo
Video length30-60s30-60s
10 fields match10 fields differvs 0 of 7 under the old taxonomy
A  bt:PERF ยท vp:SLM|SEC|RFID ยท hk:PITCH ยท st:HOME ยท sc:MID ยท hm:M ยท mb:TALK ยท pt:UGC ยท vl:41
B  bt:PERF ยท vp:SLM|SEC|RFID ยท hk:SKIT ยท st:BEACH ยท sc:WIDE ยท hm:F ยท mb:SCENE ยท pt:UGC ยท vl:37
The full system runs ~29 fields; shown are the ones these 2 ads exercise. The differences it captures.. hook, setting, shot scale, model, motion.. are exactly the levers a brief can pull, and the similarities are real too: same value props, same production type, both on-camera speech with no music. Length buckets to 30-60s for analysis cuts while the name keeps the exact seconds (vl:41 / vl:37). Each field's 2-4 character code assembles into the ad name (bottom), so the whole taxonomy rides inside every platform's reporting.

The taxonomy that saw 2 identical ads now sees 9 differences, and they're the right ones: hook, setting, shot scale, who's on camera, how it's shot. The similarities it keeps are real too.. same value props, same production type.. which matters just as much, because a cut by "creator UGC" should include both of these ads while a cut by "beach skit" includes one.

The operating layer is what makes 29 fields cheaper than 7 bad ones. Each field gets a 2-4 character code, and a small generator assembles the codes into the ad name itself (the 2 name lines under the table above), so the taxonomy travels inside every platform's reporting with no integration work and tagging a new asset takes ~2 minutes. The historical library gets backfilled by AI against the written field definitions, with human spot-checks on a sample.. and this is the part worth being precise about: AI is very good at applying an ontology and unreliable at inventing one. Generic auto-tagging gives you generic fields, which is the VisualTheme problem again with better marketing.

Why key:value codes, not underscores

Most naming conventions are positional underscore strings: EVG_PROS_UGC_BEACH_30_V2. The meaning lives in the position, and position is fragile. The day a field gets added, the day one ad skips a segment, or the day two teams disagree on whether slot 4 is audience or placement, every report parsing those names silently misreads.. and nobody notices, because the string still looks like a name. Key:value codes (st:BEACH, hk:SKIT) put the meaning in the token instead: order doesn't matter, a missing field is a missing key rather than a shifted column, and any tool.. a spreadsheet, a warehouse model, an AI.. can parse names it has never seen.

The quieter benefit is change. A taxonomy is never finished: next quarter you'll want a field for a new format, or to split one that turned out to be holding 2 questions (the VisualTheme lesson). With key:value names you add the key and move on.. every historical name stays valid and every report keyed on existing fields keeps working. With positional names, a change means re-parsing history or running 2 conventions side by side forever, so in practice nobody changes anything and the taxonomy stays wrong.

One thing the name should never be, though, is the join key. Campaigns and ads get renamed, and every rename silently orphans the web data that was joined on the old string. Pass the platform's ad ID through your UTMs (e.g. utm_content={{ad.id}} on Meta, so it populates automatically), join platform data to web data on that, and let the name carry the taxonomy. Renames then cost you nothing: the ID holds the join, and the current name re-parses into the current tags.

What to do with it

  1. Run the twin test on your current system: pull your best and worst recent ad and compare their tags. If they nearly match, your creative reads are noise, whatever the dashboard says.

  2. Split every field where 2 taggers could both be right. One question per field, and declare single vs multi-select explicitly for each.

  3. Gate each field with "would it change a brief". Cut the ones that fail, even the easy ones.

  4. Encode the fields into ad names via a generator, as key:value codes rather than positional underscores, and join platform data to web data on the ad ID passed through UTMs.. never on the name, which renames will break.

  5. Let AI backfill history against your written definitions and spot-check a sample before trusting any cut of it.

Happy to walk through how we'd approach it for your creative library.

Common questions

Can't AI just tag our creative automatically?

It can apply a taxonomy far faster and more consistently than people, and that's exactly how the backfill above works. What it can't do reliably is decide what the fields should be, because it doesn't know which distinctions would change your briefs. Off-the-shelf auto-tagging tools ship generic fields ("lifestyle", "product-focused", "UGC") that fail the same MECE test the catch-all field failed, just with less visible seams. The working division of labor: humans define the ontology against the would-it-change-a-brief test, write real definitions for each value, and AI executes tagging at scale with humans spot-checking a sample. Teams that skip the definition step usually discover it 6 months later, when the cuts contradict each other and nobody trusts the creative reporting.

Isn't ~29 fields too many to maintain?

It's fewer decisions than it looks like, because most fields are a single obvious pick (shot scale, setting, format) and only a handful require judgment. With codes assembled by a generator, tagging a new asset runs ~2 minutes, which is less time than teams currently spend arguing about one ambiguous catch-all value. The count also isn't the goal; it's the output of the 3 rules. A smaller library with fewer formats might land at 15 fields. What matters is that each field answers one question and earns its place, because a wrong 7-field system produces confident wrong answers, and a right 29-field system produces cuts you can act on.

How do we get value from this before hundreds of new ads are tagged?

The backfill is the shortcut. Because the fields have written definitions, AI can tag your existing library retroactively, so the first real analysis cut is available in weeks rather than quarters. Start with the dimensions most likely to move a brief (content type, benefit type, value props) and validate against a hand-tagged sample of ~50 assets before reading anything directionally. Early reads will be directional at best until sample sizes build within each cut, so treat the first pass as hypothesis generation for creative testing rather than settled truth. The compounding value shows up after that: every new ad ships pre-tagged through the name generator, so the dataset never decays the way manually tagged libraries do.

This kind of structure-first measurement is core to our Acquisition & Creative work.

See how it works โ†’
SG
Sam Gil
Principal, Growth & Analytics ยท Meridian Growth
About the team โ†’

Keep reading

Data FoundationsOct 2026 ยท 8 min
DMA vs CBSA vs MSA: which geography to use for ecom analysis
Read โ†’
Measurement & AttributionOct 2026 ยท 6 min
Why media affiliates look like your best channel, and the 30-minute test that cut one brand's commission by ~$500k
Read โ†’
Data FoundationsOct 2026 ยท 8 min
How to map ZIP codes to DMA, metro area and region: the one table to join to your orders
Read โ†’
Measurement & AttributionSep 2026 ยท 7 min
Why your year-over-year sales look terrible the week before a holiday
Read โ†’
ExperimentationSep 2026 ยท 6 min
How long to run an ecom A/B test
Read โ†’
ExperimentationSep 2025 ยท 6 min
Why Most Startup Experiments Fail (and What to Do Instead)
Read โ†’
Retention & LifecycleSep 2025 ยท 5 min
Retention in Marketplaces: Why Liquidity Beats Variety Alone
Read โ†’
Acquisition & CreativeSep 2025 ยท 5 min
Why First-Party Pixels Beat GA4 for User Journeys
Read โ†’
Data FoundationsSep 2025 ยท 5 min
Why creative tagging fails, and what a working ontology looks like
Read โ†’

Get in touch.

Tell us what you are trying to figure out. If we can help, we will say how. If we are not the right fit, we will say that too, and point you somewhere better.

01
Free work first
We start by doing a real piece of work on your data, free, so the first thing you judge is output, not a pitch.
02
First build, fixed scope
One piece of work at a fixed price, scoped to a few weeks: a metric layer, a tracking plan, one agent or one pipeline, whichever gap you came with. Small enough to be safe, real enough to matter.
03
Scale when it earns it
Month to month from there, from a few thousand a month. You own every model, dashboard and definition.