npm package: @logopulse/sdk
Description: Track the pulse of every customer - SDK for B2B SaaS customer health analytics
Author: Tracelot
Latest version: 1.2.4

# @logopulse/sdk

**Track customer health analytics for any B2B SaaS platform.**

Track the pulse of every customer - flexible entity tracking, configurable stage progression, and automatic feature adoption analytics.

## Installation

```bash
npm install @logopulse/sdk
```

## Quick Start

```typescript
import { createLogoPulse } from '@logopulse/sdk';

// Initialize once (singleton)
const logoPulse = createLogoPulse({
  apiKey: 'your-api-key-here',
  orgId: 'your-org-id',
  timeout: 5000, // Optional: request timeout in ms (default: 5000)
});

// Track custom entities - unlimited entity types, no configuration required!
await logoPulse.track('batch.created', accountId, { batchId: 'batch-123' });
await logoPulse.track('order.processed', accountId, { orderId: 'order-456', amount: 250.50 });
await logoPulse.track('report.generated', accountId, { reportType: 'analytics' });

// Track customer lifecycle with pre-built methods
await logoPulse.createCustomer({ accountId, companyName: 'Acme Corp', ownerEmail: 'owner@acme.com' });
await logoPulse.userLogin(accountId, { email: 'user@acme.com' });
await logoPulse.subscriptionStarted(accountId, { plan: 'pro', amount: 99.00 });
```

## Core Concepts

### Entities vs Actions

**Entities** (unlimited - define your own):
- Any countable business object your customers create
- Examples: `batch`, `order`, `product`, `report`, `document`, `shipment`, `invoice`, `warehouse`
- LogoPulse automatically tracks count, timestamps, and revenue for each entity type
- **No configuration required** - just start tracking!

**Actions** (limited - predefined set):
- Standard verbs that describe what happened to an entity
- See [Standard Actions](#standard-actions) below
- Consistent actions ensure proper tracking across all entity types

**Event Format:** `entity.action` (e.g., `batch.created`, `order.processed`)

---

## API Reference

### Initialization

#### `createLogoPulse(config)`

Initialize the SDK with your credentials.

```typescript
import { createLogoPulse } from '@logopulse/sdk';

const logoPulse = createLogoPulse({
  apiKey: 'your-api-key',      // Required: Your LogoPulse API key
  orgId: 'your-org-id',        // Required: Your organization ID
  timeout: 5000,               // Optional: Request timeout in ms (default: 5000)
});
```

#### `getLogoPulse()`

Get the singleton instance (must call `createLogoPulse()` first).

```typescript
import { getLogoPulse } from '@logopulse/sdk';

const logoPulse = getLogoPulse();
```

### Core Tracking

#### `track(eventType, accountId, data?, options?)`

Track any custom entity event using the `entity.action` format.

```typescript
await logoPulse.track(
  'batch.created',              // eventType: entity.action
  'account-123',                // accountId: customer account ID
  {                             // data: optional event data
    batchId: 'batch-456',
    productName: 'Widget',
    quantity: 100,
    amount: 1250.00             // Include amount to track revenue
  },
  {                             // options: optional metadata
    userId: 'user-789',
    traceId: 'trace-abc',
    source: 'api-service',
    timestamp: '2026-01-05T12:00:00Z'
  }
);
```

**When to use:** For tracking any custom entity specific to your business (unlimited entity types).

---

### Customer Management

#### `createCustomer(account)`

Track new customer account creation (first-time signup).

```typescript
await logoPulse.createCustomer({
  accountId: 'account-123',
  companyName: 'Acme Corp',
  ownerEmail: 'owner@acme.com',
  ownerFirstName: 'John',
  ownerLastName: 'Doe',
  phone: '+1-555-0100',
  address: '123 Main St',
  city: 'San Francisco',
  state: 'CA',
  country: 'USA',
  postalCode: '94102',
});
```

**When to use:** When a new business/company completes signup.

#### `updateCustomer(accountId, updates)`

Update customer account information.

```typescript
await logoPulse.updateCustomer('account-123', {
  companyName: 'Acme Corporation',
  phone: '+1-555-0200',
});
```

**When to use:** When account details change.

#### `addUser(user)`

Track when a user joins an existing account (additional seat).

```typescript
await logoPulse.addUser({
  accountId: 'account-123',
  userId: 'user-456',
  email: 'admin@acme.com',
  firstName: 'Jane',
  lastName: 'Smith',
  role: 'admin',
});
```

**When to use:** When user accepts invitation or is added to account.

---

### User Activity

#### `userLogin(accountId, data?)`

```typescript
await logoPulse.userLogin('account-123', {
  email: 'user@acme.com',
  userId: 'user-456',
});
```

**When to use:** On successful user authentication.

#### `userInvited(accountId, data)`

```typescript
await logoPulse.userInvited('account-123', {
  email: 'newuser@acme.com',
  role: 'member',
});
```

#### `userAcceptedInvite(accountId, data)`

```typescript
await logoPulse.userAcceptedInvite('account-123', {
  userId: 'user-789',
  email: 'newuser@acme.com',
  role: 'member',
});
```

#### `userRemoved(accountId, data)`

```typescript
await logoPulse.userRemoved('account-123', {
  userId: 'user-456',
});
```

---

### Integrations

#### `integrationConnected(accountId, data)`

```typescript
await logoPulse.integrationConnected('account-123', {
  integrationName: 'stripe',
});
```

**When to use:** When customer connects Stripe, Shopify, etc.

#### `integrationDisconnected(accountId, data)`

```typescript
await logoPulse.integrationDisconnected('account-123', {
  integrationName: 'stripe',
});
```

---

### Subscription & Billing

#### `subscriptionStarted(accountId, data?)`

```typescript
await logoPulse.subscriptionStarted('account-123', {
  plan: 'pro',
  amount: 99.00,
  interval: 'monthly',
});
```

**When to use:** When customer starts paying subscription.

#### `subscriptionUpgraded(accountId, data)`

```typescript
await logoPulse.subscriptionUpgraded('account-123', {
  plan: 'enterprise',
  amount: 299.00,
});
```

#### `subscriptionDowngraded(accountId, data)`

```typescript
await logoPulse.subscriptionDowngraded('account-123', {
  plan: 'starter',
  amount: 49.00,
});
```

#### `subscriptionRenewed(accountId, data?)`

```typescript
await logoPulse.subscriptionRenewed('account-123');
```

#### `subscriptionCancelled(accountId, data?)`

```typescript
await logoPulse.subscriptionCancelled('account-123', {
  reason: 'switching to competitor',
});
```

---

### Trial Management

#### `trialStarted(accountId, data?)`

```typescript
await logoPulse.trialStarted('account-123', {
  plan: 'pro-trial',
  trialEndsAt: '2026-02-05T00:00:00Z',
});
```

#### `trialEnded(accountId, data?)`

```typescript
await logoPulse.trialEnded('account-123', {
  converted: true,
});
```

#### `trialExpired(accountId)`

```typescript
await logoPulse.trialExpired('account-123');
```

---

### Feature Adoption

#### `trackFeature(accountId, featureName)`

Manually track feature adoption.

```typescript
await logoPulse.trackFeature('account-123', 'apiAccess');
await logoPulse.trackFeature('account-123', 'advancedReporting');
```

**When to use:** For features not automatically tracked via entity-to-feature mapping.

---

## Standard Actions

Use these standard actions with `track()` for consistent entity tracking.

**⚠️ IMPORTANT:** Only these actions are accepted by LogoPulse. Other actions will be rejected to ensure proper entity counting.

```typescript
import { StandardActions } from '@logopulse/sdk';

// Creation/Addition (increments count)
StandardActions.CREATED    // 'created'
StandardActions.ADDED      // 'added'

// Modification (no count change)
StandardActions.UPDATED    // 'updated'
StandardActions.CHANGED    // 'changed'

// Removal (decrements count)
StandardActions.DELETED    // 'deleted'
StandardActions.REMOVED    // 'removed'
StandardActions.CANCELLED  // 'cancelled'

// Data Operations (increments count)
StandardActions.UPLOADED   // 'uploaded'
StandardActions.DOWNLOADED // 'downloaded'
StandardActions.IMPORTED   // 'imported'
StandardActions.EXPORTED   // 'exported'
StandardActions.GENERATED  // 'generated'

// Processing (increments count)
StandardActions.PROCESSED  // 'processed'
StandardActions.FAILED     // 'failed'
StandardActions.SYNCED     // 'synced'

// Completion/Finalization (increments count)
StandardActions.COMPLETED  // 'completed'
StandardActions.DELIVERED  // 'delivered'
StandardActions.FULFILLED  // 'fulfilled'
StandardActions.SHIPPED    // 'shipped'
StandardActions.APPROVED   // 'approved'
StandardActions.REJECTED   // 'rejected'
StandardActions.CLOSED     // 'closed'
```

**Examples:**

```typescript
// E-commerce SaaS
await logoPulse.track('order.created', accountId, { orderId, amount });
await logoPulse.track('order.fulfilled', accountId, { orderId });
await logoPulse.track('shipment.delivered', accountId, { shipmentId });

// Inventory SaaS
await logoPulse.track('product.created', accountId, { sku, name });
await logoPulse.track('product.updated', accountId, { sku, price });
await logoPulse.track('warehouse.added', accountId, { warehouseId });

// Reporting SaaS
await logoPulse.track('report.generated', accountId, { reportType });
await logoPulse.track('report.exported', accountId, { format: 'pdf' });
await logoPulse.track('dashboard.created', accountId, { dashboardId });

// Document Management SaaS
await logoPulse.track('document.uploaded', accountId, { fileSize });
await logoPulse.track('document.approved', accountId, { documentId });
await logoPulse.track('folder.created', accountId, { folderId });

// Support/Ticketing SaaS
await logoPulse.track('ticket.created', accountId, { ticketId });
await logoPulse.track('ticket.closed', accountId, { ticketId });
```

---

## Usage Examples

### Initialize in Your App

```typescript
// app.ts or index.ts
import { createLogoPulse } from '@logopulse/sdk';

createLogoPulse({
  apiKey: process.env.LOGOPULSE_API_KEY,
  orgId: process.env.LOGOPULSE_ORG_ID,
});
```

### Use in Your Services

```typescript
import { getLogoPulse } from '@logopulse/sdk';

export class OrderService {
  async createOrder(accountId: string, data: CreateOrderData) {
    const order = await db.orders.create(data);

    // Track analytics (non-blocking, errors logged)
    getLogoPulse()
      .track('order.created', accountId, {
        orderId: order.id,
        amount: order.total,
      })
      .catch(console.error);

    return order;
  }
}
```

### Customer Onboarding Flow

```typescript
// 1. New company signs up
await logoPulse.createCustomer({
  accountId: 'account-123',
  companyName: 'Acme Corp',
  ownerEmail: 'owner@acme.com',
});

// 2. Start trial
await logoPulse.trialStarted('account-123', {
  trialEndsAt: '2026-02-05T00:00:00Z',
});

// 3. Connect integration
await logoPulse.integrationConnected('account-123', {
  integrationName: 'stripe',
});

// 4. Create first entity
await logoPulse.track('product.created', 'account-123', {
  productId: 'prod-789',
});

// 5. Convert to paid
await logoPulse.trialEnded('account-123', { converted: true });
await logoPulse.subscriptionStarted('account-123', {
  plan: 'pro',
  amount: 99.00,
});
```

---

## Error Handling

The SDK logs errors but doesn't throw, so analytics failures won't break your app.

```typescript
// Errors are caught and logged internally
await logoPulse.track('order.created', accountId, data);
// Your code continues even if tracking fails
```

---

## Environment Variables

Set `SERVICE_NAME` to automatically tag events with their source:

```bash
export SERVICE_NAME=api-service
```

---

## TypeScript Support

Full TypeScript definitions included.

```typescript
import { LogoPulseConfig, CustomerAccount, User } from '@logopulse/sdk';
```

---

## License

MIT