Integrate a quiz and survey platform
Learn how to integrate a quiz or survey platform with Klaviyo.
Overview
This resource will help you as you build an integration between a quiz or survey platform and Klaviyo. The core value of this category is zero-party data: quiz answers become Klaviyo profile properties the merchant uses for segmentation and personalization, and the email gate is a consent moment. This guide walks through the zero-party-data model, consent capture, the quiz events to send, the profile properties to sync, and the authentication and certification requirements, with an API quick reference at the end.
Why connect your quiz and survey platform to Klaviyo
A quiz is the one place a customer will tell a brand exactly what they want, in their own words, before they buy. Skin type, hair goal, fit preference, budget. That declared preference is data a merchant can't get any other way, and it's only valuable if it lands where they can act on it. The brands that get the most out of quizzes push every answer into the platform where they run every channel. When that platform is Klaviyo and the answers live on the profile, you get measurable wins:
- Personalize the welcome flow by answer. A quiz-taker who said "oily skin" enters a different flow path than one who said "dry," from the merchant's existing Klaviyo flows.
- Recommend the right products. The quiz result becomes a profile property that drives product-recommendation blocks in email and SMS.
- Segment on declared preference. "Skin Type is combination and hasn't purchased in 60 days" is a campaign audience the merchant couldn't build without the quiz.
- Recover abandoned quizzes. A started-but-not-finished quiz is a re-engagement trigger.
- Stickier merchants. Zero-party data wired into segmentation and personalization is one of the strongest retention signals across the partner program.
Short version: quiz answers from your platform become Klaviyo profile properties the merchant can segment, personalize, and automate on from the same place they run every other channel.
The flow
One-way push, partner to Klaviyo, with two streams that usually fire together at quiz completion:
- Profile property writes for the answers themselves. This is the zero-party data, and the reason the integration exists.
- Event emission for the quiz moments. Quiz started, quiz completed, recommendation viewed. These trigger and filter flows.
Each profile is keyed by email first, captured at the quiz's email gate, with phone where the quiz collects an SMS opt-in. Use the respondent or session ID as a stored reference, but always identify by email first; it is not a merge key on its own.
On initial install, no historical backfill is needed for most use cases. If you backfill existing respondents' answers for immediate segmentation value, use the bulk profile import job.
The zero-party-data model
Quiz answers are the whole point, so model them for reach, not just storage. Each answer should land as a top-level custom profile property, not nested inside a blob like {"quiz_answers": {...}}. Klaviyo segmentation, flow filters, and personalization tags all operate on top-level property keys; a nested answer is effectively invisible to the merchant.
Stable names matter more here than anywhere. A merchant builds segments ("Skin Type is Oily"), flow splits, and email personalization ({{ person|lookup:'Skin Type' }}) directly against the property name. If you rename or restructure the property later, every segment, flow, and template that references it silently stops matching.
Use two naming tiers, and don't conflate them:
- Answer properties: clean, merchant-facing names, no platform prefix. "Skin Type", "Hair Goal", "Fit Preference". These describe the customer, not your tool, and they should read naturally in the segment builder. Where a question maps to a well-known property (for example, birthday), prefer that name so it's reusable across other integrations on the same profile. Where you can, let the merchant map each question to a property name in your settings UI, since two merchants running the same quiz may want different names.
- Integration meta properties: prefixed with {Platform}. "{Platform} Last Quiz", "{Platform} Quiz Completed At". These describe the integration's behavior, so namespace them.
Send multi-select answers as arrays ("Style Preferences": ["Boho", "Minimalist"]), not concatenated strings. Arrays support Klaviyo's "any of" and "all of" segment conditions; a joined string doesn't.
Consent capture
Quizzes usually gate the results screen behind an email, which is also the consent moment. Subscribe the respondent with explicit marketing consent at that step, rather than just creating a profile. A profile write alone is not consent.
- Server-side: Bulk Subscribe Profiles (
POST /api/profile-subscription-bulk-create-jobs/). - Client-side (a browser-embedded quiz widget, public API key only): Create Client Subscription.
This requires the subscriptions:write scope alongside profiles:write. Consent handling (double opt-in behavior, SMS specifics, disclosure language) works exactly as it does for a forms integration; see the forms and popups guide for the full treatment rather than reimplementing it here.
Events to send
Event names are not prefixed with your platform name. Branded events handle source attribution via your OAuth token. Use Title Case payload field names.
| Event | When it fires | Payload |
|---|---|---|
| Quiz Started | A respondent begins the quiz. | Quiz Name, Quiz ID |
| Question Answered | Each question is submitted (optional; high volume on long quizzes). | Question, Answer, Question Number |
| Quiz Completed | A respondent reaches the results screen. | Quiz Name, Quiz ID, Answers, Completion Time |
| Survey Submitted | A standalone survey is fully submitted. | Survey Name, Answers |
| Recommendation Viewed | The results or recommendation page renders. | Quiz Name, Recommended Products, Result Segment |
| Recommended Product Clicked | A respondent clicks a recommended product. | Product ID, Product Name, Position, Quiz Name |
| Quiz Abandoned | A respondent exits before completing. | Quiz Name, Last Question Reached |
Question Answered is optional. On long quizzes it generates a lot of events; most integrations send answers in bulk on Quiz Completed instead. Offer per-question events only if a merchant needs mid-quiz triggers.
$value guidance: quiz and survey events don't carry revenue. Don't set $value. If a quiz drives an immediate purchase, model that as the merchant's existing order event rather than attaching revenue to Quiz Completed.
How merchants use it
- Answer-branched welcome flow. Quiz Completed triggers a welcome flow that splits on "Hair Goal" or "Skin Type".
- Recommendation emails. The Recommended Products property populates product blocks in a follow-up.
- Preference segments. "Skin Type is combination" plus a behavioral condition becomes a campaign audience.
- Abandoned-quiz recovery. Quiz Abandoned triggers a nudge to come back and finish.
Profile properties to sync
A mix of prefixed integration meta and clean-named zero-party answers, as described in the zero-party-data model above.
| Property | Type | Notes |
|---|---|---|
| {Platform} Last Quiz | String | Name or ID of the most recently completed quiz (meta). |
| {Platform} Quiz Completed At | Datetime (ISO 8601 UTC) | Timestamp of last completion (meta). |
| {Platform} Quiz Count | Integer | Lifetime quizzes completed (meta). |
| Skin Type | String | Zero-party answer; clean name, no prefix. |
| Hair Goal | String | Zero-party answer. |
| Fit Preference | String | Zero-party answer. |
| Style Preferences | Array of strings | Zero-party, multi-select answer. |
| Recommended Products | Array of strings/IDs | Quiz result, used for personalization. |
Implementation notes:
- Profile property writes go through Update Profile (
PATCH /api/profiles/{id}/), or are written inline on Create Event (POST /api/events/). Inline on Quiz Completed is the right default. - Keep answer properties top-level and their names stable. Don't nest them and don't rename them.
- Keep dates in ISO 8601 (UTC). Klaviyo treats string-typed dates as strings, which silently breaks date-property segmentation.
Auth, scopes, and certification
Build as a public OAuth app for server-side calls. Private API keys are a non-starter for the marketplace. Start with the Create a public OAuth app guide. Client-side consent capture uses the public API key, as described in Consent capture.
Key OAuth specifics for quiz integrations:
- PKCE is required on the authorization code exchange (
code_verifiermust be included). - Access tokens are short-lived (1 hour). Refresh tokens are long-lived but rotate on every use. Persist the latest refresh token after every refresh call.
- Tokens are scoped per Klaviyo account. Merchants with multiple Klaviyo accounts install separately for each.
Scopes to request:
profiles:writeto write zero-party answers and meta properties.events:writeto emit quiz events.subscriptions:writeto capture consent at the email gate.profiles:readonly if you match an existing profile before write.lists:readonly if the merchant picks a target Klaviyo list in your UI.
Don't over-scope. Unused scopes get flagged in marketplace review. Branded metric badges happen automatically when events flow through the OAuth token.
Once functional, submit for App Marketplace review under the Quizzes & Surveys category. Plan for at least one round of feedback. The review covers OAuth, scopes, install and uninstall validation, consent handling, and that the integration delivers what your listing claims.
API quick reference
Concrete specs for AI coding assistants and engineers grounding on this doc. The narrative above is the why and the flow. This section is the what-to-actually-type.
Headers (required on every request)
Authorization: Bearer <oauth_access_token>
revision: 2026-04-15
Accept: application/json
Content-Type: application/json
Pin the revision header to a specific date when you ship. Check the API versioning guide for the current latest. Without it you'll get a 400.
Event POST body (quiz completed with answers)
Fire Quiz Completed and write the zero-party answers to the profile inline. Identify by email first.
POST /api/events/
{
"data": {
"type": "event",
"attributes": {
"properties": {
"Quiz Name": "Find Your Routine",
"Quiz ID": "quiz_204",
"Answers": {
"Skin Type": "Oily",
"Concern": "Breakouts"
},
"Completion Time": 74
},
"time": "2026-06-17T14:22:11Z",
"unique_id": "quiz_204-6a2f10",
"metric": {
"data": {
"type": "metric",
"attributes": { "name": "Quiz Completed" }
}
},
"profile": {
"data": {
"type": "profile",
"attributes": {
"email": "[email protected]",
"properties": {
"Skin Type": "Oily",
"Style Preferences": ["Fragrance-Free", "Vegan"],
"Recommended Products": ["prod_881", "prod_902"],
"{Platform} Last Quiz": "Find Your Routine",
"{Platform} Quiz Completed At": "2026-06-17T14:22:11Z"
}
}
}
}
}
}
}
Include time (when the event occurred, ISO 8601) and unique_id (a stable identifier for the event, such as your quiz ID plus a session ID) on every event. Klaviyo uses unique_id to deduplicate.
Answer properties are top-level on the profile (segmentable and usable in personalization); the copy inside the event Answers object is for reporting on the event itself.
Retries
- 429: respect the
Retry-Afterheader. Otherwise exponential backoff starting at 1s, cap at 60s, max 5 retries. - 5xx: same backoff.
- 4xx (other than 429): don't retry. Log and surface to the merchant.
Identifier guidance
- Identify by email first, captured at the quiz email gate; phone where the quiz collects an SMS opt-in.
external_id(respondent or session ID) is NOT a merge key on its own. Pass it alongside email and store it as a property.- Capture consent explicitly at the email gate; a
PATCH /api/profiles/write is not consent.
Rate limits
Per-account, not per-app. Standard limits handle typical quiz volume. If you emit per-question events on long quizzes, watch volume and prefer batching to completion. For install-time backfill of existing respondents, use Bulk Import Profiles. Request per-account increases through Klaviyo Support and CSM before launch if a merchant is at unusual scale.
Glossary
- Klaviyo profile: customer record. Keyed by email, phone, or external ID.
- Klaviyo metric: event type. "Quiz Completed," "Recommendation Viewed," etc. Created automatically on first event ingest.
- Klaviyo segment: dynamic audience computed from rules. The merchant builds these from zero-party answer properties.
- Klaviyo flow: automated journey, triggered by a metric or segment membership. Where answer-branched welcome flows live.
- Zero-party data: information a customer intentionally and proactively shares, like a quiz answer. Distinct from behavioral (first-party) data.
- Email gate: the step where a quiz asks for an email before showing results; also the consent moment.
- Personalization tag: a Klaviyo template token (for example
{{ person|lookup:'Skin Type' }}) that renders a profile property into a message. Only works on top-level properties.
Resources
- Klaviyo Developer Portal. Start here for everything.
- Create a public OAuth app
- Integrate a forms and popups platform (for full consent-capture guidance)
- Create Event / Update Profile / Bulk Import Profiles
- Bulk Subscribe Profiles / Create Client Subscription
- Klaviyo App Marketplace, Quizzes & Surveys category. The existing set of quiz and survey integrations.
- App Marketplace Review: [email protected]
Updated about 2 hours ago