# How to create backend events with PostHog

It's important to keep track of events in your webapp so you can see what features are used and how they are used. While frontend event tracking is common, capturing backend events can provide deeper insights into your application's behavior, performance, and user patterns. With PostHog, it's quite easy to create events in your backend.

## Setting Up PostHog

First, install the PostHog Node.js library:

```bash
npm install posthog-node
# or
yarn add posthog-node
```

## Initializing PostHog

Initialize PostHog with your project API key:

```javascript
const { PostHog } = require('posthog-node')

const client = new PostHog(
    'phc_YOUR_API_KEY',
    { 
        host: 'https://app.posthog.com' // Optional: Use your self-hosted instance URL if applicable
    }
)
```

## Capturing Basic Events

The simplest way to capture an event is using the `capture` method:

```javascript
client.capture({
    distinctId: 'user_123',
    event: 'subscription_created',
    properties: {
        planType: 'premium',
        billingInterval: 'monthly',
        amount: 29.99
    }
})
```

## Best Practices for Backend Events

### 1\. Consistent Event Naming

Use a consistent naming convention for your events. A common pattern is:

* Noun\_Verb for state changes: `subscription_created`, `payment_failed`
    
* Verb\_Noun for actions: `generate_report`, `send_notification`
    

### 2\. Rich Properties

Include relevant properties that will be useful for analysis:

```javascript
client.capture({
    distinctId: 'user_123',
    event: 'api_request_completed',
    properties: {
        endpoint: '/api/v1/users',
        method: 'POST',
        responseTimeMs: 235,
        statusCode: 200,
        userAgent: req.headers['user-agent'],
        ipAddress: req.ip
    }
})
```

### 3\. Batch Processing

For high-volume events, use batch capturing to improve performance:

```javascript
const events = [
    {
        distinctId: 'user_123',
        event: 'item_purchased',
        properties: { itemId: '456', price: 29.99 }
    },
    {
        distinctId: 'user_123',
        event: 'checkout_completed',
        properties: { total: 29.99, itemsCount: 1 }
    }
]

await client.batchCapture(events)
```

## Advanced Features

### 1\. Feature Flags

You can evaluate feature flags in your backend code:

```javascript
const flagEnabled = await client.isFeatureEnabled('new_billing_flow', 'user_123')
if (flagEnabled) {
    // Roll out new billing logic
}
```

### 2\. Group Analytics

Track events at an organization level:

```javascript
// Identify a group
await client.groupIdentify({
    groupType: 'company',
    groupKey: 'company_123',
    properties: {
        name: 'Acme Corp',
        industry: 'Technology',
        employeeCount: 500
    }
})

// Capture event with group information
await client.capture({
    distinctId: 'user_123',
    event: 'project_created',
    properties: { projectName: 'New Project' },
    groups: { company: 'company_123' }
})
```

### 3\. Error Handling

Implement robust error handling to prevent event capture failures from affecting your application:

```javascript
try {
    await client.capture({
        distinctId: 'user_123',
        event: 'important_action',
        properties: { key: 'value' }
    })
} catch (error) {
    console.error('Failed to capture PostHog event:', error)
    // Consider adding to a retry queue
}
```

## Common Patterns and Use Cases

Here are some typical backend events you might want to track:

1. **Authentication Events**
    

```javascript
await client.capture({
    distinctId: 'user_123',
    event: 'login_attempted',
    properties: {
        method: 'password',
        success: true,
        userAgent: req.headers['user-agent'],
        ipAddress: req.ip
    }
})
```

2. **Background Job Events**
    

```javascript
await client.capture({
    distinctId: 'system',
    event: 'scheduled_job_completed',
    properties: {
        jobName: 'daily_report_generation',
        durationSeconds: 145,
        recordsProcessed: 1000,
        success: true
    }
})
```

3. **API Usage Events**
    

```javascript
await client.capture({
    distinctId: 'user_123',
    event: 'api_key_generated',
    properties: {
        keyType: 'read_only',
        expirationDays: 30,
        permissions: ['read_users', 'read_projects']
    }
})
```

## Shutdown

When your application is shutting down, make sure to close the PostHog client to ensure all events are sent:

```javascript
await client.shutdown()
```

## Using with Express.js

Here's an example of integrating PostHog with an Express.js middleware:

```javascript
const express = require('express')
const app = express()

// Middleware to track API requests
app.use(async (req, res, next) => {
    const startTime = Date.now()
    
    // Continue with the request
    next()
    
    // After the request is completed
    res.on('finish', async () => {
        try {
            await client.capture({
                distinctId: req.user?.id || 'anonymous',
                event: 'api_request',
                properties: {
                    path: req.path,
                    method: req.method,
                    statusCode: res.statusCode,
                    duration: Date.now() - startTime,
                    userAgent: req.headers['user-agent']
                }
            })
        } catch (error) {
            console.error('Failed to capture API request event:', error)
        }
    })
})
```

## Conclusion

Backend event tracking with PostHog in Node.js provides valuable insights into your application's behavior and usage patterns. By following these best practices and patterns, you can build a robust event tracking system that helps you make data-driven decisions about your product.

Remember to:

* Use consistent naming conventions
    
* Include relevant properties with each event
    
* Handle errors gracefully
    
* Use batch processing for high-volume events
    
* Properly shut down the client when your application terminates
    
* Leverage advanced features like feature flags and group analytics when appropriate
    

For more information, check out the [PostHog Node.js documentation](https://posthog.com/docs/libraries/node) for detailed API references and additional features.
