Package Exports
- @marginfront/sdk
Readme
@marginfront/sdk
Official Node.js SDK for MarginFront. Simplify integration with MarginFront's billing, customer management, and usage tracking services.
Installation
npm install @marginfront/sdk
# or
yarn add @marginfront/sdkQuick Start
import { MarginFrontClient } from '@marginfront/sdk';
const client = new MarginFrontClient('mf_sk_your_secret_key');
// Track a usage event
await client.trackEvent({
agentId: 'agent_123',
customerExternalId: 'customer_456',
signalName: 'api_call',
quantity: 1,
});Documentation
- Configuration Options
- Event Tracking Examples
- Usage Cost Tracking
- Customer Management
- Error Handling
- Advanced Features
Configuration
const client = new MarginFrontClient('mf_sk_your_secret_key', {
baseUrl: 'https://api.marginfront.com/v1',
timeout: 10000,
retries: 3,
retryDelay: 300,
logging: {
enabled: true,
level: 'info',
},
telemetry: {
enabled: true,
sampleRate: 1,
},
});
await client.connect();Usage Examples
Event Tracking
// Simple event tracking
await client.trackEvent({
agentId: 'agent_123',
customerExternalId: 'customer_456',
signalName: 'api_call',
quantity: 1,
});
// Event with metadata and usage cost tracking
await client.trackEvent({
agentId: 'agent_123',
customerExternalId: 'customer_456',
signalName: 'email_sent',
quantity: 1,
metadata: {
eventId: 'email_sent',
usageCost: [
{
serviceName: 'LLM',
units: 7,
},
{
serviceName: 'Intuit',
units: 1,
},
],
},
});
// Batch tracking
await client.trackEvent({
records: [
{
customerExternalId: 'customer_456',
agentId: 'agent_123',
signalName: 'api_call',
quantity: 10,
metadata: {
endpoint: '/api/v1/search',
},
},
{
customerExternalId: 'customer_789',
agentId: 'agent_123',
signalName: 'storage',
quantity: 100,
usageDate: new Date('2023-08-15'),
metadata: {
storageType: 'object',
},
},
],
});Usage Cost Tracking
Track detailed cost breakdown through the usageCost field in metadata:
await client.trackEvent({
agentId: 'agent_123',
customerExternalId: 'customer_456',
signalName: 'lead_generated',
quantity: 1,
metadata: {
eventId: 'lead_generated',
usageCost: [
{
serviceName: 'wfloengine',
units: 1,
},
],
},
});The usageCost field structure:
| Field | Type | Description |
|---|---|---|
| serviceName | string | Name of the service (e.g., 'LLM', 'TTS') |
| units | number | Number of units consumed |
Customer Management
// Create a customer
const customer = await client.customers.create({
name: 'Acme Corp',
email: 'billing@acmecorp.com',
externalId: 'acme-123',
});
// List customers
const customers = await client.customers.list({
limit: 10,
page: 1,
});
// Get, update and delete customers
const customer = await client.customers.get('customer_id');
await client.customers.update('customer_id', { name: 'Updated Name' });
await client.customers.delete('customer_id');Invoices
// List invoices with filters
const { invoices, totalResults } = await client.invoices.list({
customerId: 'cust_123',
status: 'pending',
page: 1,
limit: 20,
});
// Get a specific invoice
const invoice = await client.invoices.get('inv_abc');
console.log(`Invoice ${invoice.invoiceNumber}: $${invoice.totalAmount}`);Analytics
const analytics = await client.analytics.usage({
startDate: '2024-01-01',
endDate: '2024-01-31',
groupBy: 'daily',
customerId: 'cust_123',
});
console.log(`Total usage: ${analytics.summary.totalQuantity}`);
console.log(`Total cost: $${analytics.summary.totalCost}`);
// Time series data
analytics.data.forEach((point) => {
console.log(`${point.date}: ${point.quantity} units, $${point.cost}`);
});Subscriptions
// List subscriptions
const { subscriptions } = await client.subscriptions.list({
status: 'active',
customerId: 'cust_123',
});
// Get subscription with usage details
const sub = await client.subscriptions.get('sub_abc');
console.log(`Usage this period: ${sub.usage.totalQuantity}`);Portal Sessions
// Create a portal session (requires secret key mf_sk_*)
const session = await client.portalSessions.create({
customerId: 'cust_123',
returnUrl: 'https://myapp.com/account',
features: ['invoices', 'usage', 'subscriptions'],
});
// Redirect customer to the portal
res.redirect(session.url);Error Handling
import {
MarginFrontClient,
MarginFrontError,
AuthenticationError,
RateLimitError,
ValidationError,
} from '@marginfront/sdk';
try {
await client.connect();
await client.trackEvent({
/* ... */
});
} catch (error) {
if (error instanceof AuthenticationError) {
console.error(`Authentication failed. Request ID: ${error.requestId}`);
} else if (error instanceof RateLimitError) {
console.error(`Rate limit exceeded. Retry after ${error.retryAfter}s`);
} else if (error instanceof ValidationError) {
console.error(`Validation error: ${error.message}`);
} else if (error instanceof MarginFrontError) {
console.error(`API Error (${error.statusCode}): ${error.message}`);
}
}Advanced Features
Request Retries
const client = new MarginFrontClient('mf_sk_your_secret_key', {
retries: 3,
retryDelay: 300,
});Logging & Telemetry
The SDK includes a telemetry system that tracks API request performance and usage patterns:
const client = new MarginFrontClient('mf_sk_your_secret_key', {
logging: {
enabled: true,
level: 'debug',
handler: (level, message, data) => {
myLoggingSystem.log(level, message, data);
},
},
telemetry: {
enabled: true,
sampleRate: 0.5, // Track 50% of requests
handler: (metrics) => {
myMonitoringSystem.trackApiRequest(metrics);
},
},
});You can access telemetry statistics programmatically:
// Get current statistics
const stats = client.getTelemetryStats();
console.log(`Total Requests: ${stats.requestCount}`);
console.log(`Success Rate: ${(stats.successRate * 100).toFixed(2)}%`);CLI (Testing Tool)
The SDK ships with a lightweight CLI (mf) for testing your integration without writing code.
Note: The CLI is a testing tool only. It has no effect on the SDK when used as a library in your application.
Install globally
npm install -g @marginfront/sdkThen run commands from anywhere:
mf verify
mf track-event --customer-id customer-1 --agent-id <uuid> --signal CALL_MINUTES --quantity 10Commands
mf verify
Verifies your API key and returns organization details.
mf verify [options]
Options:
--api-key <key> API key (mf_sk_* or mf_pk_*)
--base-url <url> API base URL (default: https://api.marginfront.com/v1)
--debug Enable debug outputmf track-event
Sends a single usage event to the API.
mf track-event [options]
Options:
--api-key <key> API key (mf_sk_*)
--base-url <url> API base URL (default: https://api.marginfront.com/v1)
--customer-id <id> Customer external ID
--agent-id <id> Agent UUID
--signal <name> Signal name (e.g. CALL_MINUTES)
--quantity <number> Quantity to record (default: 1)
--metadata <json> Optional metadata as a JSON string
--debug Enable debug outputDefault values via .env.marginfront.cli
To avoid repeating flags, create a .env.marginfront.cli file in the directory where you run the CLI. Any value set here is used as a default and can be overridden by passing the flag directly.
# ⚠️ FOR TESTING ONLY
# This file is NOT used when the SDK is imported as a library.
# It only applies when running the mf CLI.
MF_API_KEY=mf_sk_your_key_here
MF_BASE_URL=http://localhost:4000/v1
MF_AGENT_ID=your-agent-uuid
MF_CUSTOMER_ID=customer-1
MF_SIGNAL=CALL_MINUTES
MF_QUANTITY=10
MF_DEBUG=falsePriority: CLI flags > .env.marginfront.cli > built-in defaults
| CLI Flag | .env Key |
|---|---|
--api-key |
MF_API_KEY |
--base-url |
MF_BASE_URL |
--customer-id |
MF_CUSTOMER_ID |
--agent-id |
MF_AGENT_ID |
--signal |
MF_SIGNAL |
--quantity |
MF_QUANTITY |
--debug |
MF_DEBUG |
Add .env.marginfront.cli to your .gitignore to avoid committing test credentials.
License
MIT License. See LICENSE for details.