A Node.js SDK for event tracking, user traits lookup, validation, and automatic retry with queueing.
npm install @cruxstack/node-sdkA Node.js SDK for event tracking, user traits lookup, validation, and automatic retry with queueing.
- Minimal init: Only clientId at initialization
- Per-event tenant context: Provide customerId and customerName on each event
- Type-safe: TypeScript types + runtime validation via Zod
- Automatic retry: Failed events are queued and retried (every 10s, up to 3 times)
- Event enrichment: UUID, timestamp, timezone added automatically
- Flexible payload: User-friendly keys mapped to compact API format
- User traits: Fetch traits for one or many users
``bash`
npm install @cruxstack/node-sdk
`javascript
import { init, cruxTrack, getUserTraits, createUsers, getUsers } from '@cruxstack/node-sdk';
// Initialize SDK (clientId only)
init({
clientId: 'your-client-id'
});
// Track an event (provide tenant context per event)
await cruxTrack('page_view', {
userId: 'user-123',
customerId: 'customer-456',
customerName: 'My Company',
eventTime: Date.now(),
pageTitle: 'Home',
pageUrl: 'https://app.example.com/home'
});
// Get user traits (customerId specifies which tenant to query)
const traits = await getUserTraits('user-123', 'customer-456');
// Create users for a tenant
const createResult = await createUsers({
customer_id: 'customer-456',
users: [
{
user_id: 'user-123',
first_name: 'John',
last_name: 'Doe',
email: 'john.doe@example.com',
job_title: 'Software Engineer',
country: 'United States',
city: 'San Francisco'
}
]
});
// Get users for a tenant (paginated)
const users = await getUsers({
customer_id: 'customer-456',
page: 0,
limit: 10
});
`
Initializes the SDK. Only clientId is required.
`typescript`
interface InitConfig {
clientId: string;
}
Example:
`javascript`
init({ clientId: 'client-123' });
Tracks a single event or multiple events in bulk. For single events, eventData is required. For bulk events, provide an array of event objects.
`typescript
interface ExtendedEventData {
// Identity & timing
userId?: string;
eventTime?: number;
// Tenant context (moved from init to event)
customerId?: string;
customerName?: string;
// Session
sessionId?: string;
// Browser/device
userAgent?: string;
screenHeight?: number;
screenWidth?: number;
language?: string;
platform?: string;
adBlock?: boolean;
viewportHeight?: number;
viewportWidth?: number;
// Page
pageTitle?: string;
pageUrl?: string;
pagePath?: string;
pageDomain?: string;
pageLoadTime?: number;
referrer?: string;
// Network
ipAddress?: string;
// Custom fields
[key: string]: any;
}
`
Examples:
Single Event:
`javascript`
await cruxTrack('purchase', {
userId: 'user-123',
customerId: 'customer-456',
customerName: 'My Company',
amount: 129.99,
currency: 'USD'
});
Bulk Events:
`javascript
const result = await cruxTrack([
{
categoryName: 'page_view',
eventData: {
userId: 'user-1',
customerId: 'customer-1',
customerName: 'Company A',
pageTitle: 'Home',
pageUrl: 'https://app.example.com/home'
}
},
{
categoryName: 'click',
eventData: {
userId: 'user-1',
customerId: 'customer-1',
customerName: 'Company A',
button: 'signup',
location: 'header'
}
},
{
categoryName: 'purchase',
eventData: {
userId: 'user-1',
customerId: 'customer-1',
customerName: 'Company A',
amount: 99.99,
currency: 'USD',
product: 'premium-plan'
}
}
]);
console.log(Bulk result: ${result.processed} processed, ${result.failed} failed);`
Fetch traits for one or more users. Pass the customerId for the tenant whose users you want to query.
`typescript`
type GetUserTraitsResponse = {
success: boolean;
data?: any;
message?: string;
error?: string;
}
Examples:
`javascript
// Single user
const r1 = await getUserTraits('user-123', 'customer-456');
// Multiple users
const r2 = await getUserTraits(['user-123', 'user-456'], 'customer-456');
`
Creates users for a tenant. Requires tenant context (customer_id).
`typescript
interface CreateUsersRequest {
customer_id: string;
users: UserData[];
}
interface UserData {
user_id: string;
first_name?: string;
last_name?: string;
email?: string;
job_title?: string;
company_name?: string;
company_industry?: string;
company_size?: string;
country?: string;
city?: string;
state?: string;
}
`
Example:
`javascript`
await createUsers({
customer_id: 'customer-456',
users: [
{
user_id: 'user-123',
first_name: 'John',
last_name: 'Doe',
email: 'john.doe@example.com',
job_title: 'Software Engineer',
company_name: 'Acme Corp',
country: 'United States',
city: 'San Francisco'
},
{
user_id: 'user-456',
first_name: 'Jane',
last_name: 'Smith',
email: 'jane.smith@example.com',
job_title: 'Product Manager',
country: 'United Kingdom',
city: 'London'
}
]
});
Retrieves users for a tenant with pagination support.
`typescript
interface GetUsersRequest {
customer_id: string;
page?: number; // Default: 0
limit?: number; // Default: 10
}
interface GetUsersResponse {
success: boolean;
data?: {
users: UserData[];
total: number;
page: number;
limit: number;
};
message?: string;
error?: string;
}
`
Example:
`javascript
const result = await getUsers({
customer_id: 'customer-456',
page: 0,
limit: 20
});
if (result.success && result.data) {
console.log(Found ${result.data.total} users);`
console.log('Users:', result.data.users);
}
- Events are sent immediately.
- If sending fails, events are queued and retried every 10 seconds.
- Max retries per event: 3.
- "SDK not initialized. Call init() first."
- "Category name is required and must be a non-empty string"
- "eventData is required when categoryName is a string"
- "Events array cannot be empty"
- "Maximum 1000 events per batch"
- "Event tracking failed: …" (validation)
- "Bulk event tracking failed: …" (bulk validation)
- "Failed to send event: …" (network/API)
- "userIds is required" / "At least one userId is required" / "All userIds must be non-empty strings"
- "customerId is required for getUserTraits"
- "customer_id is required" (for user management)
- "users array cannot be empty" (for createUsers)
- "user_id is required for each user" (for createUsers)
Headers automatically set:
- Content-Type: application/jsonx-client-id: {clientId}
-
- Init now requires only clientId.customerId
- and customerName moved from init to each event.getUserTraits
- signature: (userIds, customerId?) – pass customerId for the tenant to query.createUsers
- Added for user management with tenant context (customer_id).getUsers
- Added for retrieving users with pagination support.cruxTrack
- NEW: now supports bulk events with array input.eventData
- NEW: Single events require parameter (no longer optional).{success, processed, failed, errors?}` response.
- NEW: Bulk events return
Apache-2.0