Skip to content

Custom Metrics and Events

⏱ 20 minutes intermediate

Built-in metrics like clicks and pageviews cover common scenarios. But most businesses measure success through actions unique to their product — adding items to a cart, completing an onboarding step, generating a lead, or reaching a paywall. Custom events let you track any action and use it as an experiment metric.

The flow has three parts:

  1. Create the event in the Optimizely UI — this defines the event key and makes it available as a metric
  2. Track the event in your code — fire the event when the user performs the action
  3. Attach the event as a metric to an experiment — Optimizely measures the event rate across variations

Events are identified by a unique event key (e.g., add_to_cart, lead_submitted). The key must match exactly between the UI configuration and your tracking code.

  1. Navigate to Events in the left sidebar
  2. Click Create New Event
  3. Choose the event type:
    • Click event — Tracks clicks on a CSS selector (no code needed)
    • Custom event — Tracks a programmatically fired event (requires code)
    • Pageview event — Tracks visits to a URL pattern
  4. For custom events, enter the event key (e.g., checkout_started)
  5. Add a description for team reference
  6. Click Save
  1. Navigate to Events in the left sidebar
  2. Click Create New Event
  3. Enter the event key
  4. Add a description
  5. Click Save

The event is now available to attach to any experiment in the project.

Fire events using the Optimizely snippet API. This call sends the event to Optimizely’s event processor.

Track events in Web Experimentation
javascript
// Basic event
window.optimizely = window.optimizely || [];
window.optimizely.push({
  type: 'event',
  eventName: 'checkout_started',
});

// Event with revenue (in cents)
window.optimizely.push({
  type: 'event',
  eventName: 'purchase_completed',
  tags: {
    revenue: 7999, // $79.99 in cents
    value: 79.99,
  },
});

// Event with custom tags
window.optimizely.push({
  type: 'event',
  eventName: 'product_viewed',
  tags: {
    category: 'electronics',
    product_id: 'SKU-12345',
  },
});

Use the SDK’s trackEvent method. The event is sent along with the user context for proper attribution.

Track events in Feature Experimentation
javascript
import { createInstance } from '@optimizely/optimizely-sdk';

const optimizely = createInstance({ sdkKey: 'YOUR_SDK_KEY' });
await optimizely.onReady();

const user = optimizely.createUserContext('user-456', {
  plan: 'premium',
});

// Basic event
user.trackEvent('checkout_started');

// Event with revenue
user.trackEvent('purchase_completed', {
  revenue: 7999,
  value: 79.99,
});
python
from optimizely import optimizely

client = optimizely.Optimizely(sdk_key='YOUR_SDK_KEY')
user = client.create_user_context('user-456', {
    'plan': 'premium',
})

# Basic event
user.track_event('checkout_started')

# Event with revenue
user.track_event('purchase_completed', event_tags={
    'revenue': 7999,
    'value': 79.99,
})
csharp
using OptimizelySDK;

var optimizely = OptimizelyFactory.NewDefaultInstance("YOUR_SDK_KEY");
var user = optimizely.CreateUserContext("user-456", new UserAttributes
{
    { "plan", "premium" },
});

// Basic event
user.TrackEvent("checkout_started");

// Event with revenue
user.TrackEvent("purchase_completed", new EventTags
{
    { "revenue", 7999 },
    { "value", 79.99 },
});
  1. Open your experiment and navigate to the Metrics tab
  2. Click Add Metric
  3. Select the custom event from the event picker
  4. Configure the metric settings:
    • Direction — Increase (higher is better) or Decrease (lower is better)
    • Aggregation — Unique conversions, total conversions, or revenue sum
    • Role — Primary or secondary metric
  5. Click Save

Event tags carry metadata alongside the event. Two tags have special meaning:

TagPurposeFormat
revenueMonetary value for revenue metricsInteger in cents (e.g., 4999 for $49.99)
valueNumeric value for non-revenue numeric metricsFloat (e.g., 49.99)

All other tags are stored as metadata and available in Data Lab for segmentation but do not affect metric calculations.

Common mistake: Sending revenue in dollars instead of cents. If your revenue metric shows values 100x too large, check the unit.

Events are scoped to a project. If you run experiments across multiple projects, create the event in each project with the same event key.

Consistent naming makes events easier to find and reduces duplicates.

PatternExample
{action}_{object}click_cta, view_pricing, submit_form
{page}_{action}checkout_started, onboarding_completed
{funnel_stage}_{action}awareness_signup, activation_first_use

Avoid generic names like event1 or click. They become indistinguishable as your event library grows.

If you use Google Tag Manager or a similar tool, fire events from tags instead of application code.

  1. Create a GTM tag of type Custom HTML
  2. Add the event tracking code (see Web Experimentation example above)
  3. Set the trigger to the user action you want to track (e.g., form submission, button click)
  4. Publish the tag

This approach works for Web Experimentation. Feature Experimentation requires SDK-level tracking.

  1. Open developer tools on a page with the Optimizely snippet
  2. Trigger the action that fires your event
  3. Check the Network tab for a request to logx.optimizely.com
  4. The request payload includes the event key and any tags

Enable debug logging in the SDK to see event dispatch messages.

const optimizely = createInstance({
sdkKey: 'YOUR_SDK_KEY',
logLevel: 'DEBUG',
});

Look for log entries containing Dispatching event followed by your event key.

IssueCauseFix
Metric shows zero conversionsEvent key mismatch between UI and codeVerify the exact event key string in both places
Revenue metric shows wrong valuesRevenue sent in dollars instead of centsMultiply by 100 before sending
Events fire but do not appear in resultsEvent not attached as a metric on the experimentAdd the event as a metric in the experiment configuration
Duplicate events countedEvent fires multiple times per user actionAdd deduplication logic or use “unique conversions” aggregation
Events from tag manager not trackedOptimizely snippet loads after the tag firesEnsure the snippet loads before your tag manager fires event tags