How to make a viral referral system like Initiative Q and collect 2m emails.

Published December 1st , 2018 by Domingo Mancera

Final result

Final result

Initiative Q has managed to collect more than 2 million emails with a genius marketing campaign. The best part is that they don't even have a product yet. Before starting creating something, they decided to check if people are interested in the idea. It looks they had some validation so far. How did they do it?

Initiative Q landing

Initiative Q landing

The landing and the whole onboarding mechanism is full of well-known physiological tricks. It feels almost irresistible to join. Here are a few you'll find if you follow the entire journey:

  • Authority bias: The ex-Paypal guy knows what he's doing.
  • Loss aversion: I feel uncomfortable if I lose all my thousands of Qs.
  • Network effect: 2 million users it's a valuable network.
  • Need to complete: I'll feel satisfied when I finish my goal of inviting my five friends.
  • Reciprocity/rewards: They'll give me a lot of digital cash. At least I can help them to spread the word.
  • Scarcity/deadline: I only have 14 days to invite my five friends.
  • Social proof: All my friends are sharing it on Facebook. It must be legit.
  • Public commitment: I shared it on twitter, now I cannot change my opinion.
  • Fear of missing out: I don't want to miss the next bitcoin wave.

So what can we learn here? Craft a marketing strategy, validate before building something and make what consumes less energy and time.

Initiative Q dashboard

Initiative Q dashboard

Now I'll show you how can you also build a viral referral engine for your landing pages with Tuemilio like Initiative Q did. 

Sign up for Tuemilio and create a list. In this case, I call it WeCognitive. 

Creating an email list

Creating an email list

Once created, I copy and paste the advanced HTML form given. There is also an implementation with Bootstrap 4 that covers most of the boilerplate for a basic landing. 

Form code

Form code

Index.html

The HTML file is structured in two parts. The first part is a simple form for collecting emails. The second part is a hidden dashboard that appears when the user joins our list. Below I show you a simplified version of the HTML. You can find the whole file here.

<div class="landing-content">
    <div>
        <h1>WeCognitive is the coin of the future</h1>
        <h4>Easiest payment system ever made. Lighting fast, no fees, no maintenance costs, free forever.</h4>
    </div>
    <div class="form-inline justify-content-center" id="44722aad-f267-4e78-ba81-2c644830b425">
        <input type="email" placeholder="Email" autofocus>
        <button type="submit">Get Invited</button>
        <div class="tu-message"></div>
    </div>
</div>

<div class="tu-dashboard hidden">
    <h2>Welcome <span id="user"></span> to your dashboard!</h2>
    <div>
        <h3>You are in position <span id="position"></span> </h3>
    </div>
    <div>
        <h3>Current Task</h3>
        <!-- Sharing elements here -->
    </div>
    <div>
        <h3>Referred Friends:</h3>
        <!-- List of invited friends here -->
    </div>
    <div>
        <h3>The waiting list</h3>
        <!-- Leaderboard here -->
    </div>
    <div>
        <h3>Objective</h3>
        <!-- Define an objective and progression here -->
    </div>
</div>

The "tu-message" is filled with validation/error messages. If I don't want them in my form, I can delete the div.

Main.js

All the logic runs on the Tuemilio backend and the JavaScript library. I initialize a new Tuemilio object passing the list ID.

let tuemilio = Tuemilio.new('44722aad-f267-4e78-ba81-2c644830b425');

I listen to two events before the dashboard is loaded. When the user clicks the submit button and when the server receives the user's email correctly. I use these events to disable the button. Adding a spinner when the 'submitted' event fires is a good idea too.

tuemilio.on('submitted', () => {
    tuemilio.button.classList.add('disabled');
});

tuemilio.on('subscribed', () => {
    tuemilio.button.classList.remove('disabled');
});

The dashboard event passes the dashboard object once the email is successfully stored in my list.

tuemilio.on('dashboard', (dashboard) => {
    // console.log(dashboard);
});

It contains all the information I need to build my dashboard and looks like this:

{
    "user": "jordan@gmail.com",
    "points": 2,
    "position": 1,
    "subscribers_count": 6,
    "referreds_count": 2,
    "referreds": [
        {
            "points": 0,
            "user": "dmm.martin"
        },
        {
            "points": 0,
            "user": "david123"
        }
    ],
    "referral_link": "https:\/\/wecognitive.com?referrerId=YE8K",
    "dashboard_link": "https:\/\/wecognitive.com?email=jordan@gmail.com",
    "joined_at": "2018-12-01 18:46:06",
    "waiters": [
        {
            "address": "jordan@gmail.com",
            "points": 2,
            "position": 1
        },
        {
            "address": "ric***********com",
            "points": 1,
            "position": 2
        },
        {
            "address": "dav******************com",
            "points": 0,
            "position": 3
        },
        {
            "address": "n7d****************com",
            "points": 0,
            "position": 4
        },
        {
            "address": "bob***********com",
            "points": 0,
            "position": 5
        },
        {
            "address": "mer**************com",
            "points": 0,
            "position": 6
        }
    ]
}

I transform it as I want to show it to the user. You can use here whatever JS framework you like. For sake of simplicity I use vanilla JS.

I set my custom tweets, Facebook status, etc. that I want to write for the users when they share their link through the buttons on the landing.

tuemilio.buildShareable({
    link: dashboard.referral_link,
    facebookQuote:'I just joined this awesome payment system!',
    twitterQuote:'I just joined this awesome payment system!',
    hashTags: 'wecognitive,newbitcoin',
    whatsappQuote: 'I just joined this awesome payment system!',
    redditQuote:'I just joined this awesome payment system!',
    telegramQuote:'I just joined this awesome payment system!',
    emailBody: 'Here is my link',
    emailSubject: 'I just joined this awesome payment system!',
    linkQuote: 'Share the link below'
});

I build a list of referred friends with the number of points they achieved.

let ul = document.getElementById('referred-friends');

dashboard.referreds.forEach((referred) => {
    let li = document.createElement('li');
    let badge = document.createElement('span');
    li.classList.add('list-group-item');
    badge.classList.add('badge');
    li.appendChild(
        document.createTextNode(referred.user)
    );
    badge.appendChild(
        document.createTextNode(referred.points)
    );
    li.appendChild(badge);
    ul.appendChild(li);
});

Now I add a leaderboard with the user's position on the list and the number of points.

let waitingList = document.getElementById('waiting-list');

dashboard.waiters.forEach((referred) => {
    let li = document.createElement('li');
    let badge = document.createElement('span');
    let position = document.createElement('span');
    let address = document.createElement('span');

    li.classList.add('list-group-item');
    badge.classList.add('badge');

    position.appendChild(
        document.createTextNode(referred.position)
    );
    badge.appendChild(
        document.createTextNode(referred.points)
    );
    address.appendChild(
        document.createTextNode(referred.address)
    );

    li.appendChild(position);
    li.appendChild(address);
    li.appendChild(badge);
    waitingList.appendChild(li);
});

Fill some data inside the copy.

document.getElementById('user').innerHTML = dashboard.user;
document.getElementById('position').innerHTML = dashboard.position;
document.getElementById('subscribers-count').innerHTML = dashboard.subscribers_count;
document.getElementById('referred-friends-count').innerHTML = dashboard.referreds_count;

Hide the landing header and show the dashboard.

tuemilio.form.classList.add('hidden');
tuemilio.dashboard.classList.remove('hidden');
document.getElementsByClassName('landing-content')[0].classList.add('hidden');

Get the whole code here.

You can check a live demo here wecognitive.com.

The dashboard

The dashboard

On the Tuemilio side you'll have some analytics of your landing and all the data that is collected by the form.

The beginning of a huge list. All data shown here is dummy.

The beginning of a huge list. All data shown here is dummy.

And that's all! Any question please ping me on Twitter or send me an email. You can find my address on the footer of the page.

If you like what I am writing, please subscribe to my mailing list. Have a good day!

Subscribe and don't miss a post!

Domingo Mancera

Electronics engineer and creator of Tuemilio.

Follow me