API Client SDK
TypeScript/JavaScript client for Entrolytics API
API Client SDK
The @entrolytics/api-client package provides a type-safe TypeScript/JavaScript client for interacting with the Entrolytics API. It supports all endpoints including analytics, websites, organizations, links, pixels, boards, and the new Phase 2 features (Web Vitals, Form Analytics, Deployment Tracking).
Installation
pnpm add @entrolytics/api-clientQuick Start
import getClient from '@entrolytics/api-client'
// Initialize client
const client = getClient({
endpoint: 'https://entrolytics.dev/api',
apiKey: process.env.ENTROLYTICS_API_KEY,
// OR use bearer token (Clerk JWT)
bearerToken: 'your-clerk-jwt-token'
})
// Get your websites
const { ok, data: websites } = await client.getMyWebsites()
// Get website stats
const { data: stats } = await client.getWebsiteStats('website-id', {
startAt: Date.now() - 7 * 24 * 60 * 60 * 1000, // 7 days ago
endAt: Date.now(),
unit: 'day'
})Configuration
ClientConfig
interface ClientConfig {
/** API base URL (default: https://entrolytics.dev/api) */
endpoint?: string
/** API key for authentication */
apiKey?: string
/** Bearer token (Clerk JWT) for authentication */
bearerToken?: string
}Authentication
Choose between API key or bearer token authentication:
API Key
const client = getClient({
apiKey: process.env.ENTROLYTICS_API_KEY
})Bearer Token (Clerk)
const client = getClient({
bearerToken: await auth().getToken()
})API Reference
Me Endpoints
// Get current user
const { data: user } = await client.getMe()
// Get my websites
const { data: websites } = await client.getMyWebsites()
// Get my organizations
const { data: orgs } = await client.getMyOrgs()
// Update password
await client.updateMyPassword({
currentPassword: 'old',
newPassword: 'new'
})Website Endpoints
// List websites
const { data: websites } = await client.getWebsites()
// Get single website
const { data: website } = await client.getWebsite('website-id')
// Create website
const { data: newSite } = await client.createWebsite({
domain: 'example.com',
name: 'My Site'
})
// Update website
await client.updateWebsite('website-id', {
name: 'Updated Name'
})
// Delete website
await client.deleteWebsite('website-id')
// Reset website (clear all data)
await client.resetWebsite('website-id')
// Transfer website to another org
await client.transferWebsite('website-id', { orgId: 'new-org-id' })
// Get website stats
const { data: stats } = await client.getWebsiteStats('website-id', {
startAt: timestamp,
endAt: timestamp,
unit: 'day'
})
// Get pageviews
const { data: pageviews } = await client.getWebsitePageviews('website-id', {
startAt: timestamp,
endAt: timestamp,
unit: 'day'
})
// Get metrics
const { data: metrics } = await client.getWebsiteMetrics('website-id', {
type: 'url',
startAt: timestamp,
endAt: timestamp
})
// Get real-time data
const { data: realtime } = await client.getRealtimeData('website-id')
// Get active visitors
const { data: active } = await client.getWebsiteActive('website-id')
// Export website data
const { data: exportData } = await client.exportWebsiteData('website-id', {
startAt: timestamp,
endAt: timestamp,
format: 'csv'
})Organization Endpoints
// List organizations
const { data: orgs } = await client.getOrgs()
// Create organization
const { data: org } = await client.createOrg({ name: 'My Org' })
// Get organization
const { data: org } = await client.getOrg('org-id')
// Get organization users
const { data: users } = await client.getOrgUsers('org-id')
// Add user to organization
await client.addOrgUser('org-id', {
email: 'user@example.com',
role: 'member'
})
// Get organization websites
const { data: websites } = await client.getOrgWebsites('org-id')Session Endpoints
// Get website sessions
const { data: sessions } = await client.getWebsiteSessions('website-id', {
startAt: timestamp,
endAt: timestamp
})
// Get session details
const { data: session } = await client.getSession('session-id')
// Get session activity (events, pageviews)
const { data: activity } = await client.getSessionActivity('session-id')
// Get weekly traffic patterns
const { data: traffic } = await client.getWeeklyTraffic('website-id')Link Endpoints
// List links
const { data: links } = await client.getLinks()
// Get organization links
const { data: orgLinks } = await client.getOrgLinks('org-id')
// Create link
const { data: link } = await client.createLink({
url: 'https://example.com/product',
slug: 'summer-sale',
utmSource: 'twitter',
utmCampaign: 'summer-2024'
})
// Get link details
const { data: link } = await client.getLink('link-id')
// Update link
await client.updateLink('link-id', { slug: 'new-slug' })
// Delete link
await client.deleteLink('link-id')Pixel Endpoints
// List pixels
const { data: pixels } = await client.getPixels()
// Get organization pixels
const { data: orgPixels } = await client.getOrgPixels('org-id')
// Create pixel
const { data: pixel } = await client.createPixel({
name: 'Newsletter Open',
type: 'email'
})
// Get pixel details
const { data: pixel } = await client.getPixel('pixel-id')
// Delete pixel
await client.deletePixel('pixel-id')Board Endpoints (Custom Dashboards)
// List boards
const { data: boards } = await client.getBoards()
// Create board
const { data: board } = await client.createBoard({
name: 'Marketing Dashboard',
description: 'Custom analytics dashboard'
})
// Get board details
const { data: board } = await client.getBoard('board-id')
// Get board widgets
const { data: widgets } = await client.getBoardWidgets('board-id')
// Create widget
const { data: widget } = await client.createBoardWidget('board-id', {
type: 'line',
title: 'Traffic Over Time',
config: { metrics: ['pageviews', 'visitors'] }
})
// Update widget
await client.updateBoardWidget('board-id', 'widget-id', { title: 'New Title' })
// Delete widget
await client.deleteBoardWidget('board-id', 'widget-id')Report Endpoints
// List reports
const { data: reports } = await client.getReports('website-id')
// Create report
const { data: report } = await client.createReport('website-id', {
name: 'Monthly Report',
type: 'funnel'
})
// Run funnel report
const { data: funnel } = await client.runFunnelReport('website-id', {
urls: ['/signup', '/onboarding', '/dashboard'],
startAt: timestamp,
endAt: timestamp
})
// Run retention report
const { data: retention } = await client.runRetentionReport('website-id', {
startAt: timestamp,
endAt: timestamp
})
// Run journey report
const { data: journey } = await client.runJourneyReport('website-id', {
startAt: timestamp,
endAt: timestamp
})
// Run revenue report
const { data: revenue } = await client.runRevenueReport('website-id', {
startAt: timestamp,
endAt: timestamp
})
// Run UTM report
const { data: utm } = await client.runUTMReport('website-id', {
startAt: timestamp,
endAt: timestamp
})Web Vitals Endpoints (Phase 2)
// Get website Web Vitals summary
const { data: vitals } = await client.getWebsiteVitals('website-id', {
startAt: timestamp,
endAt: timestamp
})
// Get individual Web Vital events
const { data: vitalEvents } = await client.getWebsiteVitalEvents('website-id', {
metric: 'LCP', // LCP, FID, CLS, FCP, TTFB, INP
startAt: timestamp,
endAt: timestamp
})
// Track a Web Vital measurement
await client.trackVital('website-id', {
metric: 'LCP',
value: 2500,
rating: 'needs-improvement',
url: '/dashboard',
navigationType: 'navigate'
})
// Batch track multiple vitals
await client.trackVitalsBatch('website-id', {
vitals: [
{ metric: 'LCP', value: 2500, rating: 'needs-improvement' },
{ metric: 'CLS', value: 0.05, rating: 'good' },
{ metric: 'FID', value: 100, rating: 'good' }
]
})Form Analytics Endpoints (Phase 2)
// Get website forms
const { data: forms } = await client.getWebsiteForms('website-id')
// Get form fields analytics
const { data: fields } = await client.getFormFields('website-id', 'form-id')
// Get form events
const { data: events } = await client.getFormEvents('website-id', 'form-id')
// Track form event
await client.trackFormEvent('website-id', {
formId: 'contact-form',
eventType: 'submit', // focus, blur, change, submit, abandon
fieldName: 'email',
timeSpent: 5000
})
// Batch track form events
await client.trackFormEventsBatch('website-id', {
events: [
{ formId: 'signup', eventType: 'focus', fieldName: 'name' },
{ formId: 'signup', eventType: 'blur', fieldName: 'name', timeSpent: 2000 }
]
})Deployment Tracking Endpoints (Phase 2)
// Get website deployments
const { data: deployments } = await client.getWebsiteDeployments('website-id')
// Get deployment details
const { data: deployment } = await client.getDeployment(
'website-id',
'deploy-id'
)
// Compare recent deployments
const { data: comparison } = await client.compareDeployments('website-id', 10)
// Set deployment (from CI/CD)
await client.setDeployment('website-id', {
deployId: 'vercel-deploy-abc123',
source: 'vercel',
gitBranch: 'main',
gitSha: 'abc123',
deployUrl: 'https://example.vercel.app'
})Error Handling
All methods return an ApiResponse<T> with error handling:
const result = await client.getWebsites()
if (!result.ok) {
console.error('Error:', result.error)
console.error('Status:', result.status)
return
}
// Type-safe data access
const websites = result.dataResponse Type
interface ApiResponse<T> {
ok: boolean
data?: T
error?: string
status?: number
}Runtime Detection
The client automatically detects your runtime environment:
import {
detectRuntime,
isEdgeRuntime,
isNodeRuntime
} from '@entrolytics/api-client'
// Detect runtime
const runtime = detectRuntime() // 'node' | 'edge' | 'browser'
// Check specific runtime
if (isEdgeRuntime()) {
// Edge-specific code
}
if (isNodeRuntime()) {
// Node.js-specific code
}Edge Helpers
For edge function deployments:
import {
getGeoFromRequest,
getClientIp,
getRegionInfo
} from '@entrolytics/api-client'
// Get geographic info from request headers
const geo = getGeoFromRequest(request)
console.log(geo.country, geo.city, geo.region)
// Get client IP
const ip = getClientIp(request)
// Get region info
const region = getRegionInfo(request)Features
- ✅ Type-safe API client with full TypeScript support
- ✅ Support for both API key and JWT bearer token auth
- ✅ Comprehensive error handling
- ✅ Runtime detection (Node.js, Edge, Browser)
- ✅ Edge helpers for serverless environments
- ✅ All core endpoints (websites, orgs, sessions, links, pixels, boards)
- ✅ Phase 2 features (Web Vitals, Form Analytics, Deployments)
- ✅ Zero dependencies (uses native fetch)
- ✅ Works in Node.js, Edge, and browsers
Examples
Build a Custom Dashboard
import getClient from '@entrolytics/api-client'
async function getDashboardData(websiteId: string) {
const client = getClient({
apiKey: process.env.ENTROLYTICS_API_KEY
})
const now = Date.now()
const weekAgo = now - 7 * 24 * 60 * 60 * 1000
const [stats, pageviews, topPages, vitals] = await Promise.all([
client.getWebsiteStats(websiteId, {
startAt: weekAgo,
endAt: now,
unit: 'day'
}),
client.getWebsitePageviews(websiteId, {
startAt: weekAgo,
endAt: now,
unit: 'day'
}),
client.getWebsiteMetrics(websiteId, {
type: 'url',
startAt: weekAgo,
endAt: now
}),
client.getWebsiteVitals(websiteId, {
startAt: weekAgo,
endAt: now
})
])
return {
stats: stats.data,
pageviews: pageviews.data,
topPages: topPages.data,
webVitals: vitals.data
}
}Server-Side Analytics Export
import getClient from '@entrolytics/api-client'
import { writeFileSync } from 'fs'
async function exportAnalytics() {
const client = getClient({
apiKey: process.env.ENTROLYTICS_API_KEY
})
const { data: websites } = await client.getWebsites()
for (const site of websites || []) {
const { data: stats } = await client.getWebsiteStats(site.id, {
startAt: Date.now() - 30 * 24 * 60 * 60 * 1000,
endAt: Date.now(),
unit: 'day'
})
writeFileSync(`export-${site.domain}.json`, JSON.stringify(stats, null, 2))
}
}Track Deployments in CI/CD
import getClient from '@entrolytics/api-client'
// In your CI/CD pipeline
async function trackDeployment() {
const client = getClient({
apiKey: process.env.ENTROLYTICS_API_KEY
})
await client.setDeployment(process.env.WEBSITE_ID, {
deploymentId: process.env.VERCEL_DEPLOYMENT_ID,
provider: 'vercel',
branch: process.env.VERCEL_GIT_COMMIT_REF,
commit: process.env.VERCEL_GIT_COMMIT_SHA,
message: process.env.VERCEL_GIT_COMMIT_MESSAGE
})
}Support
- GitHub Issues
- Email: hey@entrolytics.dev