Kissmetrics Setup | Blue Frog Docs

Kissmetrics Setup

Set up Kissmetrics analytics.

Overview

Kissmetrics is a behavior analytics and engagement platform focused on tracking individual user journeys across devices and sessions. Unlike pageview-centric analytics, Kissmetrics emphasizes person-based tracking, allowing you to analyze cohorts, funnels, and revenue attribution at the user level.

Key Capabilities:

  • Person-Based Tracking: Track individual users across devices and sessions
  • Behavioral Cohorts: Group users by actions taken or properties
  • Funnel Analysis: Measure conversion at each step of user flows
  • A/B Test Analysis: Compare behavior between experiment variants
  • Revenue Tracking: Attribute revenue to specific users and campaigns
  • Customer Journey Mapping: Visualize complete user paths

Architecture:

  • JavaScript Library: Client-side tracking via _kmq queue
  • API: Server-side event and people API
  • People & Events: Dual data model tracking both identity and actions
  • Properties: Custom attributes attached to people and events

Prerequisites

1. Kissmetrics Account Setup

Before implementation:

  • Active Kissmetrics Account: Sign up at kissmetrics.io
  • API Key: Found in Settings → Account (format: alphanumeric string)
  • Product Configuration: Define which product/site you're tracking
  • Separate Projects: Use different API keys for staging vs production

2. Implementation Planning

Define your tracking strategy:

  • Identity Strategy: How users will be identified (email, user ID, anonymous)
  • Core Events: Critical actions to track (signup, purchase, subscription)
  • User Properties: Attributes to store (plan type, signup date, LTV)
  • Funnel Definitions: Key conversion flows to measure
  • Revenue Attribution: How to track monetary value

3. Data Layer Design

Plan your event structure:

// Example event structure
_kmq.push(['record', 'Signed Up', {
  'Plan Type': 'Premium',
  'Signup Method': 'Google OAuth',
  'Trial Period': 14
}]);
  • Event Names: Descriptive, past-tense (e.g., "Viewed Product," "Completed Purchase")
  • Property Names: Human-readable with spaces and capitals
  • Property Values: Strings, numbers, or booleans
  • Reserved Properties: Avoid Kissmetrics reserved names

4. Privacy & Compliance

Consider data governance:

  • PII Handling: Decide which personal identifiers to collect
  • Consent Management: Integrate with CMP if required by jurisdiction
  • Data Retention: Configure how long Kissmetrics stores data
  • GDPR Compliance: Enable data deletion capabilities for user requests

Quick Start

1. Get API Key

  1. Log in to Kissmetrics at kissmetrics.io
  2. Navigate to Settings → Account
  3. Copy your API key (alphanumeric string)
  4. Store securely in environment variables

Never commit API keys to version control.

2. Install Tracking Code

Add the Kissmetrics JavaScript snippet to your site's <head> section:

<!DOCTYPE html>
<html>
  <head>
    <title>Your Site</title>

    <!-- Kissmetrics Tracking Code -->
    <script type="text/javascript">
      var _kmq = _kmq || [];
      var _kmk = _kmk || 'YOUR_API_KEY';
      function _kms(u){
        setTimeout(function(){
          var d = document, f = d.getElementsByTagName('script')[0],
          s = d.createElement('script');
          s.type = 'text/javascript'; s.async = true; s.src = u;
          f.parentNode.insertBefore(s, f);
        }, 1);
      }
      _kms('//scripts.kissmetrics.io/' + _kmk + '.js');
      _kms('//doug1izaerwt3.cloudfront.net/' + _kmk + '.1.js');
    </script>
    <!-- End Kissmetrics Tracking Code -->
  </head>
  <body>
    <!-- Your content -->
  </body>
</html>

Replace YOUR_API_KEY with your actual Kissmetrics API key.

Script Explanation:

  • _kmq: Global queue for tracking commands
  • _kmk: Your API key
  • _kms(): Asynchronous script loader
  • Two script URLs: Primary and fallback CDN

3. Identify Users

Once a user logs in or signs up, identify them:

// Identify by email (recommended)
_kmq.push(['identify', 'user@example.com']);

// Identify by user ID
_kmq.push(['identify', 'user-12345']);

// Set user properties
_kmq.push(['set', {
  'Name': 'Jane Doe',
  'Email': 'jane@example.com',
  'Plan': 'Premium',
  'Signup Date': '2024-01-15',
  'Monthly Spend': 99.99
}]);

Identity Best Practices:

  • Use a persistent identifier (email or database user ID)
  • Call identify as early as possible after login
  • Consistent identifier across all platforms (web, mobile, server)
  • Don't identify with temporary/session IDs

4. Track Events

Record user actions:

// Simple event
_kmq.push(['record', 'Viewed Homepage']);

// Event with properties
_kmq.push(['record', 'Viewed Product', {
  'Product ID': 'SKU-12345',
  'Product Name': 'Premium Subscription',
  'Product Price': 99.99,
  'Product Category': 'Subscriptions'
}]);

// Conversion event
_kmq.push(['record', 'Completed Purchase', {
  'Order ID': 'ORDER-789',
  'Order Total': 149.99,
  'Payment Method': 'Credit Card',
  'Items Count': 2
}]);

Event Naming Conventions:

  • Use past tense (Clicked, Viewed, Completed)
  • Be specific and descriptive
  • Use Title Case for readability
  • Avoid technical jargon in event names

5. Track Revenue

Kissmetrics provides dedicated revenue tracking:

// Track billing event with revenue
_kmq.push(['record', 'Billed', {
  'Billing Amount': 99.99,
  'Billing Description': 'Monthly Premium Plan',
  'Transaction ID': 'TXN-456'
}]);

// Track revenue without specific event name
_kmq.push(['trackSubmit', 'checkout-form', 'Completed Checkout']);
_kmq.push(['set', {
  'Revenue': 99.99
}]);

Revenue Tracking Methods:

  1. Billing Events: Use "Billed" event with amount
  2. Revenue Property: Set "Revenue" property on conversion events
  3. Custom Events: Track specific revenue events (upgrade, renewal)

Installation Methods

The standard implementation for most websites.

Basic Installation

<script type="text/javascript">
  var _kmq = _kmq || [];
  var _kmk = _kmk || 'YOUR_API_KEY';
  function _kms(u){
    setTimeout(function(){
      var d = document, f = d.getElementsByTagName('script')[0],
      s = d.createElement('script');
      s.type = 'text/javascript'; s.async = true; s.src = u;
      f.parentNode.insertBefore(s, f);
    }, 1);
  }
  _kms('//scripts.kissmetrics.io/' + _kmk + '.js');
  _kms('//doug1izaerwt3.cloudfront.net/' + _kmk + '.1.js');
</script>

Environment-Specific Configuration

Use server-side templating to inject the correct API key:

<!-- Node.js/Express -->
<script>
  var _kmq = _kmq || [];
  var _kmk = _kmk || '<%= process.env.KISSMETRICS_API_KEY %>';
  // ... rest of script
</script>

<!-- Ruby on Rails -->
<script>
  var _kmq = _kmq || [];
  var _kmk = _kmk || '<%= ENV['KISSMETRICS_API_KEY'] %>';
  // ... rest of script
</script>

<!-- PHP -->
<script>
  var _kmq = _kmq || [];
  var _kmk = _kmk || '<?php echo getenv('KISSMETRICS_API_KEY'); ?>';
  // ... rest of script
</script>

Delay Kissmetrics loading until consent granted:

<script>
  var _kmq = _kmq || [];

  // Only load Kissmetrics if user has consented
  if (userHasConsented()) {
    var _kmk = _kmk || 'YOUR_API_KEY';
    function _kms(u){
      setTimeout(function(){
        var d = document, f = d.getElementsByTagName('script')[0],
        s = d.createElement('script');
        s.type = 'text/javascript'; s.async = true; s.src = u;
        f.parentNode.insertBefore(s, f);
      }, 1);
    }
    _kms('//scripts.kissmetrics.io/' + _kmk + '.js');
    _kms('//doug1izaerwt3.cloudfront.net/' + _kmk + '.1.js');
  }

  function userHasConsented() {
    // Check your consent management platform
    return localStorage.getItem('analytics_consent') === 'granted';
  }
</script>

Method 2: Google Tag Manager

Deploy Kissmetrics through GTM for centralized management.

Step 1: Create Custom HTML Tag

  1. In GTM, navigate to Tags → New
  2. Tag Type: Custom HTML
  3. Paste the Kissmetrics snippet:
<script type="text/javascript">
  var _kmq = _kmq || [];
  var _kmk = _kmk || '{{Kissmetrics API Key}}';
  function _kms(u){
    setTimeout(function(){
      var d = document, f = d.getElementsByTagName('script')[0],
      s = d.createElement('script');
      s.type = 'text/javascript'; s.async = true; s.src = u;
      f.parentNode.insertBefore(s, f);
    }, 1);
  }
  _kms('//scripts.kissmetrics.io/' + _kmk + '.js');
  _kms('//doug1izaerwt3.cloudfront.net/' + _kmk + '.1.js');
</script>

Step 2: Create API Key Variable

  1. Navigate to Variables → New
  2. Variable Type: Lookup Table
  3. Input: {{Page Hostname}}
  4. Map hostnames to API keys:
    • localhostDEV_API_KEY
    • staging.yourdomain.comSTAGING_API_KEY
    • yourdomain.comPRODUCTION_API_KEY

Step 3: Configure Trigger

  • Trigger Type: Page View - DOM Ready
  • Fires On: All Pages
  • Priority: 100 (load early)

Step 4: Track Events via GTM

Create additional Custom HTML tags for events:

<script>
  if (typeof _kmq !== 'undefined') {
    _kmq.push(['record', '{{Event Name}}', {
      'Event Category': '{{Event Category}}',
      'Event Label': '{{Event Label}}',
      'Event Value': {{Event Value}}
    }]);
  }
</script>

Trigger: Custom Event matching your data layer

Step 5: Identify Users via GTM

<script>
  if (typeof _kmq !== 'undefined' && '{{User Email}}') {
    _kmq.push(['identify', '{{User Email}}']);
    _kmq.push(['set', {
      'Name': '{{User Name}}',
      'Plan': '{{User Plan}}',
      'Signup Date': '{{User Signup Date}}'
    }]);
  }
</script>

Trigger: Custom Event on login/page load when user is authenticated

Method 3: Server-Side API

For backend event tracking and sensitive data.

HTTP API Endpoint

POST https://trk.kissmetrics.io/e

Required Parameters:

  • _k: API key
  • _p: Person identifier
  • _n: Event name

Optional Parameters:

  • _t: Timestamp (Unix epoch)
  • _d: Event property (can be repeated)

Node.js Implementation

const axios = require('axios');

async function trackKissmetricsEvent(personId, eventName, properties = {}) {
  const apiKey = process.env.KISSMETRICS_API_KEY;
  const baseUrl = 'https://trk.kissmetrics.io/e';

  const params = {
    _k: apiKey,
    _p: personId,
    _n: eventName,
    _t: Math.floor(Date.now() / 1000)
  };

  // Add properties
  Object.keys(properties).forEach(key => {
    params[key] = properties[key];
  });

  try {
    await axios.get(baseUrl, { params });
    return true;
  } catch (error) {
    console.error('Kissmetrics tracking error:', error);
    return false;
  }
}

// Usage
await trackKissmetricsEvent('user@example.com', 'Server Signup', {
  'Plan': 'Premium',
  'Method': 'API',
  'Revenue': 99.99
});

Python Implementation

import requests
import time

def track_kissmetrics_event(person_id, event_name, properties=None):
    api_key = os.environ.get('KISSMETRICS_API_KEY')
    base_url = 'https://trk.kissmetrics.io/e'

    params = {
        '_k': api_key,
        '_p': person_id,
        '_n': event_name,
        '_t': int(time.time())
    }

    if properties:
        params.update(properties)

    try:
        response = requests.get(base_url, params=params)
        return response.status_code == 200
    except Exception as e:
        print(f'Kissmetrics error: {e}')
        return False

# Usage
track_kissmetrics_event('user@example.com', 'Server Signup', {
    'Plan': 'Premium',
    'Method': 'API',
    'Revenue': 99.99
})

Ruby Implementation

require 'net/http'
require 'uri'

def track_kissmetrics_event(person_id, event_name, properties = {})
  api_key = ENV['KISSMETRICS_API_KEY']
  base_url = 'https://trk.kissmetrics.io/e'

  params = {
    '_k' => api_key,
    '_p' => person_id,
    '_n' => event_name,
    '_t' => Time.now.to_i
  }.merge(properties)

  uri = URI(base_url)
  uri.query = URI.encode_www_form(params)

  begin
    Net::HTTP.get_response(uri)
    true
  rescue => e
    puts "Kissmetrics error: #{e.message}"
    false
  end
end

# Usage
track_kissmetrics_event('user@example.com', 'Server Signup', {
  'Plan' => 'Premium',
  'Method' => 'API',
  'Revenue' => 99.99
})

Set People Properties via API

async function setKissmetricsProperties(personId, properties) {
  const apiKey = process.env.KISSMETRICS_API_KEY;
  const baseUrl = 'https://trk.kissmetrics.io/s';

  const params = {
    _k: apiKey,
    _p: personId,
    _t: Math.floor(Date.now() / 1000)
  };

  Object.keys(properties).forEach(key => {
    params[key] = properties[key];
  });

  await axios.get(baseUrl, { params });
}

// Usage
await setKissmetricsProperties('user@example.com', {
  'Name': 'Jane Doe',
  'Plan': 'Premium',
  'LTV': 1299.99,
  'Last Login': '2024-12-26'
});

Framework Integrations

React

Custom Hook

// hooks/useKissmetrics.js
import { useEffect } from 'react';

export function useKissmetricsPageview() {
  useEffect(() => {
    if (typeof window !== 'undefined' && window._kmq) {
      window._kmq.push(['record', 'Viewed Page', {
        'Page Path': window.location.pathname,
        'Page Title': document.title
      }]);
    }
  }, []);
}

export function useKissmetrics() {
  const identify = (userId, traits = {}) => {
    if (typeof window !== 'undefined' && window._kmq) {
      window._kmq.push(['identify', userId]);
      if (Object.keys(traits).length > 0) {
        window._kmq.push(['set', traits]);
      }
    }
  };

  const track = (eventName, properties = {}) => {
    if (typeof window !== 'undefined' && window._kmq) {
      window._kmq.push(['record', eventName, properties]);
    }
  };

  const set = (properties) => {
    if (typeof window !== 'undefined' && window._kmq) {
      window._kmq.push(['set', properties]);
    }
  };

  return { identify, track, set };
}

// Usage in component
import { useKissmetrics, useKissmetricsPageview } from './hooks/useKissmetrics';

function ProductPage() {
  useKissmetricsPageview();
  const { track } = useKissmetrics();

  const handleAddToCart = () => {
    track('Added to Cart', {
      'Product ID': 'SKU-123',
      'Product Price': 99.99
    });
  };

  return <button onClick={handleAddToCart}>Add to Cart</button>;
}

React Router Integration

// App.js
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

function App() {
  const location = useLocation();

  useEffect(() => {
    if (typeof window !== 'undefined' && window._kmq) {
      window._kmq.push(['record', 'Viewed Page', {
        'Page Path': location.pathname,
        'Page Title': document.title
      }]);
    }
  }, [location]);

  return <Routes />;
}

Next.js

Pages Router

// pages/_app.js
import { useEffect } from 'react';
import { useRouter } from 'next/router';

function MyApp({ Component, pageProps }) {
  const router = useRouter();

  useEffect(() => {
    const handleRouteChange = (url) => {
      if (typeof window !== 'undefined' && window._kmq) {
        window._kmq.push(['record', 'Viewed Page', {
          'Page Path': url,
          'Page Title': document.title
        }]);
      }
    };

    router.events.on('routeChangeComplete', handleRouteChange);
    return () => router.events.off('routeChangeComplete', handleRouteChange);
  }, [router.events]);

  return <Component {...pageProps} />;
}

App Router

// app/providers.js
'use client';

import { usePathname } from 'next/navigation';
import { useEffect } from 'react';

export function AnalyticsProvider({ children }) {
  const pathname = usePathname();

  useEffect(() => {
    if (typeof window !== 'undefined' && window._kmq) {
      window._kmq.push(['record', 'Viewed Page', {
        'Page Path': pathname,
        'Page Title': document.title
      }]);
    }
  }, [pathname]);

  return <>{children}</>;
}

Vue.js

// plugins/kissmetrics.js
export default {
  install: (app) => {
    app.config.globalProperties.$km = {
      identify: (userId, traits = {}) => {
        if (typeof window !== 'undefined' && window._kmq) {
          window._kmq.push(['identify', userId]);
          if (Object.keys(traits).length > 0) {
            window._kmq.push(['set', traits]);
          }
        }
      },
      track: (eventName, properties = {}) => {
        if (typeof window !== 'undefined' && window._kmq) {
          window._kmq.push(['record', eventName, properties]);
        }
      },
      set: (properties) => {
        if (typeof window !== 'undefined' && window._kmq) {
          window._kmq.push(['set', properties]);
        }
      }
    };
  }
};

// main.js
import kissmetricsPlugin from './plugins/kissmetrics';
app.use(kissmetricsPlugin);

// Component usage
this.$km.track('Button Clicked', {
  'Button ID': 'signup-cta'
});

Advanced Features

Automatic Event Tracking

Form Submissions

// Track all form submissions
_kmq.push(function() {
  document.querySelectorAll('form').forEach(form => {
    form.addEventListener('submit', function(e) {
      _kmq.push(['record', 'Submitted Form', {
        'Form ID': this.id || 'unknown',
        'Form Action': this.action,
        'Form Method': this.method
      }]);
    });
  });
});
// Track outbound link clicks
_kmq.push(['trackClick', 'outbound-link', 'Clicked Outbound Link']);

// Track specific button clicks
_kmq.push(['trackClick', 'signup-button', 'Clicked Signup Button']);

Form Submit Tracking

// Track form submission
_kmq.push(['trackSubmit', 'signup-form', 'Submitted Signup Form']);

Aliasing Identities

When a user transitions from anonymous to known:

// Before signup: tracked as anonymous (automatic)
// After signup: identify with email
_kmq.push(['identify', 'user@example.com']);

// Alias connects previous anonymous activity
_kmq.push(['alias', 'user@example.com', 'anonymous-visitor-id']);

Best Practice: Kissmetrics automatically handles most aliasing, but use explicitly when:

  • Merging duplicate profiles
  • Consolidating pre/post signup activity
  • Linking accounts across platforms

Custom Properties

// Set user-level properties
_kmq.push(['set', {
  'Account Type': 'Business',
  'Employee Count': '50-100',
  'Industry': 'SaaS',
  'Signup Source': 'Google Ads',
  'Trial End Date': '2024-02-01'
}]);

// Properties persist across sessions
// Update properties as they change
_kmq.push(['set', {
  'Last Login': new Date().toISOString(),
  'Login Count': 47,
  'Last Feature Used': 'Reports'
}]);

Verification & Testing

1. Live Event Stream

View events in real-time:

  1. Log in to Kissmetrics
  2. Navigate to Live tab
  3. Trigger events on your site
  4. Verify events appear with correct properties

2. Browser Console Testing

// Check if Kissmetrics loaded
typeof _kmq !== 'undefined'
// Should return: true

// Manually fire test event
_kmq.push(['record', 'Test Event', {
  'Test Property': 'Test Value',
  'Timestamp': new Date().toISOString()
}]);

// Check queue
console.log(_kmq);

3. Network Inspector

Monitor network requests:

  1. Open DevTools (F12)
  2. Navigate to Network tab
  3. Filter for "kissmetrics" or "trk.kissmetrics"
  4. Trigger events
  5. Verify requests to https://trk.kissmetrics.io/

Successful request format:

https://trk.kissmetrics.io/e?_k=API_KEY&_p=user@example.com&_n=Event+Name&Property=Value&_t=timestamp

4. People Profiles

Verify user data:

  1. Navigate to People in Kissmetrics
  2. Search for test user identifier
  3. Review events timeline
  4. Confirm properties are set correctly

Troubleshooting

Events Not Appearing

Problem: Events don't show in Kissmetrics

Solutions:

  1. Verify API key is correct for environment
  2. Check browser console for JavaScript errors
  3. Ensure _kmq variable exists before pushing
  4. Check ad blockers aren't blocking Kissmetrics scripts
  5. Verify network requests reaching kissmetrics.io

Duplicate Identities

Problem: Same user appears as multiple profiles

Solutions:

  1. Ensure consistent identifier across sessions
  2. Call identify with same ID every session
  3. Use aliasing to merge profiles
  4. Avoid identifying with session IDs or cookies

Missing Properties

Problem: Event properties don't appear

Solutions:

  1. Verify property names don't have typos
  2. Check property values aren't undefined/null
  3. Ensure set called before event recording
  4. Properties must be strings, numbers, or booleans

Cross-Domain Tracking Issues

Problem: Users tracked separately across domains

Solutions:

  1. Use same API key across all domains
  2. Implement consistent identification strategy
  3. Pass user ID via URL parameters if needed
  4. Call identify on each domain

Security Best Practices

1. API Key Protection

// Good - Server-side injection
var _kmk = _kmk || '<%= ENV['KISSMETRICS_API_KEY'] %>';

// Bad - Hardcoded in client code
var _kmk = _kmk || 'abc123def456'; // Don't do this

2. PII Handling

// Acceptable - Email as identifier
_kmq.push(['identify', 'user@example.com']);

// Bad - Sending sensitive PII in properties
_kmq.push(['set', {
  'SSN': '123-45-6789', // Never do this
  'Credit Card': '4111...', // Never do this
  'Password': 'password123' // Never do this
}]);

// Good - Non-sensitive properties
_kmq.push(['set', {
  'Plan Type': 'Premium',
  'Account Age Days': 365,
  'Feature Usage': 'High'
}]);

3. Server-Side for Sensitive Events

// Client-side: Track initiation only
_kmq.push(['record', 'Started Checkout']);

// Server-side: Track completion with revenue
await trackKissmetricsEvent('user@example.com', 'Completed Purchase', {
  'Order ID': 'ORDER-123',
  'Revenue': 149.99,
  'Items': 3
});

Validation Checklist

Before going live:

  • Correct API key configured per environment
  • Kissmetrics script loads successfully
  • Test events appear in Live stream
  • User identification working correctly
  • Event properties structured correctly
  • Revenue tracking implemented for purchases
  • Funnel events firing in correct sequence
  • No PII exposed in event properties
  • Cross-domain tracking works if needed
  • Server-side tracking verified
  • Team has access to Kissmetrics account
  • Critical funnels defined in Kissmetrics
  • Cohorts configured for analysis

Guides

Continue with detailed implementation guides:

Open Decisions & Follow-Ups

Document these for your implementation:

  1. Identity Strategy

    • What identifier to use (email vs user ID)?
    • How to handle pre-login activity?
    • Cross-platform identity resolution?
  2. Event Taxonomy

    • Which events are critical to track?
    • Naming conventions to standardize?
    • Event property requirements?
  3. Revenue Attribution

    • How to track different revenue types?
    • Attribution model (first-touch, last-touch, multi-touch)?
    • Subscription vs one-time purchase tracking?
  4. Privacy & Compliance

    • Consent management requirements?
    • Data retention policies?
    • User data deletion process?
  5. Reporting & Analysis

    • Key funnels to monitor?
    • Cohort definitions?
    • A/B test tracking requirements?
// SYS.FOOTER