Node.js SDK
Official Flow Myna SDK for Node.js 18+
The official Node.js SDK for Flow Myna provides a modern, TypeScript-first interface for recording process events and managing objects. It includes full TypeScript support, automatic retries, and Promise-based APIs.
Installation
Install with npm
npm install @flowmyna/sdkQuick Start
Basic Usage
import { FlowMyna } from '@flowmyna/sdk';
// Initialize the client
const client = new FlowMyna({
apiKey: 'fm_live_your_key_here'
});
// Record an event
await client.recordEvent({
event: 'Order Placed',
objects: [
{ type: 'Order', id: 'ORD-123' },
{ type: 'Customer', id: 'CUST-456' }
],
properties: { total: 149.99 }
});
// Upsert an object
await client.upsertObject({
type: 'Customer',
id: 'CUST-456',
properties: {
name: 'Jane Doe',
email: 'jane@example.com'
}
});Configuration
- Name
apiKey- Type
- string
- Required
- required
- Description
- Your Flow Myna API key (starts with
fm_live_)
- Name
baseUrl- Type
- string
- Description
- API base URL. Defaults to
https://api.flowmyna.com/api/public/v1
- Name
timeout- Type
- number
- Description
- Request timeout in milliseconds. Default: 30000
- Name
maxRetries- Type
- number
- Description
- Maximum number of retry attempts. Default: 3
Configuration Options
import { FlowMyna } from '@flowmyna/sdk';
// Using environment variable (recommended)
const client = new FlowMyna({
apiKey: process.env.FLOWMYNA_API_KEY!
});
// With custom configuration
const clientWithOptions = new FlowMyna({
apiKey: 'fm_live_xxx',
timeout: 60000, // 60 second timeout
maxRetries: 5, // Retry up to 5 times
});
// For testing/development
const devClient = new FlowMyna({
apiKey: 'fm_live_xxx',
baseUrl: 'https://staging-api.flowmyna.com/api/public/v1'
});recordEvent()
Record a process event with associated objects.
- Name
event- Type
- string
- Required
- required
- Description
- Event name (1-200 characters)
- Name
objects- Type
- EventObject[]
- Required
- required
- Description
- Array of objects involved in the event
- Name
timestamp- Type
- string | Date
- Description
- When the event occurred (ISO 8601 string or Date object)
- Name
properties- Type
- Record<string, unknown>
- Description
- Additional event properties
recordEvent() Examples
// Simple event
await client.recordEvent({
event: 'Order Created',
objects: [{ type: 'Order', id: 'ORD-123' }]
});
// With timestamp (Date object)
await client.recordEvent({
event: 'Order Shipped',
objects: [
{ type: 'Order', id: 'ORD-123' },
{ type: 'Shipment', id: 'SHIP-456' }
],
timestamp: new Date()
});
// With timestamp (ISO string)
await client.recordEvent({
event: 'Order Delivered',
objects: [{ type: 'Order', id: 'ORD-123' }],
timestamp: '2024-01-15T10:30:00Z'
});
// With properties
await client.recordEvent({
event: 'Payment Processed',
objects: [
{ type: 'Order', id: 'ORD-123' },
{ type: 'Payment', id: 'PAY-789' }
],
properties: {
amount: 149.99,
currency: 'USD',
method: 'credit_card'
}
});
// With object properties (merged on upsert)
await client.recordEvent({
event: 'Customer Login',
objects: [{
type: 'Customer',
id: 'CUST-456',
properties: {
lastLogin: new Date().toISOString(),
loginCount: 42
}
}]
});upsertObject()
Create or update an object with properties (upsert semantics).
- Name
type- Type
- string
- Required
- required
- Description
- Object type (1-100 characters)
- Name
id- Type
- string
- Required
- required
- Description
- Object ID (1-500 characters)
- Name
properties- Type
- Record<string, unknown>
- Description
- Object properties (merged with existing)
upsertObject() Examples
// Upsert a customer
const result = await client.upsertObject({
type: 'Customer',
id: 'CUST-456',
properties: {
name: 'Jane Doe',
email: 'jane@example.com',
tier: 'gold',
signupDate: '2023-01-15'
}
});
console.log(`Object ${result.created ? 'created' : 'updated'}`);
console.log(`Internal ID: ${result.objectId}`);
// Update properties (properties are merged)
await client.upsertObject({
type: 'Customer',
id: 'CUST-456',
properties: {
lifetimeValue: 5420.00, // Added
tier: 'platinum' // Updated
}
});
// Upsert without properties (just ensures object exists)
await client.upsertObject({ type: 'Order', id: 'ORD-123' });Batch Operations
Send multiple events or objects efficiently in a single request.
Batch Examples
// Batch record events (up to 100 per call)
const events = [
{
event: 'Case Opened',
timestamp: '2024-01-01T09:00:00Z',
objects: [{ type: 'Case', id: 'CASE-001' }],
properties: { priority: 'high' }
},
{
event: 'Case Assigned',
timestamp: '2024-01-01T09:15:00Z',
objects: [
{ type: 'Case', id: 'CASE-001' },
{ type: 'Agent', id: 'AGENT-A' }
]
},
{
event: 'Case Resolved',
timestamp: '2024-01-01T14:30:00Z',
objects: [{ type: 'Case', id: 'CASE-001' }]
}
];
const result = await client.recordEventBatch(events);
console.log(`Processed: ${result.processed}, Failed: ${result.failed}`);
// Batch upsert objects
const customers = Array.from({ length: 100 }, (_, i) => ({
type: 'Customer',
id: `CUST-${String(i).padStart(3, '0')}`,
properties: { index: i }
}));
const upsertResult = await client.upsertObjectBatch(customers);
console.log(`Upserted ${upsertResult.processed} objects`);health()
Verify API key and get workspace/dataset information.
Health Check
// Check API key and connection
const health = await client.health();
console.log(`Status: ${health.status}`);
console.log(`Workspace: ${health.workspaceName}`);
console.log(`Dataset: ${health.datasetName}`);
console.log(`Key Name: ${health.apiKeyName}`);
// Use in startup validation
async function validateFlowMynaConnection(): Promise<boolean> {
try {
const health = await client.health();
console.log('✓ Connected to Flow Myna');
console.log(` Workspace: ${health.workspaceName}`);
console.log(` Dataset: ${health.datasetName}`);
return true;
} catch (error) {
console.error('✗ Flow Myna connection failed:', error);
return false;
}
}Error Handling
Error Handling
import { FlowMyna } from '@flowmyna/sdk';
import {
FlowMynaError,
AuthenticationError,
ValidationError,
RateLimitError,
ServerError
} from '@flowmyna/sdk/errors';
const client = new FlowMyna({ apiKey: 'fm_live_xxx' });
try {
await client.recordEvent({
event: 'Order Placed',
objects: [{ type: 'Order', id: 'ORD-123' }]
});
} catch (error) {
if (error instanceof AuthenticationError) {
// Invalid, revoked, or expired API key
console.error('Authentication failed:', error.message);
} else if (error instanceof ValidationError) {
// Invalid request data
console.error('Validation error:', error.message);
} else if (error instanceof RateLimitError) {
// Rate limited (429)
console.error(`Rate limited. Retry after: ${error.retryAfter}`);
} else if (error instanceof ServerError) {
// Server error (5xx)
console.error('Server error:', error.message);
} else if (error instanceof FlowMynaError) {
// Base exception for all SDK errors
console.error('Flow Myna error:', error.message);
}
}TypeScript Types
The SDK exports all types for full TypeScript support:
TypeScript Types
import {
FlowMyna,
FlowMynaConfig,
EventRequest,
EventObject,
EventResponse,
ObjectUpsertRequest,
ObjectUpsertResponse,
EventBatchResponse,
ObjectBatchResponse,
HealthResponse
} from '@flowmyna/sdk';
// Typed event
const event: EventRequest = {
event: 'Order Placed',
objects: [
{ type: 'Order', id: 'ORD-123' }
],
timestamp: new Date().toISOString(),
properties: {
total: 149.99,
currency: 'USD'
}
};
// Typed configuration
const config: FlowMynaConfig = {
apiKey: process.env.FLOWMYNA_API_KEY!,
timeout: 30000,
maxRetries: 3
};
const client = new FlowMyna(config);
// Response is fully typed
const response: EventResponse = await client.recordEvent(event);
console.log(response.eventId);AI-Assisted Integration
Want an AI assistant to help integrate Flow Myna into your codebase? We provide a comprehensive prompt that guides the AI through analyzing your code, suggesting events to track, and implementing the integration step-by-step.
Complete Example
E-commerce Integration
import { FlowMyna } from '@flowmyna/sdk';
import { FlowMynaError } from '@flowmyna/sdk/errors';
// Types for your application
interface Order {
id: string;
customerId: string;
customerEmail: string;
customerName: string;
total: number;
currency: string;
channel: string;
items: OrderItem[];
createdAt: Date;
}
interface OrderItem {
productId: string;
quantity: number;
price: number;
}
// Initialize client
const client = new FlowMyna({
apiKey: process.env.FLOWMYNA_API_KEY!
});
// Validate connection on startup
async function init() {
const health = await client.health();
console.log(`Connected to ${health.workspaceName}`);
}
async function processOrder(order: Order) {
try {
// Upsert customer with details
await client.upsertObject({
type: 'Customer',
id: order.customerId,
properties: {
email: order.customerEmail,
name: order.customerName
}
});
// Record order creation
await client.recordEvent({
event: 'Order Created',
objects: [
{
type: 'Order',
id: order.id,
properties: {
total: order.total,
currency: order.currency,
itemsCount: order.items.length
}
},
{ type: 'Customer', id: order.customerId }
],
properties: { channel: order.channel }
});
// Record each item
for (const item of order.items) {
await client.recordEvent({
event: 'Item Added',
objects: [
{ type: 'Order', id: order.id },
{ type: 'Product', id: item.productId }
],
properties: {
quantity: item.quantity,
price: item.price
}
});
}
} catch (error) {
if (error instanceof FlowMynaError) {
console.error(`Failed to record order ${order.id}:`, error.message);
}
throw error;
}
}
async function importHistoricalOrders(orders: Order[]) {
const events = orders.map(order => ({
event: 'Order Created',
timestamp: order.createdAt.toISOString(),
objects: [
{ type: 'Order', id: order.id },
{ type: 'Customer', id: order.customerId }
]
}));
// Send in batches of 100
for (let i = 0; i < events.length; i += 100) {
const batch = events.slice(i, i + 100);
const result = await client.recordEventBatch(batch);
console.log(`Imported batch: ${result.processed} events`);
}
}
// Start the application
init();ESM and CommonJS supported. The SDK works with both ES modules and CommonJS. TypeScript support requires TypeScript 4.7+.