---
title: Event Tracking Integration
description: Track user behavior to trigger workflows
icon: Activity
---
## Overview
Track events from your application to trigger workflows and update contact data. Events like `user_signed_up`, `purchase_completed`, `feature_used` can start automated email sequences.
## Get your public key
1. Go to [Settings → General]({{DASHBOARD_URL}}/settings)
2. Copy your **Public Key** (starts with `pk_`)
Public keys are safe to use in client-side code.
## Basic event tracking
### JavaScript (client-side)
```javascript
await fetch('{{API_URL}}/v1/track', {
method: 'POST',
headers: {
'Authorization': `Bearer ${PLUNK_PUBLIC_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
event: 'button_clicked',
email: user.email,
data: {
buttonName: 'Get Started',
page: '/pricing'
}
})
});
```
### Node.js (server-side)
```javascript
await fetch('{{API_URL}}/v1/track', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.PLUNK_PUBLIC_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
event: 'user_signed_up',
email: user.email,
data: {
name: user.name,
plan: 'free',
signupDate: new Date().toISOString()
}
})
});
```
### Python
```python
import requests
import os
requests.post('{{API_URL}}/v1/track',
headers={
'Authorization': f'Bearer {os.environ["PLUNK_PUBLIC_KEY"]}',
'Content-Type': 'application/json'
},
json={
'event': 'purchase_completed',
'email': user.email,
'data': {
'orderId': order.id,
'total': order.total,
'items': order.items
}
}
)
```
## Common events to track
### User lifecycle
```javascript
// Signup
await trackEvent('user_signed_up', user.email, {
name: user.name,
source: 'google',
plan: 'free'
});
// Activation
await trackEvent('first_value_achieved', user.email, {
action: 'created_first_project',
timestamp: new Date().toISOString()
});
// Upgrade
await trackEvent('subscription_upgraded', user.email, {
fromPlan: 'free',
toPlan: 'premium',
mrr: 99
});
// Churn
await trackEvent('subscription_cancelled', user.email, {
reason: user.cancellationReason,
cancelledAt: new Date().toISOString()
});
```
### Product engagement
```javascript
// Feature usage
await trackEvent('feature_used', user.email, {
featureName: 'data_export',
timestamp: new Date().toISOString()
});
// Content interaction
await trackEvent('video_watched', user.email, {
videoId: 'intro-101',
duration: 300,
completed: true
});
// Settings changes
await trackEvent('settings_updated', user.email, {
setting: 'notifications',
value: 'enabled'
});
```
### E-commerce
```javascript
// Cart
await trackEvent('cart_abandoned', user.email, {
cartId: cart.id,
cartTotal: cart.total,
items: cart.items.map(i => i.name)
});
// Purchase
await trackEvent('purchase_completed', user.email, {
orderId: order.id,
total: order.total,
paymentMethod: 'credit_card'
});
// Review
await trackEvent('review_submitted', user.email, {
productId: product.id,
rating: 5
});
```
## Event naming conventions
**Use lowercase with underscores:**
- ✅ `user_signed_up`
- ✅ `purchase_completed`
- ❌ `UserSignedUp`
- ❌ `purchase-completed`
**Be specific:**
- ✅ `trial_started`
- ❌ `event`
**Use past tense:**
- ✅ `email_opened`
- ❌ `email_open`
## Event data best practices
**Keep data flat when possible:**
```javascript
// Good
{
name: 'John',
plan: 'premium',
mrr: 99
}
// Works but harder to use
{
user: {
profile: {
name: 'John'
}
}
}
```
**Use consistent types:**
```javascript
// Good - number for numeric values
{ total: 99.99 }
// Bad - string for numeric values
{ total: "99.99" }
```
**Use ISO dates:**
```javascript
// Good
{ signupDate: new Date().toISOString() }
// Okay but less flexible
{ signupDate: '2024-03-15' }
```
## Integrate with React
### Context provider
```javascript
// EventTrackingContext.js
import { createContext, useContext } from 'react';
const EventTrackingContext = createContext();
export function EventTrackingProvider({ children }) {
const trackEvent = async (event, data = {}) => {
const user = getCurrentUser(); // Your auth logic
if (!user?.email) return;
await fetch('{{API_URL}}/v1/track', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.NEXT_PUBLIC_PLUNK_PUBLIC_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
event,
email: user.email,
data: {
name: user.name,
...data
}
})
});
};
return (