ChartMogul Developer Hub

Welcome to the ChartMogul Developer Hub. You'll find comprehensive guides and documentation to help you start working with ChartMogul as quickly as possible, as well as support if you get stuck. Let's jump right in!

Get Started    

Tracking leads and free trials

This tutorial describes how you can track leads and free-trials in your ChartMogul account using our API. Tracking leads and free-trials allows for the following charts and metrics to become available.

Chart
Description

Leads

The number of new leads created over time.

Free trials

The number of new free trials started over time.

Trial-to-paid conversion rate

The percentage of free trials that have converted to active paying customers over time.

Average sales cycle length

The average number of days taken for a lead to convert into an active paying customer.

Tracking leads and free trials works a little differently depending on how you currently import your customer billing data.

  • If you use ChartMogul's Import API to import your customer billing data, then refer to this section.
  • If you manage leads and trials outside of your billing system, or use PayPal to import your customer billing data, then refer to this section.
  • If you use one of our native integrations (Stripe, Braintree, Recurly or Chargify) to manage your subscription billing and free trials, then ChartMogul will automatically import the necessary data to populate the Free trials and Trial-to-paid conversion rate charts.
  • If you have leads (without trials) which you also want to track in ChartMogul then refer to this section, and skip step 3 where free trial start dates are updated.

For Import API users

When using the Import API to import your customers into ChartMogul, all you have to do in order to track leads and free trials is start importing both your paying customers and your leads and/or trials and including two new fields on all 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_ACCOUNT_TOKEN:YOUR_SECRET_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, make sure that you populate these timestamps for customers that you have already imported into ChartMogul. Use our endpoint for updating a customer to set these timestamps.

# 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_ACCOUNT_TOKEN:YOUR_SECRET_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 are all set to track leads, trials and trial-to-paid conversion rates in ChartMogul.

How to correctly track inbound leads that start as free trials?

For many SaaS businesses, inbound leads that start as free trials can constitute a significant chunk of leads. For such leads, you can 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 as well, so that both fields have the same timestamp. This will appropriately represent leads that started as free trials.

Set lead and free trial timestamps upon creation

We highly recommend that you import leads and free trials into your ChartMogul account as soon as they are created in your CRM or internal backend. This will ensure that you have the most accurate real-time measurement of your overall trial-to-paid conversion rate, and sales cycle length.

For users managing leads and trials outside their billing systems, or users of PayPal

You can enable leads and trials charts with a little bit of work to integrate with our API, and by using our Merge Customers feature.

Let's imagine that:

  • You met Adam Smith at a conference, and he's interested in your product. You then created a lead record for him in your CRM on January 5th, 2016.
  • After some 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, via your Stripe subscriptions system.

Note - For the purposes of this example, we are using the following UUIDs,

The "Leads" 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 track Adam’s journey and enable reporting in ChartMogul, follow these steps.

1. Create a data source to track leads in ChartMogul

The first step is to create a data source in ChartMogul purely to track all leads, including Adam Smith. You can do so by following these steps.

  • Go to Admin > Data sources
  • Click New data source
  • Choose an appropriate name for the data source, like "Leads"
  • Choose Import API as the system type
  • Click on the Next button

In the next page, a uniquely generated UUID will be displayed for this data source. Make a note of this UUID for next steps.

2. Create the customer

Next, create customers in ChartMogul as and when leads are created in your CRM or internal backend system. For Adam Smith, you would create a customer record in ChartMogul on January 5th, 2016. Use the data source that you have created in the previous step for tracking leads.

Set the external_id for this customer record as the unique identifier from your CRM or internal backend system. For Adam Smith, let us say the unique identifier in your CRM 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_ACCOUNT_TOKEN:YOUR_SECRET_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 the free trial is started

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

  • you do not offer free trials of your product or service, or
  • you manage subscription trials using Stripe, Braintree, Recurly or Chargify, or
  • your only source of leads is through inbound trials, and you have set free_trial_started_at in the previous step.
# 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_ACCOUNT_TOKEN:YOUR_SECRET_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 for the customer

When Adam pays for the monthly subscription on February 25th, 2016, we will receive a webhook with this information from Stripe. We will create a new customer record for Adam under the Stripe data source that you have created in your ChartMogul account and list it as an "Active" customer.

When you receive notification of successful payment from Stripe to your servers, 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_ACCOUNT_TOKEN:YOUR_SECRET_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_ACCOUNT_TOKEN:YOUR_SECRET_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"
})

Note on customer retrieval latency

It can take ChartMogul up to ten minutes to process the webhook 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 with the billing system, then please write to us at [email protected] .

When you retrieve the above records from the API, we will return UUIDs for each record. Use these customer UUIDs of the lead and paying customer records to merge them.

5. Merge the lead and paying customer records

Now that you have the customer UUIDs of the two records of Adam Smith in your ChartMogul account, you can now 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 <token>:<secret>
       -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"
    }
})

Leads and trials charts

Once you complete the setup above, you can head over to your ChartMogul account and make use of the following charts.

Hot tip - Make the most of the trial-to-paid conversion rate chart by analyzing them in cohorts. Learn how in this help center article.