Skip to content

Basket study 01

When baskets became social objects

Designing the basket as a permission contract.

The lift

Folklore said collab baskets do 3× the spend. The verified number was bigger: collab-basket creators generated 5.8× the tracked GMV of solo-only users (BigQuery all-time, n=185,813).

That settled one debate and opened a better one: was the lift the basket type, or a self-selecting cohort of already-engaged users adopting social features first?

So we checked it three ways – cross-sectional, cross-user, within-user. All three survive a selection-bias discount and point the same way. The design of social baskets is doing real work, not flattering a self-selected cohort.

The wrong frame

The obvious framing was how do we make sharing easier? – smoother share buttons, better copy, fewer taps. But that work only moves share-button taps, link-copied counts, and modal dismissals, none of which are the loop.

Four contracts, one primitive

Sharing a wishlist is a permission contract, not a UI control. The edge cases make that obvious: a gift basket has to hide purchase state from the giftee but show it to the gifters so they can coordinate the surprise; a collab basket shares structure rights with everyone; a public basket grants visibility but no contribution. Same primitive, four different contracts.

Get the contract wrong and the social signal collapses. Get it right and every save becomes a contribution to a shared object that compounds with use.

Measure the loop, not the tap

Share basket is a state of the basket primitive with its own permission matrix, not a UI affordance. So success isn’t the tap. It’s whether the loop closed: did the invitee survive the auth wall, save into the basket, and get attributed back to the social context. That last clause is the hidden work, and where the polyglot save schema (case study 02) meets this one. Every item_added event stamps the basket type, which is what made the cohort comparisons possible.

System design

Basket as a four-state primitive

  • Solo. Owner only. Private by default. The fallback state.
  • Public. Owner-edited, follower-visible, no contribution rights. Functions as publication.
  • Collaborative. All collaborators can add, structure, and edit items. Mark-purchased rights shared.
  • Gift. Giftee owns and structures the wishlist but never sees purchase state. Gifters coordinate purchase state with each other but cannot restructure.

Role × capability matrix

Design spec · not measured data

CapabilityOwnerGifteeGifterCollaboratorFollower
See items
See purchase state
Add items
Edit structure✓ (gift)✓ (collab)
Mark purchased
Invite othersdepends

The contract is small but the consequences are large. Every blocked capability in that matrix is deliberate, not an omission – each one protects the social signal.

Invite flow with preserved context

The shared link is a universal link with a basket payload. The chain:

  1. Sharer hits Share on a collab or gift basket. basket_shared_collab / basket_shared_gift fires.
  2. Invitee taps the link. share_link_opened fires.
  3. App opens. If the invitee is signed out, the sign-up screen renders with the social context already loaded: “Joining Amy’s birthday basket – sign up to add.” The basket name, the inviter, and the implied join action are all visible before any tap.
  4. Sign-up completes. The deferred payload routes the user directly into the basket, not the home screen.
  5. Invitee lands inside the basket. First save attributed to the social context.

In the PostHog 365-day window, 6,966 invitees survived the auth wall via the collab variant and 6,700 via the gift variant. These are cross-user acquisitions where the social context survived the sign-up screen.

Data signal

1. Cross-sectional cohort

The cleanest cut: every Basket user with ≥1 save, segmented by which basket types they have ever created.

£131.0×Solon=133,014£322.4×Publicn=26,356£765.8×Collabn=13,877£604.6×Giftn=10,838£18614.3×Bothn=1,728
Avg tracked GMV per user. BigQuery all-time, n=185,813. Item-price scrapes capped at £10K to filter outliers.

Retention tracks the same gradient: 90-day-active runs 8.0%, 9.1%, 18.7%, 36.7% from solo to both. The selection-bias critique is real, but it doesn’t survive the next two checks.

2. Cross-user – invitees vs non-invitees

Invitees didn’t pick the basket type. Someone else did. That weakens the “committed users adopt social features first” critique.

SegmentUsersTracked GMV90d active× baseline
Non-invitee175,938£239.4%1.0×
Invitee – gift only4,377£4914.8%2.1×
Invitee – collab only4,886£6017.5%2.6×
Invitee – both612£10324.5%4.5×

3. Within-user – before vs after

The same users, before and after their first social basket. The lift is smaller here than in the cross-section, which is the point: the within-user lens neutralises self-selection.

Purchases

Before0.71
After1.43

Retailer breadth

Before5.60
After14
2.4×

Active save days

Before6.3
After13
2.1×

Tracked GMV

Before£30
After£49
1.6×
Same users, two time windows. Lift survives selection-bias discount.

n=1,244 · pre ~210d / post ~380d · ≥1 save before first social basket

Why I think it worked

Three mechanisms, as hypotheses rather than measured results – only the occasion-intent one has a data shape behind it.

Social accountability turns saves into contributions. Once a basket has gifters or collaborators, every save is performed for an audience, and the cost of letting it die rises with the number of people watching.

Occasion-based intent compounds. Gift baskets cluster around events with deadlines – birthdays, weddings, holidays – which give gifters a time pressure they don’t get in a solo wishlist. That fits the retention gradient.

Permission contract preserves trust. The giftee never sees who bought what, so the surprise holds; gifters coordinate without restructuring, so no one overwrites anyone. Less ambiguity, less friction.

My role and caveats

I led the product-design work: basket types, the role × capability matrix, the invite-deep-link handoff, the basket-state transitions. I argued for the analytics property set because I knew I’d need to attribute behaviour back to social contexts. The deferred-deep-link flow is backend; I designed the sign-up screen that consumes the payload, not the link mechanics.

Caveats: selection bias is real for the cross-section, though the cross-user and before/after lenses both discount it. The 14.3× “both” figure has a small sample (n=1,728) – read it as the top of the funnel, not typical behaviour.

Outcome

23,215 Collaborative and 18,053 Gift baskets were created all-time. The basket-type schema feeds downstream recommendation, monetisation, and notification systems, so every save attributed to a social context compounds into future loops.

Strategically, this anchored the WNTD product bet on the social loop rather than on AI features or coupon automation – both of which had weaker behavioural signals in the same dataset.

What I’d do next

  • Build the exact invite-to-signup-to-first-action cross-user funnel. Current measurement uses deferred-link redirect counts (6,966 collab, 6,700 gift) as a proxy.
  • Add a claimed state to gift coordination. Right now gifters see purchase state. A claimed-but-not-yet-purchased state would cut double-purchases – a known qualitative pain that the telemetry didn’t surface.
  • Attribute purchases back to inviters. Adding the inviter ID as a property on the invitee’s purchase event closes the inviter → invitee → purchase loop.

Reflection – what I got wrong

Public baskets don’t compound the way collab and gift do. Public-only users land at 2.4× solo, but a fraction of what collab or both reach – “public” turned out to be publication, not a social loop. The owner sees followers as a number; followers get no role, can’t contribute, can’t coordinate. There’s no permission contract on the receiver side.

So I designed four basket states when I should have designed three. The next bet collapses public into a reader-role variant of collab: owner controls write-access, viewers get a contract instead of a count. Smaller surface, sharper differentiation, one fewer state to explain.