Tracking leads and free trials

Importing lead and trial data into ChartMogul lets you benefit from the following Leads and Conversion charts.

ChartDescription
LeadsCharts the number of individuals or businesses who have entered your sales pipeline (and may eventually become subscribers) over time
Free TrialsCharts the number of individuals or businesses who have started free trials over time.
Trial-to-Paid Conversion RateCharts the percentage of customers who start a trial and subsequently subscribe.
Average Sales Cycle LengthCharts the average number of days it takes for a lead to become a subscriber over time.

Do I need to set up lead tracking in ChartMogul?

ChartMogul imports lead and trial data automatically from select billing systems, including Stripe, Braintree and Recurly. View the full list here. If you track leads using one of these billing systems, then no additional setup is required.

If you need to set up lead and trial tracking in ChartMogul, the method you'll use depends on how you import your customer billing data:

Tracking leads and free trials using the Import API

If you've built an integration using our Import API to import your customers into ChartMogul, track leads and free trials by including two additional fields on all customer records:

  • lead_created_at - Time at which this customer was established as a lead.
  • free_trial_started_at - Time at which this customer started a free trial of your product or service.
# Create customer with lead_created_at and free_trial_started_at

curl -X POST "https://api.chartmogul.com/v1/customers" \
     -u YOUR_API_KEY: \
     -H "Content-Type: application/json" \
     -d '{
          "data_source_uuid": "ds_fef05d54-47b4-431b-aed2-eb6b9e545430",
          "external_id": "cus_0001",
          "name": "Adam Smith",
          "email": "[email protected]",
          "country": "US",
          "lead_created_at": "2015-11-01 00:00:00",
          "free_trial_started_at": "2015-11-02 00:00:00"
         }'
# Create customer with lead_created_at and free_trial_started_at

ChartMogul::Customer.create!(
  data_source_uuid: "ds_fef05d54-47b4-431b-aed2-eb6b9e545430",
  external_id: "cus_0001",
  name: "Adam Smith",
  email: "[email protected]",
  country: "US",
  city: "New York",
  lead_created_at: Time.utc(2015, 10, 14),
  free_trial_started_at: Time.utc(2015, 11, 1)
)
// Create customer with lead_created_at and free_trial_started_at

ChartMogul.Customer.create(config, {
    "data_source_uuid": "ds_fef05d54-47b4-431b-aed2-eb6b9e545430",
    "external_id": "cus_0001",
    "name": "Adam Smith",
    "email": "[email protected]",
    "country": "US",
    "city": "New York",
    "lead_created_at": "2015-10-14",
    "free_trial_started_at": "2015-11-01"
}, function(err, res) {
    // asynchronously called
});
<?php

// Create customer with lead_created_at and free_trial_started_at
ChartMogul\Customer::create([
    "data_source_uuid" => "ds_fef05d54-47b4-431b-aed2-eb6b9e545430",
    "external_id" => "cus_0001",
    "name" => "Adam Smith",
    "email" => "[email protected]",
    "country" => "US",
    "city" => "New York",
    "lead_created_at" => "2015-10-14",
    "free_trial_started_at" => "2015-11-01"
]);
?>
// Create customer with lead_created_at and free_trial_started_at

api.CreateCustomer(&cm.NewCustomer{
  DataSourceUUID:     "ds_fef05d54-47b4-431b-aed2-eb6b9e545430",
  ExternalID:         "cus_0001",
  Name:               "Adam Smith",
  Email:              "[email protected]",
  Country:            "US",
  City:               "New York",
  LeadCreatedAt:      "2015-10-14",
  FreeTrialStartedAt: "2015-11-01",
})
# Create customer with lead_created_at and free_trial_started_at

chartmogul.Customer.create(config, data={
    "data_source_uuid": "ds_fef05d54-47b4-431b-aed2-eb6b9e545430",
    "external_id": "cus_0001",
    "name": "Adam Smith",
    "email": "[email protected]",
    "country": "US",
    "city": "New York",
    "lead_created_at": "2015-10-14",
    "free_trial_started_at": "2015-11-01"
}).then(lambda result: print(result)).get()

Next, populate the lead and free trial timestamps for customers you've already imported into ChartMogul using the update a customer endpoint.

# Update a customer with lead_created_at and free_trial_started_at

curl -X PATCH "https://api.chartmogul.com/v1/customers/cus_ab223d54-75b4-431b-adb2-eb6b9e234571" \
     -u YOUR_API_KEY: \
     -H "Content-Type: application/json" \
     -d '{
          "lead_created_at": "2015-01-01 00:00:00",
          "free_trial_started_at" : "2015-06-13 15:45:13"
         }'
# Update a customer with lead_created_at and free_trial_started_at

customer = Customer.retrieve("cus_ab223d54-75b4-431b-adb2-eb6b9e234571")

customer.lead_created_at = Time.utc(2015,1,1)
customer.free_trial_started_at = Time.utc(2015,6,13,15,45,13)

customer.update!
// Update a customer with lead_created_at and free_trial_started_at

var customerUuid = "cus_ab223d54-75b4-431b-adb2-eb6b9e234571";

var data = {
    "lead_created_at": "2015-01-01 00:00:00",
    "free_trial_started_at": "2015-06-13 15:45:13"
};

ChartMogul.Customer.modify(config, customerUuid, data);
<?php

// Update a customer with lead_created_at and free_trial_started_at
ChartMogul\Customer::update([
    "customer_uuid" => "cus_ab223d54-75b4-431b-adb2-eb6b9e234571"
        ], [
    "lead_created_at" => "2015-01-01T00:00:00.000Z",
    "free_trial_started_at" => "2015-06-13T15:45:13.000Z"
]);
?>
// Update a customer with lead_created_at and free_trial_started_at

api.UpdateCustomer(&cm.Customer{
  LeadCreatedAt:      "2015-01-01 00:00:00",
  FreeTrialStartedAt: "2015-06-13 15:45:13",
}, "cus_ab223d54-75b4-431b-adb2-eb6b9e234571")
# Update a customer with lead_created_at and free_trial_started_at

chartmogul.Customer.update(
    config,
    uuid="cus_ab223d54-75b4-431b-adb2-eb6b9e234571",
    data={
        "lead_created_at": "2015-01-01 00:00:00",
        "free_trial_started_at": "2015-06-13 15:45:13"
    })

That's it. Once you complete the above steps, you've set up lead tracking and have access to our Leads and Trials charts.

๐Ÿ“˜

How can I accurately report inbound leads that start as free trials?

For SaaS businesses, it's typical to have inbound leads start as free trials. For such leads, simply set the timestamp for free_trial_started_at. If this timestamp is set, and lead_created_at is empty, then ChartMogul will automatically set lead_created_at to the same value, so both fields have the same timestamp. This will accurately report leads that start as free trials.

๐Ÿ“˜

Set lead and free trial timestamps upon creation

We highly recommend importing leads and free trials into your ChartMogul account as soon as they are created to ensure you have the most accurate real-time measurement of your trial-to-paid conversion rate and sales cycle length.

Tracking leads and trials outside a billing system

If you store lead and trial data outside of your billing system (such as a database or the backend of your SaaS product) or, ChartMogul does not import leads and trials from your billing system (such as PayPal), set up lead tracking and use the merge customers endpoint for accurate reporting.

Let's imagine that your business is using their own database to track leads, and manages subscriptions using Stripe. The following customer journey occurs:

  • You meet Adam Smith at a conference, and he's interested in your product. A lead record is created in your database on January 5th, 2016.
  • After lead nurturing, Adam signs up for a free trial of your product on February 10th, 2016.
  • Adam likes your product and purchases a monthly subscription on February 25th, 2016 using Stripe.

Note: this tutorial uses the following UUIDs:

  • The "Leads" custom data source: ds_fef05d54-47b4-431b-aed2-eb6b9e545430
  • Adam Smith (lead record): cus_f466e33d-ff2b-4a11-8f85-417eb02157a7
  • Adam Smith (paying customer record): cus_ba1ca03c-9d09-11e5-b921-4318215bcbf6

To enable lead and trial reporting for Adam Smith in ChartMogul:

1. Create a custom data source

First, create a custom data source to track leads in ChartMogul:

  1. Navigate to to Data Platform > Data Sources
  2. Click ADD A SOURCE
  3. Select Custom Data Source
  4. Specify a name for the data source, such as "Leads"
  5. Click Next

ChartMogul creates the custom data source and generates a unique UUID. Make a note of this UUID for the next steps.

2. Create a customer

1236

Next, create customers in ChartMogul. When a lead is imported, ChartMogul creates a customer record. For Adam Smith, use the custom data source you created in the step 1 and create a customer record in ChartMogul on January 5th, 2016.

Set the external_id for this customer record as the unique identifier from your database. For Adam Smith, let's say the unique identifier is cus_0001.

# Create a customer record for Adam Smith with lead_created_at

curl -X POST "https://api.chartmogul.com/v1/customers" \
     -u YOUR_API_KEY: \
     -H "Content-Type: application/json" \
     -d '{
          "data_source_uuid": "ds_fef05d54-47b4-431b-aed2-eb6b9e545430",
          "external_id": "cus_0001",
          "name": "Adam Smith",
          "email": "[email protected]",
          "country": "US",
          "lead_created_at": "2016-01-05 00:00:00"
         }'
# Create a customer record for Adam Smith with lead_created_at

ChartMogul::Customer.create!(
  data_source_uuid: "ds_fef05d54-47b4-431b-aed2-eb6b9e545430",
  external_id: "cus_0001",
  name: "Adam Smith",
  email: "[email protected]",
  country: "US",
  lead_created_at: Time.utc(2016, 1, 5)
)
// Create a customer record for Adam Smith with lead_created_at

ChartMogul.Customer.create(config, {
    "data_source_uuid": "ds_fef05d54-47b4-431b-aed2-eb6b9e545430",
    "external_id": "cus_0001",
    "name": "Adam Smith",
    "email": "[email protected]",
    "country": "US",
    "lead_created_at": "2016-01-05"
}, function(err, res) {
    // asynchronously called
});
<?php

// Create a customer record for Adam Smith with lead_created_at
ChartMogul\Customer::create([
    "data_source_uuid" => "ds_fef05d54-47b4-431b-aed2-eb6b9e545430",
    "external_id" => "cus_0001",
    "name" => "Adam Smith",
    "email" => "[email protected]",
    "country" => "US",
    "city" => "New York",
    "lead_created_at" => "2016-01-05"
]);
?>
// Create a customer record for Adam Smith with lead_created_at

api.CreateCustomer(&cm.NewCustomer{
  DataSourceUUID: "ds_fef05d54-47b4-431b-aed2-eb6b9e545430",
  ExternalID:     "cus_0001",
  Name:           "Adam Smith",
  Email:          "[email protected]",
  Country:        "US",
  LeadCreatedAt:  "2016-01-05",
})
# Create a customer record for Adam Smith with lead_created_at

chartmogul.Customer.create(config, data={
    "data_source_uuid": "ds_fef05d54-47b4-431b-aed2-eb6b9e545430",
    "external_id": "cus_0001",
    "name": "Adam Smith",
    "email": "[email protected]",
    "country": "US",
    "lead_created_at": "2016-01-05"
}).then(lambda result: print(result)).get()

3. Update the customer when they start a free trial

This step is specific to the customer journey in this example. Skip this step if:

  • You do not want to track free trials in ChartMogul.
  • You do not offer free trials of your product or service.
  • Your only source of leads is through trials, and you set the free_trial_started_at date when creating the customer.
# Update the customer record with free_trial_started_at

curl -X PATCH "https://api.chartmogul.com/v1/customers/cus_f466e33d-ff2b-4a11-8f85-417eb02157a7" \
     -u YOUR_API_KEY: \
     -H "Content-Type: application/json" \
     -d '{
          "free_trial_started_at" : "2016-02-10 05:15:10"
         }'
# Update the customer record with free_trial_started_at

customer = Customer.retrieve("cus_f466e33d-ff2b-4a11-8f85-417eb02157a7")

customer.free_trial_started_at = Time.utc(2016,2,10,5,15,10)
customer.update!
// Update the customer record with free_trial_started_at

var customerUuid = "cus_f466e33d-ff2b-4a11-8f85-417eb02157a7";

var data = {
    "free_trial_started_at": "2016-02-10 05:15:10"
};

ChartMogul.Customer.modify(config, customerUuid, data);
<?php

// Update a customer with lead_created_at and free_trial_started_at
ChartMogul\Customer::update([
    "customer_uuid" => "cus_f466e33d-ff2b-4a11-8f85-417eb02157a7"
        ], [
    "free_trial_started_at" => "2016-02-10T05:15:10.000Z"
]);
?>
// Update the customer record with free_trial_started_at

api.UpdateCustomer(&cm.Customer{
  FreeTrialStartedAt: "2016-02-10 05:15:10",
}, "cus_f466e33d-ff2b-4a11-8f85-417eb02157a7")
# Update the customer record with free_trial_started_at

chartmogul.Customer.update(
    config,
    uuid="cus_f466e33d-ff2b-4a11-8f85-417eb02157a7",
    data={
      "free_trial_started_at": "2016-02-10 05:15:10"
}).then(lambda result: print(result)).get()

4. Identify the lead and paying customer records

When Adam Smith pays for his monthly subscription on February 25th, 2016, ChartMogul receives a webhook with this information from Stripe. ChartMogul creates a new customer record for Adam using the Stripe source in your ChartMogul account and classifies Adam Smith as Active.

1228

When your servers receive notification of successful payment from Stripe, use the information to identify and retrieve Adam Smith's lead record and the paying customer record from ChartMogul.

# Identify and retrieve the lead record using the data_source_UUID and external_id

curl -X GET "https://api.chartmogul.com/v1/customers?data_source_uuid=ds_fef05d54-47b4-431b-aed2-eb6b9e545430&external_id=cus_0001" \
     -u YOUR_API_KEY:
# Identify and retrieve the lead record using the data_source_UUID and external_id

ChartMogul::Customer.all(
  data_source_uuid: "ds_fef05d54-47b4-431b-aed2-eb6b9e545430",
  external_id: "cus_0001")
// Identify and retrieve the lead record using the data_source_UUID and external_id

ChartMogul.Customer.all(config, {
    data_source_uuid: "ds_fef05d54-47b4-431b-aed2-eb6b9e545430",
    external_id: "cus_0001"
}, function(err, res) {
    // asynchronously called
});
<?php

// Identify and retrieve the lead record using the data_source_UUID and external_id
ChartMogul\Customer::all([
    "data_source_uuid" => "ds_fef05d54-47b4-431b-aed2-eb6b9e545430",
    "external_id" => "cus_0001"
]);
?>
// Identify and retrieve the lead record using the data_source_UUID and
// external_id

api.ListCustomers(&cm.ListCustomersParams{
  DataSourceUUID: "ds_fef05d54-47b4-431b-aed2-eb6b9e545430",
  ExternalID:     "cus_0001",
})
# Identify and retrieve the lead record using the data_source_UUID and
# external_id

chartmogul.Customer.all(config, data={
    "data_source_uuid": "ds_fef05d54-47b4-431b-aed2-eb6b9e545430",
    "external_id": "cus_0001"
}).then(lambda result: print(result)).get()
# Identify and retrieve the paying customer record using the customer ID returned by Stripe for Adam Smith

curl -X GET "https://api.chartmogul.com/v1/customers?external_id=cus_9TSLDKbqG2iKgK" \
     -u YOUR_API_KEY:
# Identify and retrieve the paying customer record using the customer ID returned by Stripe for Adam Smith

ChartMogul::Customer.all(external_id: 'cus_9TSLDKbqG2iKgK')
// Identify and retrieve the paying customer record using the customer ID returned by
// Stripe for Adam Smith

ChartMogul.Customer.all(config, {
    external_id: "cus_9TSLDKbqG2iKgK"
}, function(err, res) {
    // asynchronously called
});
<?php

// Identify and retrieve the paying customer record using the customer ID returned by
// Stripe for Adam Smith
ChartMogul\Customer::findByExternalId("cus_9TSLDKbqG2iKgK");
?>
//  Identify and retrieve the paying customer record using the customer ID returned by
// Stripe for Adam Smith

api.ListCustomers(&cm.ListCustomersParams{
  ExternalID: "cus_9TSLDKbqG2iKgK",
})
# Identify and retrieve the paying customer record using the customer ID returned by
# Stripe for Adam Smith

chartmogul.Customer.all(config, data={
    "external_id": "cus_9TSLDKbqG2iKgK"
})

๐Ÿ“˜

Customer retrieval latency

It can take ChartMogul up to ten minutes to process webhooks from billing systems. Therefore, you may need to retry the customer retrieval request. We recommend building in a lookup retry every minute until successful, for about 20 minutes. If you are not able to successfully retrieve the customer within 20 minutes, and can confirm that the payment has gone through successfully in the billing system, please contact support.

When you retrieve the above records from the API, ChartMogul returns UUIDs for each record. Use the customer UUIDs of the lead and paying customer records to merge them.

5. Merge the lead and paying customer records

770

Now that you have the customer UUIDs of the two records for Adam Smith in your ChartMogul account, merge the lead record into the paying customer record.

# Merge the customer records using customer UUIDs

curl -X POST "https://api.chartmogul.com/v1/customers/merges" \
       -u YOUR_API_KEY:
       -H "Content-Type: application/json"
       -d {
             "from": {"customer_uuid": "cus_f466e33d-ff2b-4a11-8f85-417eb02157a7"},
             "into": {"customer_uuid": "cus_ba1ca03c-9d09-11e5-b921-4318215bcbf6"}
           }
# Merge the customer records using customer UUIDs

from_customer = ChartMogul::Customer.retrieve('cus_f466e33d-ff2b-4a11-8f85-417eb02157a7')
into_customer = ChartMogul::Customer.retrieve('cus_ba1ca03c-9d09-11e5-b921-4318215bcbf6')

from_customer.merge_into!(into_customer)
// Merge the customer records using customer UUIDs

ChartMogul.Customer.merge(config, {
    "from": {
        "customer_uuid": "cus_f466e33d-ff2b-4a11-8f85-417eb02157a7"
    },
    "into": {
        "customer_uuid": "cus_ba1ca03c-9d09-11e5-b921-4318215bcbf6"
    }
})
<?php

// Merge the customer records using customer UUIDs
ChartMogul\Customer::merge([
    'customer_uuid' => "cus_f466e33d-ff2b-4a11-8f85-417eb02157a7"
], [
    'customer_uuid' => "cus_ba1ca03c-9d09-11e5-b921-4318215bcbf6"
]);
?>
// Merge the customer records using customer UUIDs

api.MergeCustomers(&cm.MergeCustomersParams{
  From: cm.CustID{CustomerUUID: "cus_f466e33d-ff2b-4a11-8f85-417eb02157a7"},
  To:   cm.CustID{CustomerUUID: "cus_ba1ca03c-9d09-11e5-b921-4318215bcbf6"},
})
# Merge the customer records using customer UUIDs

chartmogul.Customer.merge(config, data={
    "from": {
        "customer_uuid": "cus_f466e33d-ff2b-4a11-8f85-417eb02157a7"
    },
    "into": {
        "customer_uuid": "cus_ba1ca03c-9d09-11e5-b921-4318215bcbf6"
    }
})

๐Ÿšง

Additional data for merged customers in an invoice

When an invoice is sent for a customer that has been merged, the invoice object is required to contain customer_external_id and data_source_uuid. These fields determine which customer of the merged records receives invoice data. Learn more about the Merge Customers endpoint.

Next Steps

Head over to your ChartMogul account and make use of Leads and Conversion charts.

Add contacts to your customers using the create a contact endpoint.

๐Ÿ‘

Make trial-to-paid conversion rates more meaningful with cohorts. Learn more on our help center.