Shopify App Growth
Shopify App Onboarding: How to Activate Merchants in the First 7 Days
2026 Shopify app benchmarks, three merchant-facing activation emails with CTA examples, and Klaviyo, HubSpot and Customer.io workflows.
By Albert Robescu ·

The install is not the outcome
A merchant installs your Shopify app after seeing its promise in the App Store. A day later, the app is still sitting in their admin, but the action that would make it useful has not happened. Your acquisition dashboard shows another install. Your product dashboard shows a merchant who has yet to experience the product.
That gap is the commercial problem. Every unactivated installation consumes acquisition effort without delivering the product's intended value. An onboarding sequence should change what the merchant does inside the app, not merely produce email opens.
Consider three categories. A review app becomes useful when a merchant publishes a widget and verifies that reviews are visible on a product page. A subscription app becomes useful when a selling plan is live and purchasable. An inventory app becomes useful when the first sync completes and the result is reliable. These are distinct first-value outcomes; none is the same as a trial signup, a paid subscription or a shopper purchase.
This guide builds one illustrative seven-day activation campaign for a fictional Shopify review app. It is written for the app provider's founder or lifecycle marketer. The emails go to the merchant using the app, not the shopper buying from that merchant. The strategy, examples and implementation are proposed; no customer results or production deployments are claimed.
Why the first days matter
Uninstall within 24 hours
30.71%
Average across connected apps
22.80% top quartile
Lower is betterInstall to trial / subscription
29.89%
Average across connected apps
49.96% top quartile
Higher is betterMonthly customer churn
8.95%
Average across connected apps
4.69% top quartile
Lower is betterApps in the Prys sample
400+
Connected Shopify apps
2026 cross-category benchmark sample
The takeaway: Merchants can abandon an app quickly. Prioritize a verified first-value action in the first seven days, not installation alone.
Source: Prys, Shopify App Benchmarks 2026. Cross-category connected-app sample, not a Shopify-wide census. Install-to-trial is not first-value activation; 24-hour uninstall and monthly churn are different measures. These figures do not establish email campaign impact.
Prys benchmarks cover more than 400 connected Shopify apps. The KPI cards compare early uninstall, install-to-trial conversion and monthly customer churn against top-quartile figures. These cross-category measures are not Shopify-wide population estimates, first-value activation rates or evidence that emails reduce uninstall.
The implication is practical: merchants can leave quickly, and installing is not the same as experiencing value. The first seven days give the app company an opportunity to make the next action obvious, show why it matters and remove barriers before an incomplete setup becomes an abandoned app.
For our review-app example, the primary goal is a storefront-visible review widget within seven days of installation. The app backend must verify that state. A saved configuration or email click does not count.
The strategy: value, demonstration, friction removal
The three sends deliberately solve different problems:
| Day | Merchant's likely obstacle | Message strategy | One primary action |
| 1 | Reviews are not a priority yet | Make the commercial case with credible research | Publish the widget |
| 3 | The merchant cannot picture the finished result | Show a specific sample layout and how to reproduce it | See the walkthrough, then apply it |
| 5 | Setup remains incomplete or blocked | Remove navigation and decision effort | Resume the exact incomplete step |
These are hypotheses, not diagnoses of individual merchants. Use `setup_status` and `setup_blocker` to refine the message where the app has reliable data. A merchant who already published the widget exits the sequence immediately.
The seven-day campaign
1.App installed; merchant/shop identity recorded
2.Treatment or holdout assigned
Next → Eligible for recovery emails?3.Eligible for recovery emails?
No → No emails; keep measurement cohortYes → Day 1: Is widget visible?4.No emails; keep measurement cohort
Next → Day 7: Measure first value5.Day 1: Is widget visible?
Yes → Exit recoveryNo → Email 1: Commercial value6.Exit recovery
Next → Day 7: Measure first value7.Email 1: Commercial value
Next → Day 3: Is widget visible?8.Day 3: Is widget visible?
Yes → Exit recoveryNo → Email 2: Example walkthrough9.Email 2: Example walkthrough
Next → Day 5: Is widget visible?10.Day 5: Is widget visible?
Yes → Exit recoveryNo → Email 3: Resume setup11.Email 3: Resume setup
Next → Day 7: Measure first value12.Day 7: Measure first value
All timing is measured from installation, not from the previous email being opened. Each send checks current app state and eligibility again. The holdout receives no recovery emails but remains in the same activation analysis.
Three merchant-facing emails, with the reasoning behind every decision
The following messages are sample copy for a fictional review app. The CTAs describe destinations the app company must build and verify before sending. They are not working links. No email requires a reply, meeting, consultation or human support.
Email 1 - Day 1: make review visibility worth doing
Segment and trigger: One day after `app_installed`, for a currently installed, eligible merchant whose `first_value_at` is still empty for this installation.
Subject: Your reviews can't build trust if shoppers can't see them Preheader: Make your customer reviews visible on your product pages.
Merchant email preview
Hi there,
Customer reviews can help shoppers feel more confident about buying.
Research from Northwestern University's Spiegel Research Center found that products with five reviews had a 270% greater purchase likelihood than products with no reviews in the study's comparison.
You've installed the review app. The next step is making your reviews visible where shoppers are deciding what to buy.
Follow the setup steps, then check that your widget appears on a product page.
CTA destination: Authenticated, shop-scoped widget publishing screen. Exit: Verified widget publication, uninstall or loss of sending eligibility. App KPI: Seven-day verified widget publication rate.
Why this email is written this way
| Copy decision | Strategic reasoning |
| Merchant obstacle | The merchant installed the app but may not have prioritized setup. We test a value hypothesis rather than assuming a technical problem. |
| Subject + preheader | The subject connects review visibility to trust; the preheader names the exact task. Neither promises an unverified uplift. |
| Opening | Starts with a merchant outcome rather than an app feature list. |
| Evidence | The Spiegel research supplies an external reason to care about visible reviews. The reported comparison is not a forecast for this merchant, proof of our app's performance or a guarantee that five reviews cause a 270% lift. Verify the research context before publishing. |
| CTA | “Publish” describes the measurable first-value action; a deep link removes dashboard navigation. |
| Timing + suppression | Day 1 after installation, only while the correct shop/installation remains unactivated and eligible. |
| A/B hypothesis | A research-led subject may produce more verified publications than a simple setup reminder. Randomize and compare activation, not opens. |
Research: Spiegel Research Center, *How Online Reviews Influence Sales*. The study examines purchase likelihood in a specific research context; it is not an app-level activation benchmark.
Email 2 - Day 3: demonstrate the finished result
Segment and trigger: Three days after installation, for eligible merchants who still have no verified storefront-visible widget.
Subject: See how reviews can look on your product pages Preheader: A product-page example you can use to finish setup.
Merchant email preview
Hi there,
Not sure where your reviews should appear?
Sample-store walkthrough: From installation to visible reviews
See a sample product page with star ratings near the product title and customer reviews below the description.
The walkthrough shows the finished layout, the steps to publish it and how to check that reviews are visible.
Use the example as a reference when publishing your own widget.
CTA destination: A clearly labeled illustrative walkthrough page showing a real rendered example and a prominent Apply this layout link back to the merchant's authenticated setup. The example must actually exist before sending. Exit: Activation, uninstall or loss of eligibility. App KPI: Verified activation after the second send, with demo-to-activation as a diagnostic metric.
Why this email is written this way
| Copy decision | Strategic reasoning |
| Merchant obstacle | A merchant who did not respond to a value-led message may be uncertain what the finished widget should look like. That is a hypothesis to test, not a known reason. |
| Subject + preheader | Promises a concrete visual example rather than another generic reminder. |
| Opening | Asks about placement, the specific uncertainty the demonstration resolves. |
| Evidence / social proof | The sample walkthrough shows how setup works but is not a customer success story. Replace it with a named, permissioned and independently verifiable case study if available; cite the original and do not invent conversion numbers or testimonials. |
| CTA | Leads to an actual example with a short path to apply it. Avoid an unrelated homepage or a video with no activation path. |
| Timing + suppression | Day 3, after rechecking the correct shop's state. Activated merchants do not receive it. |
| A/B hypothesis | A visual walkthrough may outperform a direct setup CTA for merchants who have started configuration but not published. Compare verified activation by setup-status segment. |
Email 3 - Day 5: remove the last source of friction
Segment and trigger: Five days after installation, for eligible merchants who still have not activated. If the app knows `setup_status` or `setup_blocker`, resolve the deep link to the appropriate next step; otherwise use the general setup checklist.
Subject (setup started): Pick up where you left off with your review widget Subject (setup not started): Finish setting up reviews on your store Preheader: Open your next setup step and check your widget before publishing.
Merchant email preview
Hi there,
Your review widget isn't visible on your store yet.
Open your setup checklist to see what remains. If you've already started, continue from your last saved step. You can preview the widget before publishing it.
Once the widget is visible on a product page, setup is complete.
CTA destination: Authenticated, shop-scoped resume/setup checklist. Route known blockers to the corresponding self-service instructions. Only say a step was saved if the app actually persisted it; only promise a preview if the product supports it. Exit: Activation, uninstall or loss of eligibility. App KPI: Verified activation by Day 7 and resume-to-publication completion.
Why this email is written this way
| Copy decision | Strategic reasoning |
| Merchant obstacle | After two unacted-on messages, navigation effort or a setup blocker may be the constraint. We remove friction instead of repeating commercial persuasion. |
| Subject + preheader | State-specific subject avoids falsely telling an untouched installer that setup is almost complete. The preheader describes the self-service path. |
| Opening | Uses verified app state: widget not visible. It avoids guilt, urgency theater and unsupported claims about prepared reviews. |
| Evidence | No new generic statistic is needed; the proof is a clear, accurate progress state and a preview of the result if available. |
| CTA | “Continue my setup” leads directly to the unfinished step. No reply, human intervention, booking or manual diagnosis. |
| Timing + suppression | Day 5, with a fresh activation and eligibility check immediately before sending. |
| A/B hypothesis | Blocker-specific self-service deep links may outperform a generic checklist among merchants with a recorded `setup_blocker`. Measure publication, not just click-through. |
Why the sequence works as a testable strategy: Day 1 sells the *reason* to act, Day 3 shows the *result*, and Day 5 removes the *effort*. Each message has a different hypothesis, an app-state check, one primary CTA and the same verified first-value outcome. This is a proposed experiment, not a claim that the sequence has improved activation.
Define the event contract before opening your email tool
Identity: one installation = `installation_id` scoped to `shop_id`. A merchant contact can manage multiple shops. Don't use a single contact-wide `widget_published` flag unless your integration guarantees one shop per profile. The simplest illustrative implementation below assumes one contact/profile per shop installation with an explicitly mapped recipient; production multi-shop teams should use supported objects/relationships or a shop-scoped state service.
Proposed state properties (custom fields, not native Shopify fields):
| Field | Example | Meaning |
| `shop_id` | `shop_8271` | Stable shop reference |
| `installation_id` | `inst_20261028_1` | Install/reinstall boundary |
| `installed_at` | `2026-10-28T09:00:00Z` | Cohort start |
| `setup_status` | `widget_configured` | Current step |
| `widget_published` | `false` | Current verified state |
| `first_value_at` | null | Verified activation timestamp |
| `setup_blocker` | `theme_placement` | Diagnostic branch |
| `app_uninstalled` | `false` | Recovery suppression |
| `experiment_group` | `treatment` | Randomized assignment |
| `email_eligible` | `true` | Eligibility derived from valid consent/subscription status |
Event contract (the app backend emits these; do not expose secrets, shopper data or tokens):
{
"event": "app_installed",
"recipient_id": "merchant_shop_8271",
"shop_id": "shop_8271",
"installation_id": "inst_20261028_1",
"occurred_at": "2026-10-28T09:00:00Z",
"app_category": "reviews"
}{
"event": "review_widget_published",
"recipient_id": "merchant_shop_8271",
"shop_id": "shop_8271",
"installation_id": "inst_20261028_1",
"occurred_at": "2026-10-29T10:15:00Z",
"verification": "storefront_visible"
}Also emit `setup_started` and `setup_blocked` with `step_id` or `blocker_code`. These JSON blocks describe a canonical app-side event contract, not vendor-specific API request bodies. Map the fields into each vendor's documented API format below. Update state only after trusted backend verification; deduplicate event retries by stable event ID. The `first_value_reached` event can normalize category-specific activation, but don't count both events as two activations.
Implement the campaign
Native terms and mapping
Customer.io uses People, Person attributes, Events, Data-driven Segments, and Campaigns. Its workflow actions include Time Delay, Wait Until and True/False Branch. Data-driven Segments can use attributes, events and relationship conditions; they update as data changes.
| App data | Customer.io representation | Use |
| `recipient_id` | Person ID | Recipient identity |
| `shop_id`, `installation_id` | Person attributes for one-shop-per-person example | Shop-scoped campaign state |
| `first_value_at`, `widget_published`, `setup_blocker` | Person attributes | Branching / suppression |
| `app_installed` | Event | Campaign trigger |
| `review_widget_published` | Event and synchronized activation attributes | Goal and exit |
| `email_eligible`, `experiment_group` | Attributes plus Customer.io current consent state | Eligibility |
| Unactivated merchants | Data-driven Segment | Reusable dynamic audience |
Example app-to-Customer.io mapping (conceptual): identify Person `merchant_shop_8271` with attributes `shop_id=shop_8271`, `installation_id=inst_20261028_1`, `widget_published=false`; send event `app_installed` with `shop_id` and `installation_id`. Implement via the documented Track API or supported SDK; this is not a copy-paste HTTP request.
Build the segment: Go to Segments > Create segment > Data-driven. Name it `Review App | Unactivated | Eligible`. Require all: current installation present; `widget_published=false`; `app_uninstalled=false`; `experiment_group=treatment`; appropriate current email consent/eligibility. Test membership with three synthetic People..
Build the Campaign: Create an event-triggered Campaign for `app_installed`; configure entry filters and re-entry rules around `installation_id`. Add Time Delay to Day 1; True/False Branch checking current activation and eligibility; send Email 1 only on eligible unactivated path. Repeat with delays to Day 3 and Day 5, checking state before each email. Use Wait Until if you need an early path when activation occurs and a maximum time fallback. Note that Wait Until can proceed immediately when a condition is already met; test that behavior..
Exit and measurement: Configure Campaign exit conditions for verified first value and loss of eligibility; use conversion reporting for `review_widget_published` scoped to the correct installation. An app-side randomized holdout is the safest cross-platform comparable experiment if native branching does not guarantee shop-scoped allocation.
1.Customer.io Event: app_installed
2.Entry filters: consent + treatment + installed?
No → Exit CampaignYes → Time Delay: 1 day3.Exit Campaign
4.Time Delay: 1 day
Next → True/False: widget_published false?5.True/False: widget_published false?
No → Exit CampaignYes → Email 16.Email 1
Next → Time Delay: 2 days7.Time Delay: 2 days
Next → True/False: still eligible + unactivated?8.True/False: still eligible + unactivated?
No → Exit CampaignYes → Email 29.Email 2
Next → Time Delay: 2 days10.Time Delay: 2 days
Next → True/False: still eligible + unactivated?11.True/False: still eligible + unactivated?
No → Exit CampaignYes → Email 312.Email 3
QA: Test person identity, event arrival, segment membership, missing attributes, Day 1 activation, Day 3 activation, uninstall, opt-out, duplicate event, reinstall and holdout. Verify the workflow's actual exit configuration, not just the diagram.
Native terms and mapping
HubSpot uses Contacts, Companies, CRM properties, Active segments (formerly active lists), Workflows, Enrollment triggers, Delays, and If/then branches. For a contact managing several stores, consider a shop-scoped supported custom object/association or external shop-state service; don't overwrite one global Contact activation flag.
| App data | HubSpot representation | Use |
| Merchant email and ID | Contact record / unique external ID property | Recipient |
| `shop_id`, `installation_id` | Custom CRM properties in simple one-shop-per-contact example | Installation identity |
| `widget_published`, `first_value_at` | CRM properties updated from backend | Branch / unenrollment |
| `app_installed`, `review_widget_published` | Supported event integration / custom events if available | Event context |
| Unactivated merchants | Active segment | Reporting and eligibility |
| Journey | Contact-based Workflow | Send and branch |
Create properties: In HubSpot property settings, create `Shop ID` (single-line text), `Installation ID` (text), `App Installed At` (date/time where supported), `Review Widget Published` (Boolean-style property), `First Value At` (date/time), `App Uninstalled`, `Setup Blocker` and `Experiment Group`. Confirm property type and update behavior in your portal. Sync the app backend into the associated Contact record; keep the actual shop-level source of truth outside a shared Contact when needed.
Build an Active segment: Filter for `App Installed At` known AND `Review Widget Published` false AND `App Uninstalled` false AND `Experiment Group` treatment. Apply marketing-contact status, subscription/consent and suppression rules independently. A segment is an audience, not an automation.
Build a Workflow: Go to Automation > Workflows, create a Contact-based Workflow. Choose Enrollment triggers based on installation properties or a supported event. Don't attempt to enroll on an event *not happening*. Add a Delay to Day 1, then If/then branch for current activation, uninstall and eligibility; send the corresponding Automated marketing email only to eligible contacts. Repeat with delays and branches for Days 3 and 5. Set Unenrollment and suppression for activation and consent changes; inspect re-enrollment rules before enabling. The ability to send automated marketing emails and use certain event-based triggers depends on plan and portal configuration.
Experiment: Assign `Experiment Group` in your backend before enrollment, or use a supported random percentage branch where available. Keep shop-scoped assignment stable and avoid treating workflow branch counts as a statistically valid experiment by themselves.
1.Contact CRM property: App Installed At
2.Contact-based Workflow Enrollment trigger
Next → Suppression + consent + treatment?3.Suppression + consent + treatment?
No → Unenroll / no emailYes → Delay to Day 14.Unenroll / no email
5.Delay to Day 1
Next → If/then: Review Widget Published = false?6.If/then: Review Widget Published = false?
No → Unenroll / no emailYes → Automated marketing email 17.Automated marketing email 1
Next → Delay to Day 38.Delay to Day 3
Next → If/then: still unactivated + eligible?9.If/then: still unactivated + eligible?
No → Unenroll / no emailYes → Automated marketing email 210.Automated marketing email 2
Next → Delay to Day 511.Delay to Day 5
Next → If/then: still unactivated + eligible?12.If/then: still unactivated + eligible?
No → Unenroll / no emailYes → Automated marketing email 313.Automated marketing email 3
QA: Confirm Contact/Company associations, property updates, marketing email eligibility, suppressed recipients, enrollment/re-enrollment, delayed activation, multi-shop records, email links, and test contacts.
Native terms and mapping
Klaviyo uses Profiles, Profile properties, Metrics (recorded events), Segments, Flows, Trigger Filters, Profile Filters, Time Delays and Conditional Splits. A custom `App Installed` metric is not the merchant store's native Shopify `Placed Order` metric.
| App data | Klaviyo representation | Use |
| Merchant recipient | Profile | Email identity |
| `shop_id`, `installation_id` | Custom Profile properties in one-shop-per-profile example | Shop context |
| `widget_published`, `setup_blocker` | Profile properties | Current eligibility |
| `app_installed` | Custom `App Installed` Metric | Flow trigger |
| `review_widget_published` | Custom `Review Widget Published` Metric | Conversion / measurement |
| Unactivated merchants | Segment | Reporting and targeting |
| Onboarding | Metric-triggered Flow | Journey |
Instrument custom Metrics: Send app-side merchant events through Klaviyo's Events API using a stable Profile identifier and event properties `shop_id` and `installation_id`. Verify the resulting custom `App Installed` and `Review Widget Published` Metrics in Analytics > Metrics. Update Profile properties as merchant setup state changes. Do not assume Klaviyo's native Shopify integration sends these app-provider events..
Build a Segment: Require `App Installed` occurred for the current install context and `widget_published=false`, plus treatment and installed status. For multi-install histories, prefer a reliable current-state Profile property or shop-scoped identity; a lifetime 'Review Widget Published zero times' condition can wrongly exclude a new reinstall.
Build a Flow: Create a Metric-triggered Flow from `App Installed`. Use Trigger Filters only for properties of the event at entry (e.g. app category); use Profile Filters for ongoing eligibility (not activated, not uninstalled, treatment), and Conditional Splits to distinguish setup states. Add Time Delays to Days 1, 3 and 5. Recheck activation and consent before each email. Profile Filter failures may skip an action rather than terminate the entire Flow; inspect actual behavior in test profiles. Configure Smart Sending/frequency behavior intentionally.
Experiment: Assign holdout status in the app backend and exclude holdout Profiles from the Flow, while preserving their activation events in the analytics dataset. Use shop-scoped identity and keep treatment assignment fixed for the observation period.
1.Custom Metric: App Installed
2.Trigger Filter: app category = reviews
No → Not enrolledYes → Profile Filters: treatment + installed + unactivated3.Not enrolled
4.Profile Filters: treatment + installed + unactivated
No → Not enrolledYes → Time Delay: 1 day5.Time Delay: 1 day
Next → Conditional Split: widget_published false?6.Conditional Split: widget_published false?
No → Skip setup messagesYes → Email 17.Skip setup messages
8.Email 1
Next → Time Delay: 2 days9.Time Delay: 2 days
Next → Profile Filters + split: still eligible?10.Profile Filters + split: still eligible?
No → Skip setup messagesYes → Email 211.Email 2
Next → Time Delay: 2 days12.Time Delay: 2 days
Next → Profile Filters + split: still eligible?13.Profile Filters + split: still eligible?
No → Skip setup messagesYes → Email 314.Email 3
QA: Check Profile identity, Metric names and payloads, Profile property synchronization, Trigger Filter vs Profile Filter behavior, Smart Sending, consent, early activation, multi-shop, uninstall, reinstall, duplicate events and holdout.
Measurement and experiment
7-day activation rate = eligible new shop installations reaching a verified widget-publication event within 7 days / eligible new shop installations with a full 7-day observation window. Preserve `installation_id` and report both numerator and denominator. Track median time to first value among activated shops, step-level abandonment, 24-hour uninstall, support burden and 30-day repeat value separately.
Randomly assign eligible installations to treatment and holdout before campaign exposure; measure both groups from the same installation cohort. Check balance, delivery exclusions, sample size and attribution window. An email click is not activation; a before/after improvement is not proof of incremental impact.
QA acceptance matrix
| Scenario | Expected result |
| Installed, no setup | Email 1 at eligible Day 1 |
| Setup configured, widget not published | Task-specific help; not counted activated |
| Activated before Day 1 | No recovery emails |
| Activated between Day 1 and 3 | Email 2 and 3 suppressed |
| Unsubscribed | No sends |
| App uninstalled | No recovery sends |
| Holdout | No recovery sends; activation still measured |
| Duplicate `review_widget_published` | One activation counted |
| Reinstalled shop | New installation cohort; no stale activation state |
| One person, two shops | No cross-shop activation suppression |
| Late event sync | Recheck source-of-truth state; test race conditions |
| Missing deep link | Fail QA; do not send |
Explore more
See the ReadyFly lifecycle case study