How a take-up gets tracked
An offer you can’t measure is a guess you keep repeating. The point of the one-tap link isn’t just convenience — it’s the clean signal that tells the shop whether the suggestion landed. This post is about attribution: how a tap is tied back to its offer inside a set window, how the frequency cap is updated, and how a scheduled sweep closes the book on every nudge so the whole thing can be judged.
Key takeaways
- The one-tap link is also the measurement: the tap is the clean signal that an offer landed, recorded against that exact offer.
- A tap only counts as a take-up if it falls inside the attribution window — a set span after the nudge, a few days by default.
- Sending a nudge stamps the customer’s frequency cap, so the next order is gated on when they were last nudged, not just whether.
- A scheduled sweep closes the window on offers with no tap, so every offer ends up counted as taken, ignored, or never sent.
- Because every outcome is recorded, the shop can see the real take-up rate — and prune add-ons that never land.
The tap is the signal
An offer you can’t measure is a guess you keep repeating, so the point of the one-tap link isn’t only convenience — it’s the cleanest possible attribution signal. When the customer taps, the add-link redirect from Part 4 does its two jobs in order: it records the tap against the specific offer before it redirects, and only then sends them on to the store’s add-to-cart. Because the token carries the offer id, there is no guessing about which nudge earned the click; the tap is tied to the exact offer, the exact SKU, and the exact customer. That is a far stronger signal than “this customer bought lights sometime this week”, which could have happened for a dozen reasons.
The system deliberately measures the tap, not the eventual purchase. Whether the customer completes checkout after the item lands in their basket is up to them and the store, and chasing an abandoned basket is a different system with different manners. What the recommender is responsible for is whether its suggestion was good enough to act on, and the tap answers exactly that. Keeping the measured event narrow — “did the one-tap add link get tapped” — keeps the attribution honest and the system’s scope clean.
The attribution window
A tap only counts as a take-up if it happens inside the attribution window — a set span after the nudge goes out, three days by default. A tap the same evening is plainly a response to the offer; a tap three weeks later, on a link the customer stumbled back onto, is not really the recommender’s doing and shouldn’t flatter its numbers. The window draws that line. Each offer carries its own window as a TTL-style expiry: taps before it counts as a take-up and stamps the offer taken; taps after it are still honoured — the item still lands in the basket, because it would be rude to break the link — but they’re recorded as out-of-window and don’t count toward the take-up rate.
Sending the nudge does one more thing: it stamps the customer’s frequency cap. The moment an offer is sent, the customer’s last-nudged timestamp and count are updated in the customers table — the very fields Part 2’s gate reads. This is what makes the cap real rather than notional: the next order that customer places is checked against when they were last nudged, and if that’s inside the window, the whole pick is skipped before the model ever runs. The take-up tracking and the anti-nagging cap are two views of the same small piece of per-customer state, which is why they live together.
Closing the book on every offer
Most offers are never tapped — that’s normal, and it’s a number the shop needs to know. But an untapped offer produces no event, and a system that only reacts to taps would leave those offers hanging in the sent state forever, uncounted. So a scheduled sweep, driven by EventBridge Scheduler, runs on a fixed cadence and does the one thing the tap can’t: it notices absence. It queries the offers table for anything still in sent whose attribution window has closed with no tap, and marks it ignored. Each offer is closed exactly once; the sweep is idempotent because an offer already marked taken, ignored, or out-of-window is skipped. Between the tap path and the sweep, every single offer reaches a terminal state — taken, ignored, or, for orders that never got one, no-fit.
That completeness is the whole payoff. Because no offer is left dangling, the shop can read a true take-up rate: of the orders that produced an offer, what fraction were tapped, broken down by add-on and by the item that triggered them. That turns the recommender from a black box into something a shopkeeper can actually manage — the descaler that goes with the coffee subscription lands four times out of ten, so keep it; the matching blanket the model keeps proposing for the dog bed lands almost never, so tag it out of the complementary set and let the rules stop offering it. The system suggests; the numbers teach; and because every outcome including “no offer” is recorded, the teaching is honest.
Why a window and a cap, not a memory
It would be tempting to reach for something cleverer — a model that “remembers” each customer and decides case by case how often to nudge them. That’s the wrong tool for a job that’s really just arithmetic. The attribution window is a fixed span; the frequency cap is a count and a timestamp. Both are trivially auditable, trivially explainable to a shop owner (“we won’t message the same person more than once a month, and a tap only counts if it’s within three days”), and impossible to drift. A model can’t accidentally decide a good customer is fair game for a nudge a day, because the model is never asked; the cap is deterministic Python reading two fields. Keeping measurement and pacing as plain state — not judgement — is what lets the shop trust the recommender to run unattended without ever turning into the thing everyone dreads, a store that won’t stop messaging you.
Design rules that shaped tracking
- The link is the measurement. The tap is recorded against its exact offer before the redirect — clean, unambiguous attribution.
- Measure the tap, not the purchase. Whether checkout completes is the store’s business; the recommender owns whether the offer landed.
- A window draws the line. A tap only counts inside the attribution span; later taps are honoured but not counted.
- Sending stamps the cap. The last-nudged time and count are written on send, so the next order is paced, not just permitted.
- Close every offer. A sweep marks untapped offers ignored once their window shuts, so nothing is left uncounted.
- Pacing is arithmetic, not judgement. A fixed window and a count keep the whole thing auditable and impossible to drift.