Skip to content
Tolinku
Tolinku
Sign In Start Free
Use Cases · · 6 min read

Onboarding Email Sequences with Deep Links

By Tolinku Staff
|
Tolinku fintech deep linking dashboard screenshot for use cases blog posts

In-app onboarding only works when the user is in the app. For users who don't complete onboarding in their first session (30-50% of new signups), email sequences are the primary channel for bringing them back. The key is deep links: every email CTA should open the app directly to the relevant screen, not to a generic web page or app store listing.

For personalization strategies, see Personalized Onboarding Flows with Deep Link Data. For reducing drop-off, see Reducing Onboarding Drop-Off: 10 Proven Strategies. For a broader look at onboarding fundamentals, see Onboarding Best Practices for Mobile Apps in 2026.

Email Sequence Structure

The Standard Sequence

A typical onboarding email sequence sends 5-7 emails over the first 14 days:

Day Email Purpose Deep Link Target
0 Welcome Confirm signup, set expectations /home
1 Getting started Guide to first action /onboarding/first-action
3 Feature highlight Show key feature they haven't used /feature/{feature_name}
5 Social proof Show what others are doing /explore or /trending
7 Progress check Remind them of incomplete setup /onboarding/resume
10 Advanced feature Introduce a power feature /feature/{advanced_feature}
14 Feedback request Ask how it's going /feedback

Conditional Logic

Not every user should receive every email. Skip emails based on user behavior:

async function shouldSendEmail(userId, emailId) {
  const user = await getUser(userId);

  switch (emailId) {
    case 'getting_started':
      // Skip if user already performed the first action
      return user.hasCompletedFirstAction === false;

    case 'feature_highlight':
      // Skip if user already used the featured capability
      return user.hasUsedFeature('sharing') === false;

    case 'progress_check':
      // Skip if onboarding is already complete
      return user.onboardingCompleted === false;

    case 'feedback_request':
      // Only send if user has been active at least once in the last 7 days
      return user.lastActiveAt > daysAgo(7);

    default:
      return true;
  }
}

Without deep links:

  1. User taps "Get Started" in email
  2. Opens a web page
  3. Sees "Download our app" or "Open in App"
  4. Taps that link
  5. App opens to the home screen
  6. User has to navigate to the right feature

With deep links:

  1. User taps "Get Started" in email
  2. App opens directly to the relevant screen

Every extra step loses 20-30% of users. Deep links cut 4 steps down to 1. For a technical guide on using Universal Links within email, see Universal Links in Email: Complete Guide.

async function generateEmailDeepLink(userId, emailId, destination) {
  const link = await Tolinku.createLink({
    path: destination,
    params: {
      utm_source: 'email',
      utm_medium: 'onboarding_sequence',
      utm_campaign: emailId,
      user_id: userId,
    },
    fallback: {
      web: `https://yourapp.com${destination}`, // Fallback for users without the app
    },
  });

  return link.url;
}

When the user taps a deep link from an email:

function handleEmailDeepLink(url, params) {
  // Track email engagement
  analytics.track('email_deep_link_opened', {
    campaign: params.utm_campaign,
    destination: new URL(url).pathname,
    source: 'email',
  });

  // Check authentication
  if (user.isAuthenticated === false) {
    pendingDeepLink.save(url);
    navigation.navigate('Login');
    return;
  }

  // Navigate to the destination
  handleRoute(url);
}

Fallback for Users Without the App

Some users might have uninstalled the app. The deep link should fall back to a web experience:

// In your email template
const deepLink = await generateEmailDeepLink(userId, 'getting_started', '/onboarding/first-action');

// The Tolinku link will:
// 1. Open the app if installed (directly to /onboarding/first-action)
// 2. Redirect to the web fallback if not installed
// 3. Optionally redirect to the app store with deferred deep link

Email Content Patterns

Email 1: Welcome (Day 0)

Subject: Welcome to [App]! Here's what to do first.

Hi {firstName},

Welcome to [App]. You're all set.

Here's the one thing to do right now:

[Create your first {item}]  ← deep link to /create

It takes about 30 seconds, and you'll see why 50,000 people use [App] every day.

{CTA Button: "Create Your First {Item}" → deep link}

Email 2: Getting Started (Day 1)

Only sent if the user hasn't performed their first action:

Subject: Quick tip to get the most out of [App]

Hi {firstName},

Most new users start by {first action description}.

Here's a 30-second walkthrough:
1. Open [App]
2. Tap "Create"
3. Choose a template or start from scratch

{CTA Button: "Open [App]" → deep link to /create}

Need help? Reply to this email and we'll point you in the right direction.

Email 3: Feature Highlight (Day 3)

Highlight a feature the user hasn't discovered:

Subject: Did you know [App] can {feature benefit}?

Hi {firstName},

One feature our users love: {feature name}.

{1-2 sentences explaining what it does and why it's useful.}

{Screenshot or GIF showing the feature}

{CTA Button: "Try {Feature Name}" → deep link to /feature/sharing}

Email 5: Progress Check (Day 7)

For users who haven't completed onboarding:

Subject: You're almost there

Hi {firstName},

You've completed {completedSteps} of {totalSteps} setup steps.
Here's what's left:

☑ Created account
☑ {completed step}
☐ {next incomplete step}
☐ {remaining step}

{CTA Button: "Finish Setup" → deep link to /onboarding/resume}

This takes about {estimatedTime} minutes.

Personalization by Acquisition Source

Referral Users

function getReferralEmailSequence(referralData) {
  return [
    {
      day: 0,
      subject: `Welcome! ${referralData.referrerName} sent you a gift`,
      template: 'referral_welcome',
      deepLink: '/onboarding?ref=true',
      data: {
        referrerName: referralData.referrerName,
        reward: referralData.rewardAmount,
      },
    },
    {
      day: 1,
      subject: `Claim your ${referralData.rewardAmount} reward`,
      template: 'referral_activation',
      deepLink: '/rewards',
      condition: (user) => user.hasCompletedQualifyingAction === false,
    },
  ];
}

Campaign Users

function getCampaignEmailSequence(campaignData) {
  return [
    {
      day: 0,
      subject: `Welcome! Your ${campaignData.promoCode} code is active`,
      template: 'campaign_welcome',
      deepLink: `/shop?promo=${campaignData.promoCode}`,
      data: {
        promoCode: campaignData.promoCode,
        discount: campaignData.discountAmount,
      },
    },
  ];
}

Timing Optimization

Send Time Optimization

Don't send all emails at the same time of day. Test different send times:

function getOptimalSendTime(user) {
  // If we know when the user is most active
  if (user.peakActivityHour) {
    return user.peakActivityHour;
  }

  // Default send times by email type
  const defaults = {
    welcome: 'immediate', // Send immediately after signup
    getting_started: '10:00', // Morning, when people start tasks
    feature_highlight: '14:00', // Afternoon, when engagement peaks
    progress_check: '09:00', // Morning, fresh start feeling
    feedback_request: '11:00', // Mid-morning, not too early
  };

  return defaults;
}

Time Zone Awareness

Send emails at the user's local time, not UTC:

function scheduleEmail(userId, emailConfig) {
  const user = getUser(userId);
  const timezone = user.timezone || detectTimezoneFromIP(user.signupIP);

  const sendAt = convertToTimezone(emailConfig.sendTime, timezone);

  emailQueue.add({
    userId,
    templateId: emailConfig.template,
    sendAt,
    deepLink: emailConfig.deepLink,
    data: emailConfig.data,
  });
}

Measuring Email Sequence Performance

Key Metrics

Metric Formula Benchmark
Open rate Opens / Delivered 40-60% (onboarding emails are high-priority)
Click rate Clicks / Delivered 10-20%
Deep link open rate App opens from email / Clicks 60-80%
Activation after email Users who activate within 24h of email open 5-15%
Unsubscribe rate Unsubscribes / Delivered < 0.5%

Attribution

Track which email drove the activation:

analytics.track('activation_event', {
  action: 'first_project_created',
  attributedEmail: lastEmailOpened.campaign, // 'getting_started'
  timeFromEmail: Date.now() - lastEmailOpened.timestamp,
  deepLinkUsed: true,
});

Sequence-Level Analysis

async function analyzeEmailSequence(sequenceId) {
  const emails = getSequenceEmails(sequenceId);

  for (const email of emails) {
    const sent = await countSent(email.id);
    const opened = await countOpened(email.id);
    const clicked = await countClicked(email.id);
    const activated = await countActivatedAfter(email.id, { within: '24h' });

    console.log(email.id, {
      sent,
      openRate: (opened / sent * 100).toFixed(1) + '%',
      clickRate: (clicked / sent * 100).toFixed(1) + '%',
      activationRate: (activated / sent * 100).toFixed(1) + '%',
    });
  }
}

Common Mistakes

1. Too Many Emails

Sending 10 emails in 14 days overwhelms users and increases unsubscribes. Stick to 5-7 emails, and skip emails when the user has already taken the target action. For users who stop engaging entirely, consider transitioning them to a re-engagement campaign.

2. Generic CTAs

"Open App" is a weak CTA. Be specific: "Create Your First Project," "See What's Trending," "Finish Setup." The CTA should tell the user exactly what they'll do when they tap.

Sending users to a web page that says "Download our app" is a broken experience. Every email CTA should deep link directly into the app.

4. Ignoring Mobile Rendering

Most onboarding emails are opened on mobile. Test your emails on iOS Mail, Gmail app, and Outlook mobile. Keep subject lines under 40 characters and CTAs large enough to tap easily.

For deep linking features, see Tolinku deep linking. For onboarding use cases, see the onboarding documentation.

Get deep linking tips in your inbox

One email per week. No spam.

Ready to add deep linking to your app?

Set up Universal Links, App Links, deferred deep linking, and analytics in minutes. Free to start.