Skip to content

How to Build Post-Quiz Email Flows in Klaviyo

Most merchants stop at the results email: the quiz finishes, Klaviyo sends the recommendation, done. That email is worth building, but it captures only the first session. The bigger opportunity is everything that happens after.

Your quiz collects zero-party data that no pixel or purchase history can match: the customer told you their skin type, their main concern, their goal, their budget. Every one of those answers lands on a Klaviyo profile the moment the quiz ends. Each answer becomes a segment filter. Each filter becomes a personalized flow. And each flow becomes a revenue moment timed to what the customer actually does next.

This is the difference between using your quiz as a conversion tool and using it as retention infrastructure. Across the RevenueHunt platform, 1 in 5 quiz-attributed orders lands more than 30 days after the quiz, and segmented Klaviyo sends earn roughly 3x the revenue per recipient of generic ones. The flows in this guide are how you capture that long tail.

You need two connections to Klaviyo, not one

These flows combine two data sources inside Klaviyo:

  1. RevenueHunt → Klaviyo sends the quiz data: answers, customer tags, recommended products. This is what you segment and personalize on.
  2. Your store → Klaviyo sends the behavioral events: Started Checkout, Placed Order, Viewed Product. This is what triggers the cart, browse, replenishment and cross-sell flows.

Both must be connected. The results-delivery and win-back flows only need connection 1. The four behavior-triggered flows need connection 2 as well. Connection 2 is set up in Klaviyo using your platform's native integration (see the prerequisites for your platform below).

Prerequisites

  1. Your quiz has an email question and you connected RevenueHunt to Klaviyo via OAuth with Send Quiz Leads to Klaviyo Profiles enabled.
  2. You have tagged your quiz answers so answers arrive on the profile as customer tags.
  3. Your Shopify store is connected to Klaviyo through Klaviyo's native Shopify integration, so events like Started Checkout, Placed Order and Viewed Product reach Klaviyo. Without this the four behavior-triggered flows have nothing to trigger on.
  1. Your quiz has an email question and you connected RevenueHunt to Klaviyo with your Public API Key (and a Private API Key if you also add contacts to a list).
  2. You have tagged your quiz answers.
  3. Your Shopify store is connected to Klaviyo through Klaviyo's native Shopify integration, so Started Checkout, Placed Order and Viewed Product events reach Klaviyo.

Legacy quizzes send different property names

A legacy Shopify quiz sends the older Klaviyo property format (PERMALINK, Q-, SLOT-, T-), which changes the segment, trigger filters and personalization tokens below. Consider migrating to Built for Shopify for the modern property set and one-click OAuth.

  1. Your quiz has an email question and you connected RevenueHunt to Klaviyo with your Public API Key (and a Private API Key for lists).
  2. You have tagged your quiz answers.
  3. Your WooCommerce store is connected to Klaviyo through Klaviyo's WooCommerce integration (the Klaviyo plugin), so Started Checkout, Placed Order and Viewed Product events reach Klaviyo.
  1. Your quiz has an email question and you connected RevenueHunt to Klaviyo with your Public API Key (and a Private API Key for lists).
  2. You have tagged your quiz answers.
  3. Your Magento (Adobe Commerce) store is connected to Klaviyo through Klaviyo's Magento extension, so Started Checkout, Placed Order and Viewed Product events reach Klaviyo.
  1. Your quiz has an email question and you connected RevenueHunt to Klaviyo with your Public API Key (and a Private API Key for lists).
  2. You have tagged your quiz answers.
  3. Your BigCommerce store is connected to Klaviyo through Klaviyo's BigCommerce integration, so Started Checkout, Placed Order and Viewed Product events reach Klaviyo.
  1. Your quiz has an email question and you connected RevenueHunt to Klaviyo with your Public API Key (and a Private API Key for lists).
  2. You have tagged your quiz answers.

No native store events on Standalone

A standalone quiz has no ecommerce platform feeding purchase and cart events into Klaviyo. Unless you push those events yourself through Klaviyo's Track API, the four behavior-triggered flows (cart, browse, replenishment, cross-sell) will not have events to fire on. On Standalone, focus on the results-delivery and win-back flows, which only need the RevenueHunt sync.

New to Klaviyo automations? Read Klaviyo's Getting started with flows first.

The architecture: one universal email, then five behavior-triggered flows

Every quiz needs one universal email: the results delivery, sent the moment the quiz finishes. On top of that sit five flows that fire based on what the customer does next. You don't need all six on day one. Build the results email first, then add the flows your category leans on hardest (see the industry table below).

Flow Klaviyo trigger When it fires Needs store→Klaviyo?
Results delivery Added to segment (or list) Immediately No
Cart abandonment Metric: Started Checkout 1-4h, 24h, 72h Yes
Browse abandonment Metric: Viewed Product 4h, optional +3 days Yes
Replenishment Metric: Placed Order N days before run-out Yes
Cross-sell Metric: Placed Order 7-14 days after Yes
Win-back Added to segment 60-120 days inactive No

The important idea: the setup is shared, the trigger is what diverges. Every flow reads the same quiz-derived properties. What changes from one flow to the next is the Klaviyo trigger (a segment, a checkout event, an order) and the timing.

Set this up once (shared foundation)

These steps are the same no matter which flows you build.

Know what the quiz sends

Every completion writes a set of custom properties to the Klaviyo profile. You reference these in segment definitions, conditional splits and email templates. The exact names include your quiz ID, so they are unique to your quiz.

Your quiz sends these custom properties:

  • ANSWER_BY_BLOCK-<blockRef>-<QuizID>: the answer to one question. Overwritten on each retake.
  • ANSWERS_BY_BLOCK-<QuizID>: present on every quiz taker. This is the property you use to detect quiz takers.
  • TAGS-<QuizID>: the customer tags from your quiz logic. Your main segmentation lever.
  • RECOMMENDATIONS_BY_SLOT-<QuizID>: recommended products (title, price, image, URL). JSON object, appended on each retake.
  • RESPONSE_ID-<QuizID>: the unique response ID. Use it to link back to the results page.
  • QUIZ_NAME-<QuizID>: the quiz name. Handy in subject lines.

Your quiz sends these custom properties:

  • PERMALINK-<QuizID>: present on every quiz taker. This is the property you use to detect quiz takers.
  • Q-<QuizID> <blockId>: <question text>: the answer to one question.
  • SLOT-<QuizID>: <slot name> - product_<n>_<field>: a recommended product's field (name, price, sku, url, image_url), where <n> starts at 0.
  • T-<QuizID>: <tag>: a customer tag. Present on the profile when that tag was applied.

Your quiz sends these custom properties:

  • PERMALINK-<QuizID>: present on every quiz taker. Use it to detect quiz takers.
  • Q-<QuizID> <blockId>: <question text>: the answer to one question.
  • SLOT-<QuizID>: <slot name> - product_<n>_<field>: a recommended product's field (name, price, sku, url, image_url), <n> starts at 0.
  • T-<QuizID>: <tag>: a customer tag, present when applied.

Your quiz sends these custom properties:

  • PERMALINK-<QuizID>: present on every quiz taker. Use it to detect quiz takers.
  • Q-<QuizID> <blockId>: <question text>: the answer to one question.
  • SLOT-<QuizID>: <slot name> - product_<n>_<field>: a recommended product's field (name, price, sku, url, image_url), <n> starts at 0.
  • T-<QuizID>: <tag>: a customer tag, present when applied.

Your quiz sends these custom properties:

  • PERMALINK-<QuizID>: present on every quiz taker. Use it to detect quiz takers.
  • Q-<QuizID> <blockId>: <question text>: the answer to one question.
  • SLOT-<QuizID>: <slot name> - product_<n>_<field>: a recommended product's field (name, price, sku, url, image_url), <n> starts at 0.
  • T-<QuizID>: <tag>: a customer tag, present when applied.

Your quiz sends these custom properties:

  • PERMALINK-<QuizID>: present on every quiz taker. Use it to detect quiz takers.
  • Q-<QuizID> <blockId>: <question text>: the answer to one question.
  • SLOT-<QuizID>: <slot name> - product_<n>_<field>: a recommended product's field (name, price, sku, url, image_url), <n> starts at 0.
  • T-<QuizID>: <tag>: a customer tag, present when applied.

Find your exact property names on a test profile

Take a test quiz with a sample email, then open Klaviyo > Audience > Profiles and search for it. The profile shows every property your quiz sends, with the exact block references, slot names and quiz ID. Copy the names from there. See Use Quiz Data in Klaviyo Email Templates for the full reference and the {{ person|lookup:'...' }} syntax.

Create your "Quiz Takers" segment

This segment is the backbone. It defines everyone who finished the quiz, and you use it both as a trigger (results delivery, win-back) and as a filter inside behavior-triggered flows.

  1. In Klaviyo go to Audience > Lists & Segments and click Create New > Segment.
  2. Set the definition to Properties about someone, choose ANSWERS_BY_BLOCK-<QuizID>, and set the condition to is set.
  3. Save. New quiz takers join automatically.

Segment on a specific answer or tag

To target a slice of quiz takers rather than all of them, filter on a specific value instead, for example TAGS-<QuizID> contains Color-Treated, or ANSWER_BY_BLOCK-<blockRef>-<QuizID> equals Oily. This is how you build audience-specific versions of any flow below.

  1. In Klaviyo go to Audience > Lists & Segments and click Create New > Segment.
  2. Set the definition to Properties about someone, choose PERMALINK-<QuizID>, and set the condition to is set.
  3. Save. New quiz takers join automatically.

Segment on a specific answer or tag

To target a slice of quiz takers rather than all of them, filter on a specific value instead, for example T-<QuizID>: Color-Treated is set. This is how you build audience-specific versions of any flow below.

  1. In Klaviyo go to Audience > Lists & Segments and click Create New > Segment.
  2. Set the definition to Properties about someone, choose PERMALINK-<QuizID>, and set the condition to is set.
  3. Save. New quiz takers join automatically.

Segment on a specific answer or tag

To target a slice of quiz takers rather than all of them, filter on a specific value instead, for example T-<QuizID>: Color-Treated is set. This is how you build audience-specific versions of any flow below.

  1. In Klaviyo go to Audience > Lists & Segments and click Create New > Segment.
  2. Set the definition to Properties about someone, choose PERMALINK-<QuizID>, and set the condition to is set.
  3. Save. New quiz takers join automatically.

Segment on a specific answer or tag

To target a slice of quiz takers rather than all of them, filter on a specific value instead, for example T-<QuizID>: Color-Treated is set. This is how you build audience-specific versions of any flow below.

  1. In Klaviyo go to Audience > Lists & Segments and click Create New > Segment.
  2. Set the definition to Properties about someone, choose PERMALINK-<QuizID>, and set the condition to is set.
  3. Save. New quiz takers join automatically.

Segment on a specific answer or tag

To target a slice of quiz takers rather than all of them, filter on a specific value instead, for example T-<QuizID>: Color-Treated is set. This is how you build audience-specific versions of any flow below.

  1. In Klaviyo go to Audience > Lists & Segments and click Create New > Segment.
  2. Set the definition to Properties about someone, choose PERMALINK-<QuizID>, and set the condition to is set.
  3. Save. New quiz takers join automatically.

Segment on a specific answer or tag

To target a slice of quiz takers rather than all of them, filter on a specific value instead, for example T-<QuizID>: Color-Treated is set. This is how you build audience-specific versions of any flow below.

Learn the three controls you will reuse

Every flow below is built from three Klaviyo controls. They evaluate different data, so using the right one is what keeps a flow accurate.

  • Trigger filter is checked once, at entry, and evaluates only the triggering event's data (so it exists only on metric-triggered flows). Use it to narrow the event itself, for example only enter the replenishment flow when the ordered item is a specific product.
  • Flow filter (profile filter) is re-checked before every step and evaluates profile properties and past actions. Use it to keep a flow to quiz takers only (require your quiz-completion property to be set, the property flagged in Know what the quiz sends as present on every quiz taker) and to drop people who no longer qualify (has not Placed Order since starting the flow).
  • Conditional split branches the path based on a profile property, a past action, or list membership. Use it to send one profile down a personalized path and everyone else down another, from the same trigger.

Time delays behave differently with a set send-time

Back-to-back steps in Klaviyo fire at the same time, so you need explicit Time delay steps between emails. A plain delay counts in 24-hour blocks; a delay set to a specific time of day counts in calendar days. Keep this in mind when you schedule the 1h / 24h / 72h cadence.

The flows

Flows 2 to 5 need your store connected to Klaviyo

The cart, browse, replenishment and cross-sell flows trigger on Started Checkout, Viewed Product and Placed Order, which come from your store's native Klaviyo integration, not from RevenueHunt. Confirm connection 2 from the prerequisites is in place. On Standalone these events are not available by default.

1. Results delivery (universal)

Recommended for: every quiz, every industry. This is the one flow no store should skip.

The transactional email that confirms the quiz result within seconds. It delivers the recommendation and links straight back to the results page, where products add to cart in one click.

  • Trigger: Added to segment → your Quiz Takers segment. (If you route contacts to a Klaviyo list from the email question's list selector, you can trigger on the list instead.)
  • Reentry: allow a returning quiz taker to get a fresh result email on every completion. The exact reentry setup differs by platform, so follow the method in Send Email with Each Quiz Retake.
  • Personalize: pull the recommendation and link to the results page using the tokens in Personalizing every flow. Use an information recall style subject line: "Your [skin type] routine is ready."

RESULTS DELIVERY · UNIVERSAL TRIGGER Added to segment: Quiz Takers EMAIL · IMMEDIATE Deliver results + cart link Back to results page

This flow is covered end to end, including the downloadable HTML template, in Sending Follow-up Emails via Klaviyo. The rest of the flows below are what you build on top of it.

Turn off the app's built-in result email

Once this flow is live, deactivate the app's result email notifications so customers don't get two.

2. Cart abandonment (recommendation-aware)

Recommended for: Fashion, Cosmetics, and any store with a considered purchase. High value everywhere.

A quiz taker added a recommended product to cart but didn't check out. A generic "your cart is waiting" works; a quiz-aware version works better because it reframes the cart around why the product fits them.

  • Trigger: metric Started Checkout (from your store's Klaviyo integration; some integrations label it Checkout Started).
  • Make it quiz-aware, two options:
    • Dedicated flow: add a flow filter requiring your quiz-completion property is set, so only quiz takers stay in.
    • Branch an existing flow: if you already run a store-wide cart flow, add a Conditional split on your quiz-completion property is set. Quiz takers take the personalized (YES) path; everyone else keeps the standard copy. This avoids maintaining two flows.
  • Flow filter: has not Placed Order since starting the flow (zero times), so buyers stop receiving it.
  • Timing: three emails at roughly 1-4 hours, 24 hours, 72 hours.
  • Personalize: open with the quiz angle instead of the cart, for example "Based on your oily, breakout-prone profile, [Product X] is still your best match." Pair the 72-hour email with a discount to recover price-sensitive shoppers.

CART ABANDONMENT TRIGGER · METRIC Started Checkout FLOW FILTER Quiz taker · no order yet EMAIL · 1-4h Reference quiz answers EMAIL · 24h Reinforce the match EMAIL · 72h Add a discount Cart recovered

3. Browse abandonment (tag-conditional)

Recommended for: Fashion and catalog-heavy stores where shoppers browse a lot before buying.

A quiz taker viewed a recommended product but never added it to cart. Lighter touch than cart abandonment.

  • Trigger: metric Viewed Product (or Active on Site).
  • Flow filter: your quiz-completion property is set (only quiz takers), and has not Placed Order or Added to Cart since starting the flow.
  • Timing: one email at ~4 hours, an optional second at ~3 days.
  • Personalize: add a Conditional split on a customer tag from the quiz so a customer never gets a recommendation that contradicts a different quiz answer. Reference both the viewed product and the stated need: "You said you wanted lightweight coverage; here's a closer look at the matte finish."

BROWSE ABANDONMENT TRIGGER · METRIC Viewed Product FLOW FILTER Quiz taker · no cart/order CONDITIONAL SPLIT Split on customer tag EMAIL · 4h Tag-matched pick EMAIL · 4h Other tag pick Re-engaged

4. Replenishment (cycle-timed)

Recommended for: Skincare, Haircare, Supplements, Food & drink, Pets, and any consumable with a predictable run-out.

The single highest-leverage flow for consumables: bring the customer back right before they run out.

  • Trigger: metric Placed Order.
  • Trigger filter: the ordered item is the consumable product (or in a product tag/collection). This reads the order event, so it belongs in the trigger filter.
  • Flow filter: your quiz-completion property is set (only quiz takers), and has not Placed Order for that product again since starting the flow.
  • Timing: a Time delay of roughly the consumption cycle × 0.8, so you land before they run out. A 30-day product triggers the email around day 22-24; a 60-day supply around day 48-50.
  • Personalize: reference the product they bought and their quiz concern, for example "Ready to restock your [concern] routine before it runs out?" If your quiz asked about usage frequency, add a Conditional split on that answer to set different delays per profile.

REPLENISHMENT TRIGGER · METRIC Placed Order TRIGGER FILTER Ordered = consumable FLOW FILTER Quiz taker · no re-order Wait cycle × 0.8 EMAIL · BEFORE RUN-OUT Reorder your [concern] routine Repeat purchase

Use the quiz answer to time the delay

If the quiz captured "wash frequency" or "how often do you use this," split the flow on that answer property and give each branch its own delay. A daily user runs out faster than a weekly one, and the quiz already told you which they are.

5. Cross-sell / routine completion

Recommended for: Skincare and Haircare (routine and bundle categories). Skip it for Fashion, where a first purchase rarely implies a matching second.

After the first quiz-driven purchase, complete the routine. The customer who bought the cleanser for oily skin gets the matching serum and moisturizer for the same profile. It outperforms a generic bundle pitch because the recommendation comes from the customer's own answers.

  • Trigger: metric Placed Order.
  • Flow filter: your quiz-completion property is set (only quiz takers). Optionally exclude anyone who has already Ordered Product the item you're about to recommend.
  • Timing: a Time delay of 7-14 days.
  • Branch by tag: add a Conditional split on a customer tag to recommend the complementary product that matches their profile.

CROSS-SELL · ROUTINE COMPLETION TRIGGER · METRIC Placed Order FLOW FILTER Quiz taker · not already bought Wait 7-14 days CONDITIONAL SPLIT Split on customer tag EMAIL Matching product A EMAIL Matching product B AOV lift

6. Win-back (segment-conditional)

Recommended for: every industry. Only the timing shifts: ~60 days for impulse categories, ~120 for considered purchases.

Re-engage quiz takers who have gone quiet. The quiz tag is what makes a win-back feel personal instead of pleading.

  • Build the segment: combine two conditions:
    • Properties about someone → your quiz-completion property is set (they took the quiz), and
    • What someone has donePlaced Order zero times in the last 60-120 days (they've gone quiet).
  • Trigger: Added to segment → this inactive-quiz-takers segment.
  • Branch by tag: a Conditional split on a customer tag so a Curly + Dry profile and a Volume + Anti-Frizz profile get different copy.
  • Timing: one email on entry, a second ~14 days later with an incentive.

WIN-BACK TRIGGER · SEGMENT Inactive quiz takers (60-120d) CONDITIONAL SPLIT Split on customer tag EMAIL · ENTRY Re-engage, tag A EMAIL · ENTRY Re-engage, tag B EMAIL · +14 DAYS Incentive to return Won back

Which flows to build first, by industry

The architecture is universal; the cadence and priority shift by category. Start with the results email, then add the two flows your category leans on hardest. Layer the rest in as traffic grows.

Industry Build first (after results email) Why
Skincare Cross-sell + replenishment Routines and refills drive repeat revenue
Haircare Replenishment (6-8 week cycle) + cross-sell Products run out on a predictable cycle
Supplements & wellness Replenishment (30-day cycle) + win-back Add a subscription nudge to the replenishment email
Cosmetics & makeup Cart abandonment + seasonal cross-sell Faster decision, more cart drop-off
Fashion & apparel Cart abandonment + browse abandonment Impulse buying, skip cross-sell
Food & drink Replenishment + subscription nudge Predictable consumption
Pets Replenishment (food cycle) + cross-sell (accessories) Recurring food, adjacent products

The pattern: consumables lean on replenishment and cross-sell; impulse categories lean on cart and browse abandonment. Win-back matters everywhere.

Personalizing every flow with quiz data

Whatever the flow, the personalization comes from the same lookups inside an HTML block.

  • Answer: {{ person|lookup:'ANSWER_BY_BLOCK-<blockRef>-<QuizID>' }}
  • Recommended product: {{ person|lookup:'RECOMMENDATIONS_BY_SLOT-<QuizID>'|lookup:'<slot>'|lookup:'0'|lookup:'title' }} (swap title for description, price, onlineUrl, or image)
  • Link to their results: #response-{{ person|lookup:'RESPONSE_ID-<QuizID>' }}
  • Branch on a tag: in a Conditional split, TAGS-<QuizID> contains <tag>

Let Quiz Copilot build it

Paste any template into Quiz Copilot and ask it to restyle or trim the code for you, no developer required.

  • Answer: {{ person|lookup:'Q-<QuizID> <blockId>: <question text>'|default:'' }}
  • Recommended product: {{ person|lookup:'SLOT-<QuizID>: <slot name> - product_0_name'|default:'' }} (swap product_0_name for _price, _sku, _url, _image_url; the count starts at 0)
  • Branch on a tag: in a Conditional split, T-<QuizID>: <tag> is set, or in a template {% if person|lookup:'T-<QuizID>: <tag>' %}...{% endif %}
  • Answer: {{ person|lookup:'Q-<QuizID> <blockId>: <question text>'|default:'' }}
  • Recommended product: {{ person|lookup:'SLOT-<QuizID>: <slot name> - product_0_name'|default:'' }} (swap product_0_name for _price, _sku, _url, _image_url; the count starts at 0)
  • Branch on a tag: in a Conditional split, T-<QuizID>: <tag> is set, or in a template {% if person|lookup:'T-<QuizID>: <tag>' %}...{% endif %}
  • Answer: {{ person|lookup:'Q-<QuizID> <blockId>: <question text>'|default:'' }}
  • Recommended product: {{ person|lookup:'SLOT-<QuizID>: <slot name> - product_0_name'|default:'' }} (swap product_0_name for _price, _sku, _url, _image_url; the count starts at 0)
  • Branch on a tag: in a Conditional split, T-<QuizID>: <tag> is set, or in a template {% if person|lookup:'T-<QuizID>: <tag>' %}...{% endif %}
  • Answer: {{ person|lookup:'Q-<QuizID> <blockId>: <question text>'|default:'' }}
  • Recommended product: {{ person|lookup:'SLOT-<QuizID>: <slot name> - product_0_name'|default:'' }} (swap product_0_name for _price, _sku, _url, _image_url; the count starts at 0)
  • Branch on a tag: in a Conditional split, T-<QuizID>: <tag> is set, or in a template {% if person|lookup:'T-<QuizID>: <tag>' %}...{% endif %}
  • Answer: {{ person|lookup:'Q-<QuizID> <blockId>: <question text>'|default:'' }}
  • Recommended product: {{ person|lookup:'SLOT-<QuizID>: <slot name> - product_0_name'|default:'' }} (swap product_0_name for _price, _sku, _url, _image_url; the count starts at 0)
  • Branch on a tag: in a Conditional split, T-<QuizID>: <tag> is set, or in a template {% if person|lookup:'T-<QuizID>: <tag>' %}...{% endif %}

The full token reference, the downloadable Klaviyo template, and worked examples are in Use Quiz Data in Klaviyo Email Templates.

Common pitfalls

Watch for these

  • Two connections, not one. RevenueHunt supplies the quiz properties and tags; Started Checkout, Placed Order and Viewed Product come from your store platform's own connection to Klaviyo. Without both, flows 2 to 5 have nothing to trigger on. On Standalone, those events do not exist by default.
  • Confirm your exact property names. Take a test quiz and check the resulting Klaviyo profile for the exact property names before you build, since they include your quiz ID.
  • Set reentry deliberately. The results email should re-send on retakes; behavior-triggered flows usually should not, to avoid over-emailing.
  • Filter every behavior flow to quiz takers. Otherwise your personalized copy reaches people who never took the quiz and the lookup tokens render empty.
  • Lists must be Single Opt-in. Quiz contacts can only be added to a Single Opt-in Klaviyo list.
  • Special characters and delay. New profiles can take a few minutes to appear, and accented characters (è, é, ê) can interfere with data transmission.