A promo code proves somebody had the code, not that the ad sent them
Photo by Tamanna Rumee (opens in a new tab) on Pexels
Promo codes look like the cleanest attribution there is for phone and in-store sales: the code names the campaign, and the invoice records the code. In practice codes leak to coupon sites, get applied by staff to close a sale, go unasked for on the phone, and cost real margin every time. Here is when a code is good evidence, when it is not, and how to check codes against sales matched by phone and email.
Contents
A promo code proves the buyer had the code, not that your ad reached them. Public codes leak, staff apply them to close sales, and phone buyers are rarely asked. Use single-use codes where you can, record who supplied each code, and only credit a code's channel when the buyer's phone or email matches a lead from that channel.
An HVAC company runs a spring offer: $75 off any repair or replacement over $500, code SPRING75, promoted only in its paid social ads. By June the invoicing system shows 180 jobs with SPRING75 on them. The social campaign cost $12,000, so the owner's spreadsheet says $66.67 per customer, the cheapest number in the business, and the budget for next spring doubles.
Some of those 180 customers saw the ad. Some found SPRING75 on a coupon site while comparing quotes. Some were already halfway through a quote from a search lead and asked whether there was a deal on. Some never mentioned a code at all, and a technician typed it in to close a reluctant homeowner on the doorstep. The invoice cannot tell these apart, and the spreadsheet credits all of them to the ad.
Our posts on direct mail, podcasts and creators each argue that codes undercount, because most people moved by an ad never use the code. That is true, and it is half of the problem. This post is about the other half: the ways a code overcounts, what each redemption actually costs, and the check that sorts the redemptions you can believe from the ones you cannot.
What a promo code actually records
A redeemed promo code records that, at the moment of sale, somebody entered a particular string and a discount was given. It does not record where the buyer got the string, who typed it, or whether the buyer would have paid full price without it. Everything else is inference.
That is a narrower fact than it looks. In an online checkout the buyer usually types the code themselves, so "somebody entered it" at least means the buyer. At a counter, on a phone booking or on a technician's tablet, the person entering the code is staff, and the code is whatever they were told, remembered or decided to apply. The system records a string and an amount either way.
Read that from the attribution side. A point-of-sale system is built to answer "how much did we give away, and under which discount name", which is a finance question. It is not built to answer "which ad reached this person", and nothing in the redemption row says so. The code becomes attribution only because somebody decided that a string named after a campaign means the campaign made the sale.
Four ways a code reaches a sale the ad never made
A code overcounts its channel whenever it reaches buyers by another route: posted to coupon sites, applied by staff, quoted by a customer who was already buying, or used by an existing customer. Each route puts the campaign's name on a sale the campaign did not produce.
1. The code leaks
A code anybody can type is a code anybody can post. Customers share it, coupon sites list it, and browser extensions try every known code at checkout without the buyer ever searching. The affiliate partners post covers how coupon sites get paid for that; the attribution problem is separate and arrives even if you pay nobody.
The symptom Chen describes is the one to watch for: redemptions that rise while the campaign behind the code has not changed. For a business selling by phone the leak is slower but the same. A homeowner comparing three quotes searches your name plus "coupon", finds SPRING75 on a deal site, and quotes it to your office. The office applies it, and the campaign gets a customer it never reached.
2. Staff apply it
Give a counter, a call center or a sales team a live code and they will use it as a closing tool. A customer hesitates over price, the rep says "I can do the spring offer for you", and the sale closes with the code on it. That is a reasonable thing for a rep to do. It is also a price concession, and it lands in the report as a sale from the ad. Variable discounts and a code everyone knows make this easy; a passcode or manager approval makes it rarer, not rare.
3. A buyer who was already buying asks for a deal
"Is there any discount on at the moment?" is one of the most common questions at the end of a quote. A buyer who called from a search ad two weeks ago, got a quote and is ready to sign asks it, and the rep offers the current code. The code is now on a sale whose first contact came from a different channel, and the code's campaign takes the credit for the last step of somebody else's sale. This is the same fight described in channel conflict, with a discount attached.
4. Existing customers use it
A code meant for new customers is usually redeemable by old ones unless the system checks. Shopify, for instance, lets a merchant set the number of times a code can be used and a maximum of one use per customer, but one use per customer still lets every existing customer use it once. For a service business that does maintenance visits, a spring code can easily end up on a large share of repeat customers' jobs.
And the ways it misses the sales the ad did make
A code undercounts its channel whenever a buyer the ad reached pays without it: nobody asked on the phone, the buyer forgot, the code expired before the job closed, or the discount was entered as a manual price change instead of the code. These buyers leave no trace in the redemption report at all.
The other posts cover the forgetting. For phone and field sales, two specific failures are worth adding, because they are fixable.
- The code is captured at booking and lost at invoicing. The customer quotes SPRING75 to the call center, the call-center notes say so, and the invoice three weeks later shows "$75 courtesy discount" typed by the office. The code exists in one system and the sale in another, and the export used for reporting has only the second.
- The code expired before the sale closed. A spring offer that ends on 31 May misses the customer who called on 28 May and signed on 9 June, unless somebody honored it under a different name. Long sales cycles break code attribution more than anything else, as the long sales cycles post explains.
Put the two halves together and the redemption count is neither a floor nor a ceiling. It is a number that is too high for some reasons and too low for others, by amounts nobody has measured. That is why it should not be the measure of a channel on its own, and why it is still worth keeping: once each redemption is checked against an independent record, the code becomes a useful second witness.
A redemption count is inflated by leaks, staff and existing customers, and deflated by forgotten and unasked-for codes. It is not a floor. It is an unverified claim per sale, and it becomes evidence only when something independent agrees with it.
When a code is good evidence
A code is good evidence when only one channel could have delivered it and the buyer, not staff, supplied it. Single-use codes sent to named people are close to proof. A code printed in an ad and never published online is moderate evidence. A code anyone can find, or any staff member can apply, is barely evidence at all.
| Kind of code | Who can have it | Evidence it gives | Main way it fails |
|---|---|---|---|
| Single-use, sent to a named person | That person, or whoever they forwarded it to | Strong: close to a match | Forwarding to friends and family |
| One code per medium, never published online | Anyone who saw that ad or was told about it | Moderate | Word of mouth, and later coupon sites |
| One code in a public ad, landing page or social post | Anyone on the internet within days | Weak | Coupon sites and extensions |
| A code staff can apply or a variable discount | Every customer a rep chooses | None about the channel | Used as a closing tool |
| A seasonal or evergreen code used everywhere | Everyone | None | It is a price, not a tracker |
The first row deserves its own sentence. A single-use code mailed to a named customer is, in effect, a match on a person: the code was issued to one identity, and redeeming it ties the sale to that identity. That is why the mailing-list methods in the direct mail post work so well and why the same logic applies to an email list. Unique codes are cheap to generate; the reason most businesses do not use them is that a single memorable code is easier to put in an ad.
Two cheap changes move a code up the table without changing the offer:
- Record who supplied the code. A required field on the booking or the invoice: customer quoted it, customer typed it online, staff offered it. Staff-offered codes are a pricing decision and come out of every channel's count.
- Carry the code from first contact to the invoice. Write it on the lead when the customer first mentions it, with their phone and email, so it survives a discount being re-entered weeks later under another name. The CRM export post covers getting that field into the file you report from.
Check every code against the matched lead
The cross-check is simple: match each closed sale to your lead file by normalized phone and email, then compare the code on the sale with the source on the matched lead. Sales where both agree are strong evidence. Disagreements are leaks, late discounts or another channel's customers, and are reported separately rather than credited to the code.
This works because the two records fail independently. A code can be applied by anyone; a lead row was created when the customer first called or filled in a form, before anyone was discussing price. If the buyer's normalized phone number or email appears on a lead tagged with the code's channel, two separate records agree. If it appears on a lead from somewhere else, or nowhere, they do not.
Back to the HVAC company. The 180 SPRING75 jobs were matched against every lead it had exported for the season, and the invoices were checked for who added the code. The figures are illustrative, but the arithmetic is the method:
| Group | Sales | What it means | Credit to paid social? |
|---|---|---|---|
| Code, matched to a paid social lead | 62 | Both records agree | Yes |
| Code, earliest lead from another channel | 41 | A leak, or a late discount on another channel's sale | No |
| Code, no matching lead, quoted by the customer | 29 | Plausible, unproven | Footnote only |
| Code, no matching lead, added by staff | 48 | A price concession | No |
| No code, matched to a paid social lead | 38 | The ad's buyers who never used the code | Yes |
The arithmetic. The code report credits paid social with 180 sales: $12,000 ÷ 180 = $66.67 a sale. The matched view credits it with 62 + 38 = 100 sales: $12,000 ÷ 100 = $120 a sale. If every customer-quoted, unmatched redemption is generously given to social as well, it is 129 sales and $12,000 ÷ 129 = $93.02. So the honest statement is a range: between $93 and $120 a sale, with $120 the figure that can be traced to a lead, an invoice and a phone number.
Notice that the cross-check moved the number in both directions. It removed 89 sales the code report claimed (41 + 48) and added 38 it missed. That is the case against reporting redemptions as a floor: a floor would have been 180 and the truth is lower. The 29 in the middle stay visible as their own line, neither hidden nor counted, the same treatment unattributed revenue gets.
The 41 are worth reading row by row. If most of them have earliest leads from branded search, the code is being found by people already looking for you, which is a leak. If most were quoted weeks after first contact, the code is being used as a closer, which is a pricing question for the sales manager. Either way, the match rate of the code's own sales against its own channel, here 62 ÷ 180 = 34%, is the single best number for how much to trust that code next time.
CloseRev does the matching half of this check: it matches your closed-sales CSV against your lead CSV on normalized phone and email, credits each matched sale to the source written on its earliest matching lead, and counts only high-confidence matches automatically, with medium and low ones left for review. It does not read promo codes, so the comparison with the code column is done in your own sales file. A sale with a code and no matching lead stays in Direct / Unknown, not in the code's channel.
What a code costs, and the break-even test
A promo code costs its discount on every redemption, including the buyers who would have paid full price. It pays for itself only if enough redemptions are sales the offer created. The share it needs is the discount divided by the gross profit on the sale before the discount.
A national retailer and a local contractor have little in common, but the mechanism is the same: a discount is a cost charged on every buyer who uses it, and an attribution report that only counts the redemptions as wins never shows it. The HVAC company's SPRING75 cost 180 × $75 = $13,500 over the season, more than the $12,000 of media it was meant to measure.
Split it by the groups above. The 62 matched social buyers received 62 × $75 = $4,650. The 41 buyers from other channels received $3,075, the 48 staff-applied codes $3,600 and the 29 unproven ones $2,175, which adds back to $13,500. The cost of the social campaign is its media plus the discount on its own sales: $12,000 + $4,650 = $16,650, or $166.50 for each of its 100 matched sales. The remaining $8,850 is the cost of having a public code at all.
Now the break-even test. Suppose the average job is $1,200 with a 45% gross margin, so $540 of gross profit before the discount. A redemption by somebody who would have bought anyway loses $75. A redemption that is a genuinely new sale earns $540 − $75 = $465. If a share f of redemptions are new sales, the code breaks even when 465f = 75(1 − f), which is 540f = 75, or f = 75 ÷ 540 = 13.9%. About one redemption in seven has to be a sale the code created.
| Discount | Gross profit before discount | Break-even share (discount ÷ profit) |
|---|---|---|
| $75 on a $1,200 job | $540 (45%) | 75 ÷ 540 = 13.9% |
| $150 on a $1,200 job | $540 (45%) | 150 ÷ 540 = 27.8% |
| 10% on a $300 sale | $120 (40%) | 30 ÷ 120 = 25% |
| 20% on a $60 sale | $12 (20%) | 12 ÷ 12 = 100% |
The last row is the one to show anyone planning a 20% code on a thin-margin product: every single redemption has to be a sale that would not otherwise have happened, which no code achieves. The cross-check is what makes the test usable. It cannot say which matched buyers would have bought anyway, but the 41 buyers already in another channel's pipeline and the 48 staff-applied codes are a direct, countable lower bound on the redemptions that created nothing. Here that is 89 of 180, or 49%, before asking about anyone else. To measure the rest, run a holdout as described in incrementality tests.
How to run codes so they can be checked
Keep the code as an offer, and design it so each redemption can be checked: one code per medium, unique codes for named recipients, a short expiry, a field recording who supplied the code, and the buyer's phone and email on the lead where the code first appears. Then report matched sales as the result and redemptions as a cross-check.
- One code per medium, never reused. A code that appears in the radio spot and the social ad cannot tell them apart. Change the code when the medium changes.
- Unique codes wherever you know the recipient. Mailings, email lists and past customers can all receive single-use codes, which turn redemptions into near-matches.
- Keep the code off your own website. A code on a public page will be indexed and copied within days. Put it in the ad and on the call script only.
- Restrict who can apply it. Require a passcode or manager approval for discounts at the counter, and record when staff offered the code rather than the customer.
- Write the code on the lead, with a phone and email. Make sure the call-center or front-desk record carries the code into the export, not just the invoice.
- Report three numbers. Sales matched to the channel's leads, redemptions that agree with a matched lead, and redemptions that do not, each with its discount cost.
- Watch for spikes. A jump in redemptions with no change in the campaign is a leak. Retire the code and issue a new one.
None of this needs a new tool. It needs the code treated as what it is: a discount with a label on it, which can be good evidence when the label is hard to obtain any other way, and is otherwise one more thing somebody typed into a field.
Keep promo codes for the offer. Measure the channel with matched leads, and use the code as a second witness: when a redemption agrees with the lead the buyer's phone or email matches, believe it; when it does not, count the discount and not the sale.
Questions people actually ask
- Are promo codes a reliable way to attribute phone and in-store sales?
- Only some codes, and only after a check. A single-use code sent to a named person is close to proof. A code published in an ad is weak: it leaks to coupon sites, staff apply it to close sales, and phone customers are rarely asked for it. Treat each redemption as a claim, and confirm it against the lead the buyer's phone or email matches.
- Why do promo codes end up on coupon sites?
- Because a code anybody can type is a code anybody can post. Customers share them, coupon sites collect them, and browser extensions test known codes automatically at checkout. In May 2024 Modern Retail reported a founder saying usage limits set in Shopify did not stop Honey's extension picking codes up. Once a code is public, its redemptions include people your ad never reached.
- Should staff be allowed to apply a promo code for a customer?
- They will, so record it when they do. Staff apply live codes to win a hesitant customer or match a competitor, which turns the code into a price concession rather than evidence about an ad. Add a field for who supplied the code, customer or staff, and leave staff-supplied codes out of any channel's count.
- How do I check promo codes against my matched sales?
- Match each closed sale to your lead file by normalized phone and email first, then compare the code on the sale with the source on the matched lead. Agreement is strong evidence. A code on a sale whose earliest lead came from another channel is a leak or a late discount. A code with no matching lead is a claim with nothing behind it. Report each group separately.
- How much does a promo code actually cost?
- The discount, on every redemption, including the buyers who would have paid full price. The break-even test is simple: divide the discount by the gross profit on the sale before the discount. A $75 code on a sale with $540 of margin needs at least 14% of redemptions to be sales the offer created. A 20% code on a 20% margin needs all of them.