Best Practices

Recommended patterns and approaches for using Appizer effectively

Follow these guidelines to get the most out of Appizer.

Event Tracking

Use Consistent Event Naming

DO: Use snake_case and descriptive names

appizer.track({ event: 'user_signup_completed' })
appizer.track({ event: 'product_added_to_cart' })

DON'T: Use inconsistent or vague names

appizer.track({ event: 'signup' })
appizer.track({ event: 'ProductAddedToCart' })

Include Relevant Properties

DO: Add context that helps with segmentation

appizer.track({
  event: 'purchase_completed',
  properties: {
    amount: 99.99,
    currency: 'USD',
    product_category: 'electronics',
    payment_method: 'credit_card',
  },
})

DON'T: Track events without context

appizer.track({ event: 'purchase_completed' })

Property naming

Use snake_case for property names and keep them consistent across events.

Batch Events When Possible

For high-volume scenarios, use batch tracking:

await appizer.batchTrack([
  { event: 'page_view', userId: 'user_1', properties: { page: '/home' } },
  { event: 'page_view', userId: 'user_2', properties: { page: '/products' } },
  { event: 'page_view', userId: 'user_3', properties: { page: '/about' } },
])

Performance benefit

Batch tracking reduces API calls by up to 90% and improves throughput.

User Management

Identify Users Early

Identify users as soon as you have their information:

appizer.identify({
  userId: 'user_123',
  traits: {
    email: 'user@example.com',
    name: 'John Doe',
    plan: 'pro',
  },
})

Use Aliases for Anonymous Users

Track anonymous users, then alias when they sign up:

const anonymousId = generateAnonymousId()
appizer.track({ event: 'page_view', anonymousId })

appizer.alias({
  userId: 'user_123',
  previousId: anonymousId,
})

Keep User Profiles Updated

Update user traits when they change:

appizer.identify({
  userId: 'user_123',
  traits: {
    plan: 'enterprise',
    last_login: new Date().toISOString(),
  },
})

API Usage

Handle Rate Limits Gracefully

Implement exponential backoff:

async function trackWithRetry(event, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      return await appizer.track(event)
    } catch (error) {
      if (error.status === 429) {
        const delay = Math.pow(2, i) * 1000
        await new Promise(resolve => setTimeout(resolve, delay))
      } else {
        throw error
      }
    }
  }
}

Rate limits

Default rate limit is 1000 requests per minute. Contact support for higher limits.

Use Appropriate Timeouts

Set reasonable timeouts for API calls:

const appizer = new Appizer({
  apiKey: process.env.APPIZER_API_KEY,
  timeout: 5000,
})

Validate Data Before Sending

Always validate data before making API calls:

function validateEvent(event) {
  if (!event.event || typeof event.event !== 'string') {
    throw new Error('Event name is required and must be a string')
  }
  if (!event.userId && !event.anonymousId) {
    throw new Error('Either userId or anonymousId is required')
  }
  return true
}

Security

Never Expose API Keys

DO: Use environment variables

const appizer = new Appizer({
  apiKey: process.env.APPIZER_API_KEY,
})

DON'T: Hardcode API keys

const appizer = new Appizer({
  apiKey: 'sk_live_abc123...',
})

Use Server-Side SDKs for Sensitive Operations

Keep sensitive operations on the server:

await appizer.identify({
  userId: 'user_123',
  traits: {
    email: 'user@example.com',
    internal_score: 95,
  },
})

Implement Proper Authentication

Always authenticate API requests:

const response = await fetch('https://api.appizer.com/v1/events', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.APPIZER_API_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(event),
})

Performance

Cache Analytics Queries

Cache frequently accessed analytics data:

const cache = new Map()

async function getMetrics(query) {
  const cacheKey = JSON.stringify(query)
  
  if (cache.has(cacheKey)) {
    return cache.get(cacheKey)
  }
  
  const result = await appizer.analytics.query(query)
  cache.set(cacheKey, result)
  
  setTimeout(() => cache.delete(cacheKey), 60000)
  
  return result
}

Use Webhooks for Real-Time Updates

Instead of polling, use webhooks:

app.post('/webhooks/appizer', (req, res) => {
  const event = req.body
  
  if (event.type === 'campaign.delivered') {
    updateCampaignStatus(event.data)
  }
  
  res.status(200).send('OK')
})

Optimize Audience Queries

Use specific filters to reduce query time:

const audience = await appizer.audiences.query({
  filters: [
    { property: 'plan', operator: 'equals', value: 'pro' },
    { property: 'last_active', operator: 'after', value: '2024-01-01' },
  ],
  limit: 1000,
})

Next Steps