API Client SDK

TypeScript/JavaScript client for Entrolytics API

API Client SDK

The @entro314labs/entro-api package provides a type-safe TypeScript/JavaScript client for interacting with the Entrolytics API.

Installation

pnpm add @entro314labs/entro-api

Quick Start

import getClient from '@entro314labs/entro-api';

// Initialize client
const client = getClient({
  apiUrl: 'https://cloud.entrolytics.click',
  apiKey: process.env.ENTROLYTICS_API_KEY,
  // OR use bearer token (Clerk JWT)
  bearerToken: 'your-clerk-jwt-token',
});

// Get your websites
const websites = await client.me.getMyWebsites();

// Get website stats
const stats = await client.websites.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://cloud.entrolytics.click) */
  apiUrl?: string;
  /** API key for authentication */
  apiKey?: string;
  /** Bearer token (Clerk JWT) for authentication */
  bearerToken?: string;
  /** Request timeout in milliseconds (default: 30000) */
  timeout?: number;
  /** Number of retry attempts (default: 3) */
  retries?: number;
  /** Delay between retries in ms (default: 1000) */
  retryDelay?: number;
}

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 user = await client.me.getMe();

// Get my websites
const websites = await client.me.getMyWebsites();

// Get my organizations
const orgs = await client.me.getMyOrgs();

// Update password
await client.me.updateMyPassword({
  currentPassword: 'old',
  newPassword: 'new',
});

Website Endpoints

// List websites
const websites = await client.websites.getWebsites();

// Get single website
const website = await client.websites.getWebsite('website-id');

// Create website
const newSite = await client.websites.createWebsite({
  domain: 'example.com',
  name: 'My Site',
});

// Update website
await client.websites.updateWebsite('website-id', {
  name: 'Updated Name',
});

// Delete website
await client.websites.deleteWebsite('website-id');

// Get website stats
const stats = await client.websites.getWebsiteStats('website-id', {
  startAt: timestamp,
  endAt: timestamp,
  unit: 'day',
});

// Get pageviews
const pageviews = await client.websites.getWebsitePageviews('website-id', {
  startAt: timestamp,
  endAt: timestamp,
  unit: 'day',
});

// Get metrics
const metrics = await client.websites.getWebsiteMetrics('website-id', {
  type: 'url',
  startAt: timestamp,
  endAt: timestamp,
});

Organization Endpoints

// List organizations
const orgs = await client.orgs.getOrgs();

// Get organization users
const users = await client.orgs.getOrgUsers('org-id');

// Invite user
await client.orgs.inviteOrgUser('org-id', {
  email: 'user@example.com',
  role: 'member',
});

Board Endpoints

// List boards
const boards = await client.boards.getBoards('website-id');

// Create board
const board = await client.boards.createBoard('website-id', {
  name: 'My Dashboard',
  description: 'Custom analytics dashboard',
});

// Get board widgets
const widgets = await client.boards.getBoardWidgets('board-id');

Report Endpoints

// Generate insights report
const insights = await client.reports.getInsights('website-id', {
  startAt: timestamp,
  endAt: timestamp,
});

// Get funnel report
const funnel = await client.reports.getFunnel('website-id', {
  urls: ['/signup', '/onboarding', '/dashboard'],
  startAt: timestamp,
  endAt: timestamp,
});

// Get retention report
const retention = await client.reports.getRetention('website-id', {
  startAt: timestamp,
  endAt: timestamp,
});

Error Handling

All methods return an ApiResponse<T> with error handling:

const result = await client.websites.getWebsites();

if (result.error) {
  console.error('Error:', result.error);
  console.error('Status:', result.status);
  return;
}

// Type-safe data access
const websites = result.data;

Response Type

interface ApiResponse<T> {
  ok: boolean;
  data?: T;
  error?: string;
  status?: number;
}

Features

  • ✅ Type-safe API client with full TypeScript support
  • ✅ Automatic retries with exponential backoff
  • ✅ Support for both API key and JWT bearer token auth
  • ✅ Comprehensive error handling
  • ✅ Zero dependencies (uses native fetch)
  • ✅ Works in Node.js and browsers

Examples

Build a Custom Dashboard

import getClient from '@entro314labs/entro-api';

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] = await Promise.all([
    client.websites.getWebsiteStats(websiteId, {
      startAt: weekAgo,
      endAt: now,
      unit: 'day',
    }),
    client.websites.getWebsitePageviews(websiteId, {
      startAt: weekAgo,
      endAt: now,
      unit: 'day',
    }),
    client.websites.getWebsiteMetrics(websiteId, {
      type: 'url',
      startAt: weekAgo,
      endAt: now,
    }),
  ]);

  return {
    stats: stats.data,
    pageviews: pageviews.data,
    topPages: topPages.data,
  };
}

Server-Side Analytics Export

import getClient from '@entro314labs/entro-api';
import { writeFileSync } from 'fs';

async function exportAnalytics() {
  const client = getClient({
    apiKey: process.env.ENTROLYTICS_API_KEY,
  });

  const websites = await client.websites.getWebsites();

  for (const site of websites.data || []) {
    const stats = await client.websites.getWebsiteStats(site.id, {
      startAt: Date.now() - 30 * 24 * 60 * 60 * 1000,
      endAt: Date.now(),
      unit: 'day',
    });

    writeFileSync(
      `export-${site.domain}.json`,
      JSON.stringify(stats.data, null, 2)
    );
  }
}

Support