Co-founded product · Quiz funnel with a subscription
A five-language quiz funnel, from the first click to the subscription
A consumer product I launched with partners: paid traffic enters a nineteen-screen quiz and leaves as a paid subscription. Everything in between is my design and my code, built for conversion: the quiz engine, the paywall, billing, report generation, three analytics layers and five language versions. The brand and the revenue stay with the partners. The engineering is shown in full.
- Quiz funnel
- Subscription
- Server-side events
- 5 languages
- PostgreSQL
Entry
A full landing page for organic traffic, a short pre-lander for ads.
Session from the first click
Every answer reaches the server at once, with the campaign and the device.
Quiz, 19 screens
From easy one-tap questions to the birth date and personal data.
Partial reveal
A real summary, a blurred image, four teasers. The paid text stays on the server.
Paywall, three tiers
A symbolic entry week, a highlighted middle tier, no timer.
Trial week
Four portions of value in seven days. The reason not to cancel.
- Role
- Co-founder. Product, architecture and all of the development. I assembled the team around the project, traffic included.
- Period
- Launched in 2024, running since
- Product
- A personalized report of text and image, sold behind a quiz and billed as a subscription.
- Platform
- Custom web stack: pre-rendered pages, PostgreSQL, the payment provider and the pixels behind swappable interfaces.
- Languages
- English, Spanish, German, Romanian, Polish. Each language has its own address.
- Status
- In production end to end: the funnel, billing, report generation, the drip week, analytics and localization. Taking paid traffic in five markets.
- What stays private
- The brand, the niche and the revenue: they belong to the partners. The architecture and the decisions are shown in full. Screens, figures and the live funnel I show on a call.
Why the funnel is built this way
The image sells the entry, the text report delivers the value, a subscription with a low-priced first week collects the money.
I did not invent this combination at a desk. Before writing code I took two working competitors apart screen by screen and looked at about ten products through the Meta Ad Library. The picture formed quickly. An image earns a cheap click because it poses a concrete visual question the visitor wants answered.
Selling the image alone as a one-off does not pay: one payment, no repeats, and the most fragile category for acquiring. A bare subscription does not hold either, because nothing justifies the second week. The working middle turned out to be this: the image opens the door, the person pays for a subscription, and the value of the first week arrives in portions. Those portions do the job a mobile app usually does.
Three roles, one system
- Hook
- The image: a cheap click and a concrete promise
- Product
- A personalized text report in three sections
- Till
- A subscription with a symbolic first week, delivered in portions
The user path
No screen is where it is by accident. This is what a person sees from the click on the ad to the moment they reach for a card.
Two entry points
Organic traffic and platform moderation land on the full page. Ads go to a short pre-lander: first screen, proof, button. The strongest of the competitors I studied does the same, and for a reason: ad traffic does not need a long landing page, it needs the first question.
A session is born on the first click
Not on the email step and not at the end. The id lives in the address and in a cookie, and every answer reaches the server the moment it is chosen. An abandoned funnel is not lost: I can see that a person answered seven questions and left on the eighth, from which campaign and on which device. Competitors keep quiz state in the browser only, so that data does not exist for them.
Nineteen screens, twelve questions
Only the questions count toward the progress bar. The order is a staircase: two neutral one-tap questions on large cards, a trust screen, preferences, the birth date as the point of investment, the pain, a projection of the future. I ask for personal data only after four easy yeses.
The pause before the offer
Between the last answer and the result sits a loader with three progress bars, each labelled with a real stage of the computation. It is not decoration: the pause builds the expectation the result then lands in.
The moment of the result
Instead of a blank wall the person sees a real heading with their data, a real summary, a blurred image and four teaser cards. The paid text is never sent to the client, and the sketch under the blur is deliberately unfinished. You can strip the CSS filter in developer tools; there is nothing to see. Both competitors give their paid text away from the DOM in ten seconds.
The sum of this part: the funnel knows more about each person than they know about it, and the paid content exists nowhere except on the server.
The paywall and the trial week
Three tiers, the middle one highlighted. Every element here works for conversion; the chargeback risk is handled by the payment provider's tooling.
Tiers
Entry
A symbolic price for seven days
Full price struck through
Week
HighlightedMid price, the main choice
Full price struck through
Month
Best price per unit
Full price struck through
Anchor, middle tier and guarantee
The struck-through full price sets the anchor, the highlighted middle tier becomes the default choice, and the money-back guarantee removes the last objection. The auto-renewal terms sit above the button, short and next to the guarantee: platforms and the provider require it, and presented this way it does not slow the purchase.
Real urgency instead of a timer
There is no fake countdown. The urgency here is real and it is paid for: the generation queue and the speed-up for a fee. That converts better than a timer and raises no questions at moderation.
The upsell at peak desire
The report takes twenty minutes to prepare. For a small extra fee the queue drops to three. It costs nothing to deliver and sells readily: the person has just paid, the desire is at its peak, and they want the result now.
A week in portions
Day one brings the image; days two, three and five bring the remaining sections of the report, each as an email and a separate page. This is the substitute for an app: the person has a reason not to cancel on day three.
What works for conversion here
The engineering in this case serves the sale. Below are the techniques that move a person from the ad to the payment and on to the second week, and why each one sits where it does.
- 01
The first question instead of a landing page
Ad traffic lands on the pre-lander and is answering within one screen. The shorter the path from click to first action, the cheaper every step after it.
- 02
Two easy yeses up front
The first questions are neutral, on large cards, one tap each. The person joins the dialogue before anything is asked of them.
- 03
The birth date as the point of investment
By this step the person has answered several questions and has something invested. After the point of investment far fewer people leave, so the pain and the personal data come only after it.
- 04
A pause that sells the result
A loader with labelled stages of the computation turns waiting into value: the person sees something being computed for them, and the result feels worth more.
- 05
The curiosity gap
A partial reveal with a real heading, a real summary and a blurred image. The answer is almost visible, and that is stronger than any promise on a landing page.
- 06
A symbolic entry price
The decision about the first payment is small, so it is made quickly. From there the subscription and the portioned delivery do the work.
- 07
Anchor, middle tier, guarantee
Three tiers with the middle one highlighted and the full price struck through steer the choice; the guarantee removes the last doubt.
- 08
Real urgency
Not a timer but a generation queue with a paid speed-up. Urgency the person is willing to pay for converts and earns at the same time.
- 09
The second week as a separate sale
Portioned delivery gives a reason not to cancel. Retention here is the conversion of the second payment.
- 10
Per-step analytics as a sales tool
When you can see which of the nineteen screens is leaking, that is what gets fixed: the creative, the question or the offer. Recovered abandoned sessions show exactly where.
Payments and acquiring
The payment layer is hidden behind an interface, and the provider can be replaced without touching the funnel. Above all: the client never decides what it pays.
The price is computed on the server
The amount and the composition of the order are always resolved on the server from the offer id. The only thing that arrives from the browser is that id. Any price coming from the client is ignored by definition.
The payment flow
An invoice is created at the provider, then a redirect or an embedded form. The result comes back by webhook with a signature check, I reconcile the status with a separate request, and a redelivered webhook is handled idempotently. Full card data never passes through our perimeter.
Acquiring for a high-risk category
The category is high risk, so acquiring was arranged in parallel with development and a second provider is on standby. The provider's chargeback-reduction systems are switched on, and the payment loop is complete: payment, auto-renewal, guarantee refunds and one-click cancellation.
Report generation
The job is queued at the moment of payment, not when a button is pressed. Three parallel tasks run from one set of answers.
Text
The language model receives a structured profile rather than raw answers: fields derived from the birth date, the named qualities, the type of connection, the named difficulty. The output is three fixed sections, always the same shape.
Image
The image model receives an appearance description assembled from the answers and derived fields. The result passes through post-processing into one visual style, so two reports never look like two different products.
Assembly
Text and image are folded into an email and a personal page, and the same assembly feeds the portioned delivery across the week.
The time ceiling is explicit. If generation does not finish in time, the person gets what is ready and the missing part follows. The response shape is fixed, so a model can be swapped without a single change in the interface.
Three analytics layers
Ad platforms, blockers and Safari lose events. I start from that and rely on no single layer: each has its own job, and none depends on the others.
First-party, our own
Every event lands in our own database with the session id, the step, the step index, the time and full attribution: all five UTM tags, referrer, landing variant, quiz variant, language, device type. This layer depends on no blocker and no platform, and it is the one the unit economics are computed from.
Browser pixels
Providers sit behind one interface, ids live in environment variables, none is hardcoded. A provider without an id does not load and does not touch the network.
Server-side events
Meta Conversions API and TikTok Events API. The event leaves the server the moment the fact is written to the database, not when the browser happens to fire.
Platforms
- Meta PixelPrimary paid channel
- TikTok PixelSecond channel
- Google Ads / GA4Remarketing and end-to-end analytics
- PostHogProduct analytics, per-step funnel, session recordings
Deduplication is mandatory: the browser event and the server event carry the same event_id, and the platform merges them into one. Without it conversions count twice and campaigns learn on inflated numbers.
The server layer closes the hole left by blockers and iOS, but the bigger point is different: it carries events that never exist in the browser at all. A confirmed payment arrives as a webhook from the provider, not from a page, and the platform learns about it exactly when I do.
An event on each of the nineteen screens gives a funnel by step, not one conversion figure. When the first transition drops, the problem is the hook and the creative. When the second drops, the questions turned personal too early. When the second-to-last drops, the problem is the offer, not the quiz. Telling these apart matters, because without this kind of analytics the wrong thing usually gets fixed.
Event map
| Funnel step | Own event | Standard Meta event |
|---|---|---|
| Landing view | landing_view | PageView |
| Quiz started | quiz_started | ViewContent |
| Each step | step_view | custom |
| Answer | quiz_answered | custom |
| Back navigation | step_back | custom |
| Quiz completed | quiz_completed | custom |
| email_submitted | Lead | |
| Paywall view | buybox_view | ViewContent |
| Checkout started | checkout_started | InitiateCheckout |
| Payment | payment_success | Purchase |
| Subscription | subscription_created | Subscribe |
The quiz engine
Not a line of content lives in code. The engine is reusable, the offer is configuration, and a second product on the same engine needs no schema rewrite.
Content lives in JSON
Texts, questions, options, images, branching and the legal documents. Changing a wording needs neither a build nor a deploy.
Screens through a registry
The step type selects its component through a registry. A new type of screen is one component and one line in the registry.
Namespaced answers
Common fields and the fields of a specific offer are separated up front. A second offer is added beside the first, not on top of it.
The server assembles the answer tree
It is rebuilt from the answers table, never accepted as a snapshot from the client. A corrupted or forged snapshot from the browser cannot damage the state.
Personalization without code
Three declarative mechanisms. Mirrors substitute an earlier answer into the text. Branching changes the content of a screen without changing the step index, so direct links keep working and the analytics stay aligned. Option sets swap the list of answers depending on an earlier choice.
Five languages as a system
English, Spanish, German, Romanian and Polish: twenty-five pre-rendered pages. Localization here is not a translation file. It is part of the architecture.
One language, one address
The language is always in the URL. Nothing is guessed at render time.
Detection by priority
An explicit choice in the cookie, then Accept-Language, then geo, then English. The browser header outranks geolocation on purpose: an IP says where the device is, not what language the person reads.
Paid traffic skips detection
The Spanish campaign lands on /es, the German one on /de. Accuracy is total, there is no delay, and moderation sees a language that matches the ad.
An explicit address is never redirected
Every redirect is temporary: a permanent one gets cached by the browser and locks the person into one language for good.
Everything is translated, not only what is visible
Mirror branches, consent texts, field labels, image alt texts, meta descriptions. Month names come from the system locale, numbers follow local formats, and the Slavic cases are handled with separate forms for different positions in a sentence.
Legal layer and storage
Consent as a fact in the database
The first quiz step carries a mandatory checkbox: until it is ticked, the answer options do not react. The consent is written to the database with the session id, the time and the attribution. In a dispute with the acquirer that is the direct answer to who agreed, when and from where.
Terms and policy from configuration
Both documents render from configuration, with company details substituted from one place. The policy states plainly that text and image are generated automatically, that the result is not unique, the retention period, the data-subject rights, the cancel button and the auto-renewal. Competitors ignore this. In Europe it is no longer a detail.
One interface to the database
No route handler writes SQL; all database access goes through one interface. Implementations are swappable: local and production PostgreSQL are chosen by connection string. The schema is created on the first request, so there are no migrations to run.
Research before building
Before writing code I took two working competitors apart screen by screen and analyzed about ten products through the Meta Ad Library: active creatives, launch dates, geographies, destination domains.
The research gave more than the funnel structure. Two of the brands turned out to be one operator: byte-identical terms of service, one legal entity, one stack. A third advertises under page names that do not match its brand and cannot be found in the library by brand name at all. And their technical weaknesses became my list of what not to do.
What I deliberately did not repeat
- Quiz state kept only in the browser
- Questions compiled into the bundle
- Paid text in the DOM under a blur
- Pixels firing without consent
- A wait with no explanation
What I measure
The analytics are built around seven transitions. Each answers its own question, which is why a problem in the funnel shows up in minutes rather than a week.
| Transition | What it tells me |
|---|---|
| Landing → first answer | The hook and the creative |
| First answer → birth date | Whether the questions turned personal too early |
| Birth date → end of quiz | The escalation staircase |
| End of quiz → email | Trust at the moment data is requested |
| Email → paywall | The strength of the partial reveal |
| Paywall → checkout started | The offer: the product's main metric |
| Payment → cancellation within 7 days | Delivery of value across the week |
The figures behind these transitions, like the revenue, stay with the partners. On a call I will walk through the funnel step by step.
What this case shows
The platform differs from the Shopify work. The thinking is the same, and here it runs the whole way: from research and the offer to the till and retention.
A quiz funnel in one pair of hands
From the pre-lander and the order of the questions to the partial reveal and the paywall.
The commercial model, not only the markup
The tiers, the trial week, the upsell and the reasons behind each decision were designed by me, not received in a brief.
Tracking with no blind spots
First-party events, browser pixels and server-side events with deduplication, per step, through payment.
Five markets from one codebase
Addresses, language detection, ad routing and grammar solved as a system.
A team assembled for the job
Traffic and the surrounding roles I hired and ran myself. The development is mine in full.
On Shopify the same funnel is assembled from a quiz section or app, Selling Plans for the subscription, a Web Pixel for checkout events and the same server-side layer behind them. The platform changes the parts. The thinking does not change.
Stack
Front end
- Pre-rendered pages, one URL per language
- Config-driven quiz engine
- Component registry per screen type
Data
- PostgreSQL
- Single storage interface
- Server-side session and answer tree
Payments
- Provider behind an interface
- Signed webhooks
- Idempotent order handling
Analytics
- First-party event store
- Meta Pixel + Conversions API
- TikTok Pixel + Events API
- GA4 and Google Ads
- PostHog
Generation
- Language model for the report
- Image model for the visual
- Queue with a time ceiling
Ownership
Product decisions were made together with the partners. The architecture, the funnel design, the engine, the analytics, the localization and all of the code are mine, as is the research before the start.
Previous case
Boxwood Coffee
A Prestige adaptation for a specialty roaster: knowing what not to rebuild.
Hand over the storefront. Consider it handled.
Send the task and the goal. From there I read the code, take the work through release and verify it myself.
Start a conversation