The sale that arrives with no referrer

A creator shares a link on Instagram, the buyer taps it, installs the app and purchases. Nothing in that chain carries the creator's name across. Here is what does.

3 min readGlitz · Attribution stage

A marketplace that pays creators a commission has one promise underneath everything else: if your link made the sale, you get paid. On the web that promise is cheap to keep. The link carries a code, the code lands in a cookie, the cookie is read at checkout. On mobile, through a social app, it falls apart at every step.

The buyer is inside Instagram. They tap the link and it opens in Instagram's own browser, not theirs. The page offers the app. They tap through to the App Store, install, and open something that has never seen the link, the cookie, or the code. The referrer did not survive the trip. From the platform's side, a stranger just installed the app and bought something, and the creator who did the work gets nothing.

The two ways out

The standard answer is an attribution vendor: an SDK in the app, a script on the page, and a fingerprint service in the middle that matches one to the other. It works, it costs money per install, and it puts a third party between the platform and the one number it cannot afford to get wrong. The other answer is to build the small version yourself, and the small version is small.

What the platform does

The tracking page looks at the user agent. A normal browser gets redirected to the product with the code in the URL, and a cookie takes it from there. An in-app browser gets something else: before the page renders, the visit is recorded with the visitor's IP address, the user agent, the code, and a 48-hour expiry. The page then offers the app.

When the app opens for the first time, it asks the server one question: has anyone at my address tapped a link in the last two days that nobody has claimed? If so, the newest one is marked claimed and its code is handed back. The app treats that code exactly as if the link had arrived directly, holds it through sign-up, and applies it at the first purchase. The question is asked once per install, with a cooldown, and not at all if a real link is already waiting.

That is the whole mechanism. The user agent is stored beside the record but the match is the address and the clock. No SDK, no vendor, one collection of short-lived documents that a scheduled job sweeps.

What broke it, and what that added

One social platform resolves links on its own servers before showing them to the user, as a safety measure, and follows the redirect. The visitor never touches the tracking page, so the record is never written. The fix was a second capture point: the product page itself, when it arrives with a code, posts the record from the browser. That page is statically cached, so the recording had to be a separate endpoint rather than something done while rendering, or the page would have stopped being static for everyone to serve one social app.

Then the endpoint itself. It has to be unauthenticated, because the visitor is a stranger, and anything unauthenticated that writes to a pool used for matching can be flooded or poisoned. So it is rate-limited per address, the code has to have the right shape and has to resolve to a live link, and the user agent is truncated. The rate limiter runs in a transaction, and if that transaction fails the request is allowed through. That was a decision, written next to the limiter: for this endpoint, dropping a real tap costs more than admitting an extra one.

What it costs

It is probabilistic. Two people behind the same address, a household or an office, both installing within the window: the second gets matched to the first's tap. The window and the rate limit are the whole defence, and for a commission that is held thirty days before it pays out, the platform can afford to be occasionally generous to a creator rather than reliably unfair to all of them. That trade is not hidden. It is written here and it is written in the anatomy.

Why it belongs on this page

The problem spans a web page, a hosting platform's cache, an API endpoint, a database, a mobile app and the behaviour of somebody else's in-app browser. Each piece is simple. The reason it works is that one person could hold all six at once and move the fix to whichever layer was cheapest. That is the case for one pair of hands, made with a link that lost its referrer.

More notes
  • The webhook that credits twiceA payment processor delivers every result at least once. The interesting engineering is in what happens when your side fails halfway through.
  • A ledger you can edit from a route handler is not a ledgerWhy every movement of value on the payments platform goes through a Postgres function, and what it costs to keep it that way.
  • Four rows that were not theirsHardening multi-tenant row-level security in four reversible phases, verified by impersonating a member and counting what they could see.
  • The bug inside the fixA payout race, the fix for it, the bug inside that fix, and why it is the best argument I have for one person owning the whole path.
  • The minimum that belongs to someone elseHeld commissions are released to creators once a brand's payout minimum is met. Group the money by creator, the obvious way, and one brand's minimum ends up holding another brand's money.
  • The commission that must not mint twiceA buyer pays and the platform owes a creator a commission. Between those two facts sit a colluding pair, a call that arrives twice, and a cart with three items on one payment.
  • The rule that has to be written twiceFirestore security rules do not cascade to subcollections. Forget that in one place and a single query returns every private message on the platform.
  • Thirty days in the ledgerSplitting a payment at charge time is simpler and wrong: a refund after the creator is paid is a clawback nobody enjoys. Holding the money creates a different set of problems, and each piece of machinery around the hold answers one of them.
  • Arbitrary but consistentA gym's assessment answers become rules that swap an exercise for a member before a session. Two rules can disagree about the same movement. The code says who wins, and the comment admits how.