Re-Creating My Favorite Growth Hack from Dropbox – Part 1

If you scan the volumes of growth hacking literature on the web, there’s a lot of good data and post-mortem analysis on how startups like DropboxPaypal and Uber used referral marketing programs to accelerate early user adoption and brand-building. As a result, I’m assuming if you’re here reading this, as a baseline, you agree: IF you have a good product, a customer referral program is an effective way to incentivize your existing user community to do some of your marketing for you.

But this post isn’t about repeating why customer referral programs are a tasty growth hacking recipe: instead, we’re going to walk through how to bake the cake, structure and implement one.

[disclaimer: BuzzFork is a Django shop, so the code examples presented in this post are all in Python. I’ve been fiddling around with a referral program module adaption for node.js using Express, but no promises if/when that gets done. Unfortunately, if Rails is your bread and butter I’ve got nothing for you (other than brotherly love), although maybe this guy does…]

Let’s begin, shall we?

Program Structure

In terms of the structure the referral program, I didn’t try to think too outside the box: the growth hacking community has already been handed a growth-oriented industry blueprint by product-oriented marketers at startups like Dropbox, Paypal, Uber, AirBnb and Groupon, so why reinvent a working wheel?

Here are the basic implementation principles:

  1. Two-sided benefit stream: both referrer and referee get a benefit. I asked SaaS expert David Skok of Matrix Partners whether his data and experience suggested a two-sided referral program outperformed a referrer-benefit-only one, and he confirmed it consistently did. Check.
  2. $10 worked for Paypal and Uber, and since BuzzFork is in Uber’s price-point ballpark (despite a polar opposite SaaS offering aimed at growth hackers, social media managers, agencies, and emerging brands), “give $10, get $10” was going to be the core call to action to trigger affiliate link sharing. I also polled some existing users and friends, with the general agreement being that $10 was a psychologically significant threshold where it was actually worth doing something, without being so lavish an offer I felt like we’re leaving a lot of value on the table.
  3. Offer a separate benefit to brand new users who aren’t as familiar with the product and haven’t demonstrated a willingness-to-pay yet. For free users (non-subscribers), sharing BuzzFork gives them extra free trial time.

Referral Program Architecture

Ok, we’ve got our program model, so what steps (features) do we need to implement? How do we break our goal down into actionable, programmable steps?

Here’s what we need our system to accomplish:

  1. We need to generate a user-specific, unique URL for each user when they sign up (existing users will be handled separately). The URL will be made unique by a URL parameter code (and can also be passed through a trackable, 301 redirect-generating shortener API like bit.ly). Here’s an example of a code generator which generates (returns) a 40 character code that will be appended as a URL parameter to our link:

Generate User Referral Link Code

             Then we define a url where “code” (as path) gets added to our domain:

Dropbox Referral Program Python Example

        2.  We want a one-to-one relationship between each user and their sharing URL, which we’ll talk more about below.

        3.  We then want to track whether a browsing session came from a referral link. What we need is a way to listen and record   within our app if an HTTP request came from a referral link.

        4. When we record a browsing session that came from a referral, we’ll want to connect it to the user who created/shared the link.

        5. We need to define a schema for our “reward(s)” so it can be redeemed, credited and messaged.

        6. When a sharing reward is earned, we need to be able to credit it to the referrer. In our case, this means posting two $10 discount codes to Stripe, one to the referrer and one to the referree. We’ll also display the rewards our referring user has earned within the app, similar to Dropbox’s rewards section.

Referral Program Dependencies

To recreate our rewards system in Django (while using modular libraries and writing as little new code as possible), we used:

  1. Django==1.5.1
  2. Anafero (anafero==1.0.1, in our case)
  3. django-celery==3.0.17
  4. A celery broker and back end (we run Redis)
  5. Django-Stripe-Payments  // if you’re using Stripe for payment processing

Referral Program Implementation (Models)

After a quick analysis of existing open source code, we identified Eldarion’s Anafero library as a good starting module to build our referral system on top of. Django devs can install Anafero into their own project with a simple “pip install anafero” from the command line, followed by adding the app to settings.py like so:


Then, simply add Anafero’s middleware and url configs as detailed in its documentation. If Django isn’t your framework of choice hopefully this can still serve as a useful “how we tackled/thought about the problem” resource that you can adapt to Rails, Meteor or whatever the kids are into these days.

Anafero works by establishing a one-to-one relationship between your app’s user profile object and a Referral object, then uses a record_response method to listen to user sessions and check for a referral_response to see if a browsing session is linked to an existing user referral. Signal responses are handled by the receiver user_linked_to_response. So let’s walk through how to integrate this basic structure into our app’s models (models.py):

1. If you’re using Anafero, be sure to import whatever objects you need from anafero.models (i.e. Referral, ReferralResponse)

2. Next, we specify our rewards (the different types of perks our users can qualify for by sharing their affiliate URL):

Customer Referral Program User Sharing Options

3. Third, we create our referral reward database model, which establishes the following fields: (a) referral type, (b) user [using models.ForeignKey to establish the relationship to our user schema], (c) response, (d) reward amount, (e) date credited, (f) date redeemed and (g) a Boolean indicating whether or not the reward was redeemed. This enables us to create ReferralRewards that can be displayed and redeemed (credited to a user’s account).

Database Model Schema for Referral Object

We also create custom methods for reward redemption (redeem) and a conditional reward label.

4. Our next step is to add two new fields to our user profile model to establish the one-to-one relationship between the user and Referral (thereby connecting them to their referral code and link):

One to One Model Relationship with User

5. Then we define a new method get_referral_link which we’ll rely on to generate the sharing URL on the client side within our HTML template using an <input> element with value=”{{ user.get_referral_link }}” [note: if you’re using social auth to create your user profile this might look something like {{ user.facebook.get_referral_link }} instead]. This method also checks to see if we have a shortened URL available, otherwise, it returns us the un-shortened referral URL:

Get Referral Link Python Method

If you’re using anafero, that’s all the model customization that’s required after importing Referral and Referral Response. If you’re not using anafero because you’re rolling your own or working in another framework, you’ll also need to create schema and class methods for Referral and Referral Response. See here for how anafero implements this.

Ok, at this point, we’ve now accomplished three key things:

1. We’ve installed our modules and dependencies.

2. We created a ReferralReward model.


This now gives us our app three objects total that we can work with: (a) Referral, (b) Referral Response and (c) ReferralReward.

3. Finally, we linked Referral and ReferralReward to our user schema so that — logically — users can refer and be referred (and rewarded).

If you’re following along in Django, all that’s required now is a syncdb (and possibly a quick south migration) and our database is primed to support our referral system. Now that we’ve got our models set up, our next steps are to (a) configure our receivers, (b) set up our views, (c) add referral sharing into our templates and create the UX around it, then (d) track, award and log rewards. In part 2 of this tutorial, we’ll focus on signaling, views and templates so we can display functioning, sharable URLs to our users just like Dropbox. Finally, in part 3, we’ll look at reward implementation, crediting discounts to Stripe and tracking reward redemptions/credits.

Comments ( 2 )
    • David @ Growth Hero says:

      Thanks for the shout, Chris. Great article. When can we expect part 2?

    • chrisbolman says:

      Hey David, been meaning to get to this. Have a few writing commitments I need to deliver on before I can sit down and work through it (takes a while to organize the examples). It’s coming through — feel free to join my email list if you want to be the first to know.

    Leave A Comment

    Your email address will not be published. Required fields are marked *