SdkServer
API Client
TypeScript API client for REST API access
API Client
The @entrolytics/api-client package provides a comprehensive TypeScript client for accessing the Entrolytics REST API with full type safety, authentication, and rate limiting.
Installation
pnpm add @entrolytics/api-clientQuick Start
Initialize Client
import { EntrolyticsApiClient } from '@entrolytics/api-client'
const client = new EntrolyticsApiClient({
websiteId: 'your-website-id',
apiKey: 'your-api-key',
host: 'https://entrolytics.dev'
})Track Events
// Track a custom event
await client.events.track({
event: 'signup',
properties: {
plan: 'pro',
source: 'landing-page'
}
})
// Track a page view
await client.events.page({
url: '/dashboard',
properties: {
title: 'Dashboard'
}
})Get Analytics Data
// Get overview statistics
const overview = await client.analytics.overview({
startDate: new Date('2025-01-01'),
endDate: new Date('2025-01-31')
})
// Get top pages
const topPages = await client.analytics.topPages({
startDate: new Date('2025-01-01'),
endDate: new Date('2025-01-31'),
limit: 10
})Configuration
Client Options
interface EntrolyticsApiClientConfig {
/** Website ID (required) */
websiteId: string
/** API key for authentication */
apiKey?: string
/** JWT token for server-to-server auth */
jwt?: string
/** Custom API host */
host?: string
/** Request timeout in milliseconds */
timeout?: number
/** Enable debug logging */
debug?: boolean
/** Custom fetch implementation */
fetch?: typeof fetch
/** Rate limiting configuration */
rateLimit?: {
requests: number
window: number // in milliseconds
}
/** Retry configuration */
retry?: {
attempts: number
delay: number // in milliseconds
}
}Environment Variables
# .env
ENTROLYTICS_WEBSITE_ID=your-website-id
ENTROLYTICS_API_KEY=your-api-key
ENTROLYTICS_HOST=https://entrolytics.dev
ENTROLYTICS_TIMEOUT=10000API Reference
Events API
Track Event
await client.events.track({
event: string,
properties?: Record<string, any>,
timestamp?: Date,
userId?: string,
sessionId?: string
})Track Page View
await client.events.page({
url: string,
properties?: Record<string, any>,
timestamp?: Date,
userId?: string,
sessionId?: string
})Track Batch Events
await client.events.batch({
events: Array<{
event: string
properties?: Record<string, any>
timestamp?: Date
}>
})Identify User
await client.events.identify({
userId: string,
traits?: Record<string, any>
})Analytics API
Overview Statistics
const overview = await client.analytics.overview({
startDate: Date,
endDate: Date,
timezone?: string
})
// Returns:
interface AnalyticsOverview {
visitors: number
pageviews: number
events: number
sessions: number
bounceRate: number
avgSessionDuration: number
}Top Pages
const pages = await client.analytics.topPages({
startDate: Date,
endDate: Date,
limit?: number,
timezone?: string
})
// Returns:
interface TopPage {
path: string
pageviews: number
uniquePageviews: number
avgTimeOnPage: number
bounceRate: number
}Event Analytics
const events = await client.analytics.events({
startDate: Date,
endDate: Date,
event?: string,
limit?: number,
timezone?: string
})
// Returns:
interface EventAnalytics {
event: string
total: number
uniqueUsers: number
properties: Record<string, any>
}Funnel Analysis
const funnel = await client.analytics.funnel({
startDate: Date,
endDate: Date,
steps: Array<{
event: string
properties?: Record<string, any>
}>,
timezone?: string
})
// Returns:
interface FunnelAnalysis {
steps: Array<{
event: string
users: number
conversionRate: number
}>
overallConversionRate: number
}Websites API
Get Website Info
const website = await client.websites.get(websiteId)List Websites
const websites = await client.websites.list({
limit?: number,
offset?: number
})Update Website
await client.websites.update(websiteId, {
name?: string,
domain?: string,
settings?: Record<string, any>
})Users API
Get User Profile
const user = await client.users.get(userId)Update User Traits
await client.users.update(userId, {
traits: Record<string, any>
})List User Events
const events = await client.users.events(userId, {
startDate: Date,
endDate: Date,
limit?: number
})Advanced Usage
Custom Fetch Implementation
import { fetch } from 'undici'
const client = new EntrolyticsApiClient({
websiteId: 'your-website-id',
apiKey: 'your-api-key',
fetch // Custom fetch implementation
})Rate Limiting
const client = new EntrolyticsApiClient({
websiteId: 'your-website-id',
apiKey: 'your-api-key',
rateLimit: {
requests: 100,
window: 60000 // 100 requests per minute
}
})Retry Logic
const client = new EntrolyticsApiClient({
websiteId: 'your-website-id',
apiKey: 'your-api-key',
retry: {
attempts: 3,
delay: 1000 // Retry 3 times with 1s delay
}
})Request Interceptors
client.addRequestInterceptor((config) => {
// Add custom headers
config.headers['X-Custom-Header'] = 'value'
return config
})
client.addResponseInterceptor((response) => {
// Log responses
console.log('Response:', response.status)
return response
})Error Handling
Error Types
try {
await client.events.track({ event: 'test' })
} catch (error) {
if (error instanceof EntrolyticsValidationError) {
console.error('Validation failed:', error.errors)
} else if (error instanceof EntrolyticsAuthError) {
console.error('Authentication failed:', error.message)
} else if (error instanceof EntrolyticsRateLimitError) {
console.error('Rate limit exceeded:', error.retryAfter)
} else if (error instanceof EntrolyticsNetworkError) {
console.error('Network error:', error.message)
}
}Global Error Handler
client.onError((error) => {
console.error('API Error:', error)
// Send to error tracking service
Sentry.captureException(error)
})Real-time Data
WebSocket Connection
const ws = client.realtime.connect(websiteId)
ws.on('event', (data) => {
console.log('Real-time event:', data)
})
ws.on('pageview', (data) => {
console.log('Real-time pageview:', data)
})
ws.on('error', (error) => {
console.error('WebSocket error:', error)
})Server-Sent Events
const events = client.realtime.events(websiteId)
for await (const event of events) {
console.log('SSE event:', event)
}Testing
Mock Client
import { EntrolyticsApiMockClient } from '@entrolytics/api-client/testing'
const mockClient = new EntrolyticsApiMockClient()
// Configure mock responses
mockClient.events.track.mockResolvedValue({ success: true })
// Use in tests
const result = await mockClient.events.track({ event: 'test' })
expect(result).toEqual({ success: true })Jest Integration
import { EntrolyticsApiClient } from '@entrolytics/api-client'
jest.mock('@entrolytics/api-client')
const mockClient =
new EntrolyticsApiClient() as jest.Mocked<EntrolyticsApiClient>
mockClient.events.track.mockResolvedValue({ success: true })Best Practices
Examples
Express.js Integration
import express from 'express'
import { EntrolyticsApiClient } from '@entrolytics/api-client'
const app = express()
const client = new EntrolyticsApiClient({
websiteId: process.env.ENTROLYTICS_WEBSITE_ID!,
apiKey: process.env.ENTROLYTICS_API_KEY!
})
app.post('/track', async (req, res) => {
try {
await client.events.track(req.body)
res.json({ success: true })
} catch (error) {
res.status(500).json({ error: error.message })
}
})Next.js API Route
// pages/api/analytics/track.ts
import { NextApiRequest, NextApiResponse } from 'next'
import { EntrolyticsApiClient } from '@entrolytics/api-client'
const client = new EntrolyticsApiClient({
websiteId: process.env.ENTROLYTICS_WEBSITE_ID!,
apiKey: process.env.ENTROLYTICS_API_KEY!
})
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method !== 'POST') {
return res.status(405).json({ error: 'Method not allowed' })
}
try {
await client.events.track(req.body)
res.status(200).json({ success: true })
} catch (error) {
res.status(500).json({ error: error.message })
}
}TypeScript API client for Entrolytics - First-party growth analytics for the edge