> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zixflow.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Node.js-Specific Features

> Batching, flush lifecycle, and event emitters.

### Event batching

Events are queued and sent to `https://cdp.zixflow.com/v1/batch` by default:

```javascript theme={null}
import { Analytics } from '@zixflow/analytics-node'

const analytics = new Analytics({
  writeKey: 'YOUR_WRITE_KEY',
  maxEventsInBatch: 15,  // default 15
  flushInterval: 10000,  // default 10s
  maxRetries: 3,
  httpRequestTimeout: 10000
})
```

### Flushing events

Flush pending events before the process exits:

```javascript theme={null}
await analytics.closeAndFlush()

await analytics.closeAndFlush({ timeout: 5000 })

process.on('SIGTERM', async () => {
  await analytics.closeAndFlush()
  process.exit(0)
})
```

### Error handling and emitters

```javascript theme={null}
analytics.on('error', (err) => {
  console.error('Analytics error:', err)
})

analytics.on('http_request', (event) => {
  console.log('HTTP request:', event)
})

analytics.on('drained', () => {
  console.log('Queue drained')
})
```

Other useful events: `initialize`, `track`, `page`, `identify`, `group`, `alias`, `screen`, `register`, `deregister`, `call_after_close`.

### Callbacks

```javascript theme={null}
analytics.track(
  {
    userId: 'user@example.com',
    event: 'signup_completed'
  },
  (err, ctx) => {
    if (err) {
      console.error('Failed to track event:', err)
    } else {
      console.log('Event accepted:', ctx)
    }
  }
)
```

### Custom plugins

```javascript theme={null}
await analytics.register({
  name: 'Custom Plugin',
  type: 'enrichment',
  version: '1.0.0',
  isLoaded: () => true,
  load: async () => {},
  track: async (ctx) => ctx
})
```
