Collecting Events

Flywheel supports two primary methods for collecting in-app user events:
  1. PostHog Integration (Recommended)
  2. Segment Integration
We generally recommend starting with PostHog due to its more favorable pricing model and superior platform features.

User Profile Management

Both Segment and PostHog integrations process user profiles in accordance with their respective SDK/API conventions. When a user first signs in or signs up, an identify call is made to associate user data with their profile.

Supported User Properties

All properties in Flywheel use snake_case naming convention. The following properties can be passed with any event to enrich user profiles:
  • first_name - User’s first name
  • last_name - User’s last name
  • email - User’s email address
  • primary_email - Primary email address (automatically managed by Flywheel)
  • phone - User’s phone number
  • primary_phone - Primary phone number (automatically managed by Flywheel)
  • stripe_customer_id - Associated Stripe customer ID
  • anonymous_id - Anonymous identifier
Flywheel automatically sets the first email or phone number found for a user as their primary contact method. All subsequent emails and phone numbers are stored but not set as primary. You can override the primary contact method at any time by explicitly passing primary_email or primary_phone - this will update the primary while maintaining a record of all previous contact information.

Why PostHog?

  • More favorable pricing model
  • Rich feature set
  • Better platform capabilities
  • Open-source foundation

Example Implementation

import posthog from 'posthog-js';

// Initialize PostHog
posthog.init('your-project-api-key', {
	api_host: 'https://app.posthog.com',
});

// Identify a user
posthog.identify('user_123', {
	email: 'user@example.com',
	first_name: 'John',
	last_name: 'Doe',
	plan_type: 'premium',
});

// Track an event
posthog.capture('subscription_created', {
	plan_type: 'premium',
	amount: 99,
	currency: 'USD',
});

Setting Up PostHog Data Forwarding

To start sending your PostHog event data to Flywheel, follow these steps:
  1. Enable Data Pipeline
    • Navigate to the Data Pipeline section in your PostHog dashboard
    • Enable the Data Pipeline if not already enabled
  2. Configure HTTP Webhook
    • Go to the Destinations section
    • Click “New Destination”
    • Select “HTTP Webhook”
  3. Configure Webhook Settings
    • Webhook URL:
      https://api.flywheel.cx/posthog/event-receiver
      
    • Method: Leave as default (POST)
    • JSON Body: Leave as default PostHog value
    {
    	"event": "{event}",
    	"person": "{person}"
    }
    
    PostHog Webhook Configuration
  4. Add Required Headers
    • Add the following headers:
      • Auth-Type: api
      • Authorization: your-flywheel-write-api-key
    • Leave the Content-Type header as the PostHog default (application/json; charset=utf-8)
  5. Enable the Integration
    • Save your configuration
    • Enable the webhook
    • Your events should now start appearing in your Flywheel dashboard

Segment Integration

Example Implementation

import Analytics from 'analytics-node';

const analytics = new Analytics('your-write-key');

// Identify a user
analytics.identify({
	userId: 'user_123',
	traits: {
		email: 'user@example.com',
		first_name: 'John',
		last_name: 'Doe',
		plan_type: 'premium',
	},
});

// Track an event
analytics.track({
	userId: 'user_123',
	event: 'subscription_created',
	properties: {
		plan_type: 'premium',
		amount: 99,
		currency: 'USD',
	},
});

Setting Up Segment Data Forwarding

To start sending your Segment event data to Flywheel, follow these steps:
  1. Access Segment Dashboard
    • Navigate to your Segment dashboard
    • Go to the Destinations page
    • Click “Add Destination”
  2. Create Function
    • Select the “Functions” tab at the top of the destinations page
    • Click “New Function”
    • Select “Destination Function” type
    • Click “Next” to build the function
  3. Add Function Code
    • Replace the default code with the following:
// Learn more about destination functions API at
// https://segment.com/docs/connections/destinations/destination-functions

/**
 * Handle track event
 * @param  {SegmentTrackEvent} event
 * @param  {FunctionSettings} settings
 */
async function onTrack(event, settings) {
	// Learn more at https://segment.com/docs/connections/spec/track/
	console.log('sending event');
	const endpoint = 'https://api.flywheel.cx/segment/event-receiver';
	let response;

	try {
		response = await fetch(endpoint, {
			method: 'POST',
			headers: {
				Authorization: `${settings.apiKey}`,
				'Auth-Type': 'api',
				'Content-Type': 'application/json',
			},
			body: JSON.stringify(event),
		});
		console.log(response);
	} catch (error) {
		console.log(error);
		// Retry on connection error
		throw new RetryError(error.message);
	}

	if (response.status >= 500 || response.status === 429) {
		// Retry on 5xx (server errors) and 429s (rate limits)
		throw new RetryError(`Failed with ${response.status}`);
	}
}

/**
 * Handle identify event
 * @param  {SegmentIdentifyEvent} event
 * @param  {FunctionSettings} settings
 */
async function onIdentify(event, settings) {
	// Learn more at https://segment.com/docs/connections/spec/identify/
	const endpoint = 'https://api.flywheel.cx/segment/event-receiver';
	let response;

	try {
		response = await fetch(endpoint, {
			method: 'POST',
			headers: {
				Authorization: `${settings.apiKey}`,
				'Auth-Type': 'api',
				'Content-Type': 'application/json',
			},
			body: JSON.stringify(event),
		});
	} catch (error) {
		// Retry on connection error
		throw new RetryError(error.message);
	}

	if (response.status >= 500 || response.status === 429) {
		// Retry on 5xx (server errors) and 429s (rate limits)
		throw new RetryError(`Failed with ${response.status}`);
	}
}
  1. Configure Settings
    • Navigate to the Settings tab on the right side of the code editor
    • Click “Add Setting”
    • Configure the setting:
      • Label: apiKey
      • Name: apiKey
      • Value: Your Flywheel API key
Segment API Key Setting
  1. Test and Deploy
    • Use Segment’s Function Tester to verify event forwarding
    • Once testing is successful, save and deploy the function
Your Segment events should now start flowing into your Flywheel dashboard.

Best Practices

User Identification

  1. Always call identify when a user signs up or logs in
  2. Include essential user properties in the identify call
  3. Use consistent user IDs across your application
  4. Pass relevant custom properties to enrich user profiles

Troubleshooting

Common issues and solutions:
  1. Events not appearing
    • Verify API keys are correct
    • Check integration configuration
    • Ensure proper initialization
  2. User profiles not updating
    • Verify identify calls are being made
    • Check property names use snake_case format
    • Ensure user IDs are consistent
  3. Missing event properties
    • Validate event payload structure
    • Check properties use snake_case format
    • Verify property names match documentation
Need help? Contact support@flywheel.cx