---
title: "How to allocate ad spend to products when ads don't map one-to-one"
description: "To allocate advertising cost to products, read cost at the level of the individual ad, match each ad to a product through a fixed ladder of rules (exact SKU code, then keyword, then account), split shared ad accounts by a token in the campaign name, and divide what remains across products by number of orders. Every rule fails silently in a specific way, so the method is mostly about catching those failures."
date: 2026-10-11
lang: en
canonical: https://goingstellar.ro/methods/allocate-ad-spend-to-products/
author: Going Stellar
publisher: GOING STELLAR S.R.L.
topic: E-commerce / Marketing attribution
license: CC BY 4.0
alternate_ro: https://goingstellar.ro/ro/metode/alocare-cost-reclame-pe-produse/
---

# How to allocate ad spend to products when ads don't map one-to-one

*To allocate advertising cost to products, read cost at the level of the individual ad, match each ad to a product through a fixed ladder of rules (exact SKU code, then keyword, then account), split shared ad accounts by a token in the campaign name, and divide what remains across products by number of orders. Every rule fails silently in a specific way, so the method is mostly about catching those failures.*

> E-commerce · Marketing attribution · 2026-10-11 · https://goingstellar.ro/methods/allocate-ad-spend-to-products/

## Key points

- Allocate ad spend to products with a precedence ladder: an exact SKU code in the campaign or ad name, then a product keyword, then the ad account, and finally share group or brand cost across sold SKUs by number of orders.
- Use ad-level cost to decide how spend is divided between products, but keep the account-level figure as the authority for the total, because catalogue campaigns do not always split their cost per ad.
- On a shared ad account, each brand must have a token in its campaign names; an empty token means the brand captures every campaign on the account and the cost is counted twice.
- Short keywords of three characters or fewer need word boundaries, with the hyphen counted as part of the boundary, or they match inside unrelated words and ad identifiers.
- An ad account's name is not proof of its brand: accounts change hands and get renamed, so attribution rules belong on campaign names.

## Why ads don't map one-to-one to products

Allocating ad spend to products means deciding, for every unit of advertising cost, which product it was spent to sell. The direct answer is a precedence ladder: an exact product code in the campaign or ad name wins; otherwise a product keyword in the name assigns the cost to a product group; otherwise the ad account assigns it to a brand; and group or brand cost is then shared across sold products by number of orders.

A ladder is needed because ads and products rarely line up. One campaign can promote a whole catalogue. One ad account can run campaigns for several stores. An account opened for one brand can later run another brand's budget. Test campaigns spend money on products that may never sell. If spend is assigned by account name alone, all of these cases land on the wrong product without any error.

Product-level ad cost feeds profit per product. Without it, a product's contribution has no marketing line, and every product looks more profitable than it is.

## Step 1: read cost at ad level, keep totals at account level

Product-level allocation needs the cost of each individual ad together with its campaign name and ad name, because the product is often named only in the ad, not in the campaign. Data warehouses frequently store advertising cost per account per day, which carries no product signal at all. We pull ad-level cost directly from the advertising platforms.

Ad-level cost does not always add up to the account total. Catalogue and automated campaigns do not always split their cost per ad, so the ad-level sum can fall short of what the account was charged. Our rule: ad-level data decides how cost is divided between products, and the account-level figure stays the authority for the total.

Two more details at this step. Advertising accounts bill in different currencies, so cost is converted with the exchange rate of each day before anything is added. And raw cost is ingested without filtering by brand; filtering at ingestion hides real cost, while an unfiltered feed shows unmapped cost as unmapped, where an audit can see it.

## Step 2: a precedence ladder from exact code to account

**1. Exact product code.** If the campaign or ad name contains a SKU code, the cost goes straight to that SKU. We accept the code only if it matches a SKU the store actually sold, so a typo cannot create a phantom product. Some codes in names are agency tags rather than products, and those are treated as noise.

**2. Campaign keyword, then ad keyword.** A rule table maps keywords to product groups. Campaign-name keywords are tried first; ad-name keywords come on a separate, later step.

**3. Account.** For an account that sells a single brand or category, the whole account maps to that brand. For an account that sells many products, we do not use an account fallback at all: cost that no product rule catches stays unmapped, because spreading it over the whole brand would hide the mapping gap.

**Tests.** A campaign whose name marks it as a test goes into a test group that is excluded from product allocation and reported separately. A platform report that includes tests reads higher than the sales figure, and the gap is exactly the test cost.

## Step 3: matching rules for keywords

Keyword matching for ad names has to survive how people type. We remove diacritics from both the keyword and the name before comparing, so a keyword written with Romanian letters still matches a campaign typed without them. When several keywords match, the longest keyword wins, so a specific product name beats a generic word it contains.

Short keywords need word boundaries. A keyword of three characters or fewer matched as a plain substring hits inside unrelated words and random ad identifiers. The hyphen counts as part of the boundary, so a two-letter store code does not match the start of a hyphenated product name. The word TEST also needs a boundary: as a substring it caught real products whose names contained TESTER, and those products then showed zero marketing.

Some keywords must be restricted to campaign names. Ad names that were duplicated in the platform interface carry the words `Copy of`, so a two-letter code like OF, matched on ad names, routed cost to the wrong store. That code is now allowed only on campaign names.

## Step 4: shared ad accounts are split by a campaign-name token

A shared ad account runs campaigns for more than one brand. The split rule is a campaign-name token. Each brand on a shared account has a word, or a pattern, that must appear in its campaign names, and the brand takes only the campaigns containing that token. On an account dedicated to one brand, the brand takes everything.

An empty token on a shared account means the brand captures every campaign on the account. That is the most common attribution bug we have seen: one brand silently absorbed another brand's campaigns, which were then counted twice, once under each brand. When several brands share an account, the most specific token wins.

Account names are not proof of brand. An account can be handed from one brand to another on a given date, so the rule lives on the campaign name, not the account. An account can also be renamed in the platform while it keeps running the same brand; we read account names live and log every rename, and we check the campaigns on a renamed account before moving any cost.

## Step 5: from product groups to SKUs, per order

Once cost sits on a product group or a brand, it is divided across the SKUs sold in that group or brand in proportion to their number of orders. Every order then carries the same advertising cost, a uniform cost per acquisition (CPA). A SKU sold in two stores receives cost from each account that advertises it.

Catalogue campaigns that promote many products are handled per day: the cost of each day is shared across the products that received orders in that store on that day. If a store had no orders that day, the monthly order mix is used; if that is empty too, the cost is reported as not spread rather than lost. The key that decides the store must include the campaign, not only the account, because on a shared account a catalogue campaign for one store would otherwise be credited to whichever store spends most on that account.

## A worked example with hypothetical numbers

The numbers below are round and hypothetical, chosen to make the arithmetic easy. They do not come from any account we run.

One day on a shared account, four campaigns. A campaign whose ad names carry SKU code `SKU-0101` costs 400: all 400 go to that SKU. A campaign with the keyword for a towel group costs 300; the group's two SKUs had 30 and 10 orders, so they take 225 and 75. A catalogue campaign costs 200; the store had 50 orders that day, so each order carries 4 and each product takes 4 times its orders. A test campaign costs 100 and goes to the test group, outside product allocation.

Assigned by account name, all 1,000 would have landed on one brand, and the products would have carried cost they did not cause.

## Where we were wrong, and the limits

**We edited a cache instead of the source.** The brand-to-account mapping lives in a shared sheet, and local files are only cached copies of it. Editing one copy by hand looked like a fix, while another script read a different copy; the source already had the right rows and only needed a sync. **A rule fix broke correct matches.** Adding a word boundary to a short code would have pushed correctly attributed campaigns onto an account fallback, so the specific campaign rule had to be added first. **An audit lied by finding nothing.** A script looked up the platform under a different key than the rule table used, received an empty list, and reported that no short keyword ever fired.

Limits: the method reaches about 99% of cost mapped to a product or group, and the rest remains unmapped until someone adds a rule. Ad-level cost undercounts automated catalogue campaigns. Allocation by orders is a model of who caused a sale, not a measurement. Naming discipline is what makes the method possible: a SKU code in every ad name, one token per brand on shared accounts, and test campaigns marked as tests.

Checklist: ad-level cost with campaign and ad names; totals from account level; currency per account per day; exact SKU, then keyword, then account; diacritics removed, longest keyword wins, boundaries on short keywords; tests excluded; tokens on every shared account; live account names; per-order allocation; unmapped cost reported, never dropped; simulate a rule before applying it.

## Questions and answers

### How do I allocate ad spend to products when one campaign promotes several products?

If the campaign names the products in its ad names, read cost per ad and match each ad separately. If it is a catalogue campaign with no product signal, share each day's cost across the products that received orders in that store on that day, weighted by number of orders. If the store had no orders that day, use the month's order mix, and report anything still unallocated.

### How do I split a shared ad account between brands?

Give each brand on the shared account a token that must appear in its campaign names, and let the brand take only the campaigns containing that token. On an account dedicated to one brand, the brand takes all campaigns. Never leave the token empty on a shared account: the brand then captures every campaign, including other brands', and that cost is counted twice.

### Why should keyword matching ignore diacritics?

People type campaign and ad names inconsistently, sometimes with diacritics and sometimes without. If the rule keyword is written one way and the campaign the other way, a plain comparison fails and the cost stays unmapped or falls to a broader rule. Removing diacritics from both sides before comparing makes the keyword match regardless of how the name was typed.

### Should ad spend be allocated to products by revenue or by orders?

We allocate by number of orders, so every order of a brand carries the same advertising cost, a uniform cost per acquisition. Advertising buys orders, and a revenue weighting would push the cost of cheap products onto expensive ones. Either choice is a model rather than a measurement; the important part is to apply one rule consistently and report unallocated cost.

### What naming convention makes ad spend easy to attribute to products?

Put the product's SKU code in every ad name, accepted only if it matches a SKU the store actually sells. On shared ad accounts, put a fixed brand or store token in every campaign name. Mark test campaigns with the word TEST as a separate word. Avoid very short codes that also occur inside ordinary words, or give them strict word boundaries.

## How to cite

**Cite this as:** Going Stellar (2026). *How to allocate ad spend to products when ads don't map one-to-one*. GOING STELLAR S.R.L.. https://goingstellar.ro/methods/allocate-ad-spend-to-products/

```bibtex
@misc{goingstellar2026allocate,
  title  = {How to allocate ad spend to products when ads don't map one-to-one},
  author = {{Going Stellar}},
  year   = {2026},
  url    = {https://goingstellar.ro/methods/allocate-ad-spend-to-products/},
  note   = {2026-10-11}
}
```

Licence. Free to quote with attribution.

## Also available

- This page as HTML: https://goingstellar.ro/methods/allocate-ad-spend-to-products/
- Same article in Romanian: https://goingstellar.ro/ro/metode/alocare-cost-reclame-pe-produse/
