@marginfront/sdk 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +310 -0
- package/dist/index.d.mts +1448 -0
- package/dist/index.d.ts +1448 -0
- package/dist/index.js +1365 -0
- package/dist/index.mjs +1311 -0
- package/package.json +60 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1448 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MarginFront SDK Types
|
|
3
|
+
* TypeScript interfaces for all API requests and responses
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Log levels supported by the SDK
|
|
7
|
+
*/
|
|
8
|
+
type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
9
|
+
/**
|
|
10
|
+
* Custom log handler function
|
|
11
|
+
*/
|
|
12
|
+
type LogHandler = (level: LogLevel, message: string, data?: unknown) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Logging configuration options
|
|
15
|
+
*/
|
|
16
|
+
interface LoggingOptions {
|
|
17
|
+
/** Whether logging is enabled */
|
|
18
|
+
enabled?: boolean;
|
|
19
|
+
/** Minimum log level to output */
|
|
20
|
+
level?: LogLevel;
|
|
21
|
+
/** Custom log handler function */
|
|
22
|
+
handler?: LogHandler;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Telemetry handler function
|
|
26
|
+
*/
|
|
27
|
+
type TelemetryHandler = (metrics: RequestMetrics) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Telemetry configuration options
|
|
30
|
+
*/
|
|
31
|
+
interface TelemetryOptions {
|
|
32
|
+
/** Whether telemetry is enabled */
|
|
33
|
+
enabled?: boolean;
|
|
34
|
+
/** Sample rate for telemetry (0-1), 1 = track every request */
|
|
35
|
+
sampleRate?: number;
|
|
36
|
+
/** Custom handler for telemetry events */
|
|
37
|
+
handler?: TelemetryHandler;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Request metrics collected for telemetry
|
|
41
|
+
*/
|
|
42
|
+
interface RequestMetrics {
|
|
43
|
+
/** Unique ID for the request */
|
|
44
|
+
requestId: string;
|
|
45
|
+
/** Request method (GET, POST, etc) */
|
|
46
|
+
method: string;
|
|
47
|
+
/** Normalized request path */
|
|
48
|
+
path: string;
|
|
49
|
+
/** Timestamp when request started */
|
|
50
|
+
startTime: number;
|
|
51
|
+
/** Timestamp when request ended */
|
|
52
|
+
endTime?: number;
|
|
53
|
+
/** Duration of the request in milliseconds */
|
|
54
|
+
duration?: number;
|
|
55
|
+
/** HTTP status code */
|
|
56
|
+
statusCode?: number;
|
|
57
|
+
/** Whether the request was successful */
|
|
58
|
+
success?: boolean;
|
|
59
|
+
/** Error message if request failed */
|
|
60
|
+
errorMessage?: string;
|
|
61
|
+
/** Error type if request failed */
|
|
62
|
+
errorType?: string;
|
|
63
|
+
/** Number of retry attempts */
|
|
64
|
+
retryCount?: number;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Telemetry statistics
|
|
68
|
+
*/
|
|
69
|
+
interface TelemetryStats {
|
|
70
|
+
requestCount: number;
|
|
71
|
+
successCount: number;
|
|
72
|
+
errorCount: number;
|
|
73
|
+
successRate: number;
|
|
74
|
+
averageDuration: number;
|
|
75
|
+
errorBreakdown: Record<string, number>;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Configuration options for the MarginFront client
|
|
79
|
+
*/
|
|
80
|
+
interface MarginFrontConfig {
|
|
81
|
+
/** API key for authentication (format: mf_sk_* or mf_pk_*) */
|
|
82
|
+
apiKey: string;
|
|
83
|
+
/** Base URL for the API */
|
|
84
|
+
baseUrl?: string;
|
|
85
|
+
/** @deprecated Use baseUrl instead */
|
|
86
|
+
baseURL?: string;
|
|
87
|
+
/** Request timeout in milliseconds (default: 30000) */
|
|
88
|
+
timeout?: number;
|
|
89
|
+
/** Number of retry attempts for failed requests (default: 0) */
|
|
90
|
+
retries?: number;
|
|
91
|
+
/** Delay between retry attempts in milliseconds (default: 300) */
|
|
92
|
+
retryDelay?: number;
|
|
93
|
+
/** Custom headers to include in all requests */
|
|
94
|
+
headers?: Record<string, string>;
|
|
95
|
+
/** Enable debug logging (shorthand for logging.enabled) */
|
|
96
|
+
debug?: boolean;
|
|
97
|
+
/** Logging configuration */
|
|
98
|
+
logging?: LoggingOptions;
|
|
99
|
+
/** Telemetry configuration for performance tracking */
|
|
100
|
+
telemetry?: TelemetryOptions;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Client options (config without apiKey)
|
|
104
|
+
*/
|
|
105
|
+
type ClientOptions = Omit<MarginFrontConfig, 'apiKey'>;
|
|
106
|
+
interface Organization {
|
|
107
|
+
id: string;
|
|
108
|
+
name: string;
|
|
109
|
+
}
|
|
110
|
+
interface VerifyResponse {
|
|
111
|
+
organization: Organization;
|
|
112
|
+
verified: boolean;
|
|
113
|
+
createdAt: string;
|
|
114
|
+
updatedAt: string;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* A single usage record to be tracked
|
|
118
|
+
*/
|
|
119
|
+
interface UsageRecord {
|
|
120
|
+
/** Customer's external ID in your system */
|
|
121
|
+
customerExternalId: string;
|
|
122
|
+
/** ID of the agent/product being used */
|
|
123
|
+
agentId: string;
|
|
124
|
+
/** Name of the signal/metric being tracked */
|
|
125
|
+
signalName?: string;
|
|
126
|
+
/** Quantity to record (must be >= 0) */
|
|
127
|
+
quantity?: number;
|
|
128
|
+
/** Optional date for the usage event (defaults to now) */
|
|
129
|
+
usageDate?: string | Date;
|
|
130
|
+
/** Optional metadata to attach to the usage event */
|
|
131
|
+
metadata?: Record<string, unknown>;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Parameters for tracking events - supports single record or batch
|
|
135
|
+
*/
|
|
136
|
+
type TrackEventParams = UsageRecord | {
|
|
137
|
+
records: UsageRecord[];
|
|
138
|
+
};
|
|
139
|
+
/**
|
|
140
|
+
* Response for a single tracked event
|
|
141
|
+
*/
|
|
142
|
+
interface SingleEventResponse {
|
|
143
|
+
/** ID of the recorded usage */
|
|
144
|
+
id: string;
|
|
145
|
+
/** Whether the recording was successful */
|
|
146
|
+
success: boolean;
|
|
147
|
+
/** Additional response data */
|
|
148
|
+
[key: string]: unknown;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Response for batch event tracking
|
|
152
|
+
*/
|
|
153
|
+
interface BatchEventResponse {
|
|
154
|
+
/** Whether the batch operation was successful */
|
|
155
|
+
success: boolean;
|
|
156
|
+
/** Total number of records processed */
|
|
157
|
+
totalRecords: number;
|
|
158
|
+
/** Number of records successfully processed */
|
|
159
|
+
successCount: number;
|
|
160
|
+
/** Number of records that failed to process */
|
|
161
|
+
failureCount: number;
|
|
162
|
+
/** Results for each record */
|
|
163
|
+
results: Array<{
|
|
164
|
+
/** Whether this record was successfully processed */
|
|
165
|
+
success: boolean;
|
|
166
|
+
/** The data for the record, if successful */
|
|
167
|
+
responseData?: SingleEventResponse;
|
|
168
|
+
/** Error message if the record failed */
|
|
169
|
+
error?: string;
|
|
170
|
+
/** The original data that was submitted */
|
|
171
|
+
originalData?: Record<string, unknown>;
|
|
172
|
+
}>;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Response from event tracking - can be single or batch
|
|
176
|
+
*/
|
|
177
|
+
type TrackEventResponse = SingleEventResponse | BatchEventResponse;
|
|
178
|
+
interface UsageRecordSuccess {
|
|
179
|
+
customerExternalId: string;
|
|
180
|
+
agentId: string;
|
|
181
|
+
signalName: string;
|
|
182
|
+
quantity: number;
|
|
183
|
+
eventId: string;
|
|
184
|
+
rawEventId: string;
|
|
185
|
+
timestamp: string;
|
|
186
|
+
}
|
|
187
|
+
interface UsageRecordFailure {
|
|
188
|
+
record: UsageRecord;
|
|
189
|
+
error: string;
|
|
190
|
+
}
|
|
191
|
+
interface UsageRecordResponse {
|
|
192
|
+
processed: number;
|
|
193
|
+
successful: number;
|
|
194
|
+
failed: number;
|
|
195
|
+
results: {
|
|
196
|
+
success: UsageRecordSuccess[];
|
|
197
|
+
failed: UsageRecordFailure[];
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
type CustomerStatus = 'active' | 'inactive' | 'suspended';
|
|
201
|
+
/**
|
|
202
|
+
* Data for creating a new customer
|
|
203
|
+
*/
|
|
204
|
+
interface CreateCustomerData {
|
|
205
|
+
/** Customer name (required) */
|
|
206
|
+
name: string;
|
|
207
|
+
/** Unique external ID in your system */
|
|
208
|
+
externalId?: string;
|
|
209
|
+
/** Customer email address */
|
|
210
|
+
email?: string;
|
|
211
|
+
/** Customer phone number */
|
|
212
|
+
phone?: string;
|
|
213
|
+
/** Customer timezone (default: UTC) */
|
|
214
|
+
timezone?: string;
|
|
215
|
+
/** Customer status */
|
|
216
|
+
status?: CustomerStatus;
|
|
217
|
+
/** Billing contact name */
|
|
218
|
+
billingContactName?: string;
|
|
219
|
+
/** Billing contact email */
|
|
220
|
+
billingContactEmail?: string;
|
|
221
|
+
/** Net payment terms in days (default: 30) */
|
|
222
|
+
netTerms?: number;
|
|
223
|
+
/** List of email addresses to receive invoices */
|
|
224
|
+
invoiceEmailRecipients?: string[];
|
|
225
|
+
/** Custom metadata */
|
|
226
|
+
metadata?: Record<string, unknown>;
|
|
227
|
+
/** Agent ID - if provided, auto-creates a subscription */
|
|
228
|
+
agentId?: string;
|
|
229
|
+
}
|
|
230
|
+
/** Alias for CreateCustomerData */
|
|
231
|
+
type CustomerCreateParams = CreateCustomerData;
|
|
232
|
+
/**
|
|
233
|
+
* Data for updating an existing customer
|
|
234
|
+
*/
|
|
235
|
+
interface UpdateCustomerData {
|
|
236
|
+
name?: string;
|
|
237
|
+
email?: string;
|
|
238
|
+
phone?: string;
|
|
239
|
+
timezone?: string;
|
|
240
|
+
status?: CustomerStatus;
|
|
241
|
+
billingContactName?: string;
|
|
242
|
+
billingContactEmail?: string;
|
|
243
|
+
netTerms?: number;
|
|
244
|
+
invoiceEmailRecipients?: string[];
|
|
245
|
+
metadata?: Record<string, unknown> | null;
|
|
246
|
+
}
|
|
247
|
+
/** Alias for UpdateCustomerData */
|
|
248
|
+
type CustomerUpdateParams = UpdateCustomerData;
|
|
249
|
+
interface CustomerSubscription {
|
|
250
|
+
id: string;
|
|
251
|
+
status: string;
|
|
252
|
+
startDate: string;
|
|
253
|
+
endDate: string | null;
|
|
254
|
+
agent: {
|
|
255
|
+
id: string;
|
|
256
|
+
name: string;
|
|
257
|
+
agentCode: string;
|
|
258
|
+
};
|
|
259
|
+
plan: {
|
|
260
|
+
id: string;
|
|
261
|
+
name: string;
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
interface Customer {
|
|
265
|
+
id: string;
|
|
266
|
+
name: string;
|
|
267
|
+
externalId: string | null;
|
|
268
|
+
email: string | null;
|
|
269
|
+
phone: string | null;
|
|
270
|
+
timezone: string;
|
|
271
|
+
status: CustomerStatus;
|
|
272
|
+
billingContactName: string | null;
|
|
273
|
+
billingContactEmail: string | null;
|
|
274
|
+
netTerms: number;
|
|
275
|
+
invoiceEmailRecipients: string[];
|
|
276
|
+
metadata: Record<string, unknown> | null;
|
|
277
|
+
subscriptions?: CustomerSubscription[];
|
|
278
|
+
createdAt: string;
|
|
279
|
+
updatedAt: string;
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* Parameters for listing customers
|
|
283
|
+
*/
|
|
284
|
+
interface CustomerListParams {
|
|
285
|
+
/** Page number for pagination */
|
|
286
|
+
page?: number;
|
|
287
|
+
/** Number of items per page */
|
|
288
|
+
limit?: number;
|
|
289
|
+
/** Filter by external ID */
|
|
290
|
+
externalId?: string;
|
|
291
|
+
/** Filter by email */
|
|
292
|
+
email?: string;
|
|
293
|
+
/** Search query string */
|
|
294
|
+
query?: string;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Response for customer listing
|
|
298
|
+
*/
|
|
299
|
+
interface CustomerListResponse {
|
|
300
|
+
/** Array of customers */
|
|
301
|
+
data: Customer[];
|
|
302
|
+
/** Total number of results */
|
|
303
|
+
totalResults: number;
|
|
304
|
+
/** Current page number */
|
|
305
|
+
page: number;
|
|
306
|
+
/** Number of items per page */
|
|
307
|
+
limit: number;
|
|
308
|
+
/** Whether there's a next page */
|
|
309
|
+
hasMore: boolean;
|
|
310
|
+
}
|
|
311
|
+
type InvoiceStatus = 'draft' | 'issued' | 'pending' | 'paid' | 'overdue' | 'void';
|
|
312
|
+
interface InvoiceLineItem {
|
|
313
|
+
id: string;
|
|
314
|
+
description: string;
|
|
315
|
+
quantity: number;
|
|
316
|
+
unitPrice: string;
|
|
317
|
+
amount: string;
|
|
318
|
+
signalName?: string;
|
|
319
|
+
}
|
|
320
|
+
interface InvoiceCustomer {
|
|
321
|
+
id: string;
|
|
322
|
+
name: string;
|
|
323
|
+
email: string | null;
|
|
324
|
+
externalId: string | null;
|
|
325
|
+
}
|
|
326
|
+
interface Invoice {
|
|
327
|
+
id: string;
|
|
328
|
+
invoiceNumber: string;
|
|
329
|
+
status: InvoiceStatus;
|
|
330
|
+
invoiceDate: string;
|
|
331
|
+
dueDate: string;
|
|
332
|
+
totalAmount: string;
|
|
333
|
+
amountPaid: string;
|
|
334
|
+
amountDue: string;
|
|
335
|
+
currency: string;
|
|
336
|
+
customer: InvoiceCustomer;
|
|
337
|
+
lineItems: InvoiceLineItem[];
|
|
338
|
+
createdAt: string;
|
|
339
|
+
}
|
|
340
|
+
interface InvoiceDetail extends Invoice {
|
|
341
|
+
payments?: Array<{
|
|
342
|
+
id: string;
|
|
343
|
+
amount: string;
|
|
344
|
+
paymentDate: string;
|
|
345
|
+
paymentMethod: string;
|
|
346
|
+
}>;
|
|
347
|
+
subscription?: {
|
|
348
|
+
id: string;
|
|
349
|
+
status: string;
|
|
350
|
+
agent: {
|
|
351
|
+
id: string;
|
|
352
|
+
name: string;
|
|
353
|
+
};
|
|
354
|
+
plan: {
|
|
355
|
+
id: string;
|
|
356
|
+
name: string;
|
|
357
|
+
};
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
interface ListInvoicesParams {
|
|
361
|
+
/** Filter by customer ID */
|
|
362
|
+
customerId?: string;
|
|
363
|
+
/** Filter by customer external ID */
|
|
364
|
+
customerExternalId?: string;
|
|
365
|
+
/** Filter by invoice status */
|
|
366
|
+
status?: InvoiceStatus;
|
|
367
|
+
/** Page number (default: 1) */
|
|
368
|
+
page?: number;
|
|
369
|
+
/** Results per page (default: 20) */
|
|
370
|
+
limit?: number;
|
|
371
|
+
}
|
|
372
|
+
interface ListInvoicesResponse {
|
|
373
|
+
invoices: Invoice[];
|
|
374
|
+
page: number;
|
|
375
|
+
limit: number;
|
|
376
|
+
totalPages: number;
|
|
377
|
+
totalResults: number;
|
|
378
|
+
}
|
|
379
|
+
type GroupBy = 'daily' | 'weekly' | 'monthly';
|
|
380
|
+
interface UsageAnalyticsParams {
|
|
381
|
+
/** Start date (ISO format, required) */
|
|
382
|
+
startDate: string;
|
|
383
|
+
/** End date (ISO format, required) */
|
|
384
|
+
endDate: string;
|
|
385
|
+
/** Grouping interval (default: daily) */
|
|
386
|
+
groupBy?: GroupBy;
|
|
387
|
+
/** Filter by customer ID */
|
|
388
|
+
customerId?: string;
|
|
389
|
+
/** Filter by customer external ID */
|
|
390
|
+
customerExternalId?: string;
|
|
391
|
+
/** Filter by agent ID */
|
|
392
|
+
agentId?: string;
|
|
393
|
+
/** Filter by signal ID */
|
|
394
|
+
signalId?: string;
|
|
395
|
+
}
|
|
396
|
+
interface UsageAnalyticsSummary {
|
|
397
|
+
totalEvents: number;
|
|
398
|
+
totalQuantity: number;
|
|
399
|
+
totalCost: number;
|
|
400
|
+
uniqueCustomers: number;
|
|
401
|
+
uniqueAgents: number;
|
|
402
|
+
uniqueSignals: number;
|
|
403
|
+
}
|
|
404
|
+
interface UsageAnalyticsDataPoint {
|
|
405
|
+
date: string;
|
|
406
|
+
quantity: number;
|
|
407
|
+
cost: number;
|
|
408
|
+
eventCount: number;
|
|
409
|
+
}
|
|
410
|
+
interface UsageAnalyticsResponse {
|
|
411
|
+
dateRange: {
|
|
412
|
+
start: string;
|
|
413
|
+
end: string;
|
|
414
|
+
groupBy: GroupBy;
|
|
415
|
+
};
|
|
416
|
+
summary: UsageAnalyticsSummary;
|
|
417
|
+
data: UsageAnalyticsDataPoint[];
|
|
418
|
+
}
|
|
419
|
+
type SubscriptionStatus = 'active' | 'paused' | 'cancelled' | 'ended' | 'pending';
|
|
420
|
+
interface SubscriptionCustomer {
|
|
421
|
+
id: string;
|
|
422
|
+
name: string;
|
|
423
|
+
email: string | null;
|
|
424
|
+
externalId: string | null;
|
|
425
|
+
phone?: string | null;
|
|
426
|
+
}
|
|
427
|
+
interface SubscriptionAgent {
|
|
428
|
+
id: string;
|
|
429
|
+
name: string;
|
|
430
|
+
agentCode: string;
|
|
431
|
+
description?: string;
|
|
432
|
+
}
|
|
433
|
+
interface SubscriptionPlan {
|
|
434
|
+
id: string;
|
|
435
|
+
name: string;
|
|
436
|
+
description?: string;
|
|
437
|
+
features?: string[];
|
|
438
|
+
}
|
|
439
|
+
interface Subscription {
|
|
440
|
+
id: string;
|
|
441
|
+
status: SubscriptionStatus;
|
|
442
|
+
startDate: string;
|
|
443
|
+
endDate: string | null;
|
|
444
|
+
billingCycle: string;
|
|
445
|
+
customer: SubscriptionCustomer;
|
|
446
|
+
agent: SubscriptionAgent;
|
|
447
|
+
plan: SubscriptionPlan;
|
|
448
|
+
createdAt: string;
|
|
449
|
+
}
|
|
450
|
+
interface SubscriptionUsage {
|
|
451
|
+
totalQuantity: number;
|
|
452
|
+
totalEvents: number;
|
|
453
|
+
periodStart: string;
|
|
454
|
+
periodEnd: string;
|
|
455
|
+
}
|
|
456
|
+
interface SubscriptionDetail extends Subscription {
|
|
457
|
+
timezone: string;
|
|
458
|
+
usage: SubscriptionUsage;
|
|
459
|
+
updatedAt: string;
|
|
460
|
+
}
|
|
461
|
+
interface ListSubscriptionsParams {
|
|
462
|
+
/** Filter by customer ID */
|
|
463
|
+
customerId?: string;
|
|
464
|
+
/** Filter by customer external ID */
|
|
465
|
+
customerExternalId?: string;
|
|
466
|
+
/** Filter by agent ID */
|
|
467
|
+
agentId?: string;
|
|
468
|
+
/** Filter by subscription status */
|
|
469
|
+
status?: SubscriptionStatus;
|
|
470
|
+
/** Page number (default: 1) */
|
|
471
|
+
page?: number;
|
|
472
|
+
/** Results per page (default: 20) */
|
|
473
|
+
limit?: number;
|
|
474
|
+
}
|
|
475
|
+
interface ListSubscriptionsResponse {
|
|
476
|
+
subscriptions: Subscription[];
|
|
477
|
+
page: number;
|
|
478
|
+
limit: number;
|
|
479
|
+
totalPages: number;
|
|
480
|
+
totalResults: number;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Available features in a portal session
|
|
484
|
+
*/
|
|
485
|
+
type PortalFeature = 'invoices' | 'subscriptions' | 'usage' | 'profile';
|
|
486
|
+
/**
|
|
487
|
+
* Parameters for creating a portal session
|
|
488
|
+
* Requires a secret key (mf_sk_*)
|
|
489
|
+
*/
|
|
490
|
+
interface CreatePortalSessionParams {
|
|
491
|
+
/** Customer ID (internal MarginFront ID) */
|
|
492
|
+
customerId?: string;
|
|
493
|
+
/** Customer external ID (your system's ID) */
|
|
494
|
+
customerExternalId?: string;
|
|
495
|
+
/** URL to redirect customer after portal session */
|
|
496
|
+
returnUrl?: string;
|
|
497
|
+
/** Features to enable in the portal (default: all) */
|
|
498
|
+
features?: PortalFeature[];
|
|
499
|
+
}
|
|
500
|
+
/**
|
|
501
|
+
* Portal session response
|
|
502
|
+
*/
|
|
503
|
+
interface PortalSession {
|
|
504
|
+
/** Portal session ID */
|
|
505
|
+
id: string;
|
|
506
|
+
/** Object type identifier */
|
|
507
|
+
object: 'portal_session';
|
|
508
|
+
/** Full URL for the customer portal */
|
|
509
|
+
url: string;
|
|
510
|
+
/** Portal session token (prtl_*) */
|
|
511
|
+
token: string;
|
|
512
|
+
/** Customer ID */
|
|
513
|
+
customerId: string;
|
|
514
|
+
/** Customer name */
|
|
515
|
+
customerName?: string;
|
|
516
|
+
/** Customer email */
|
|
517
|
+
customerEmail?: string;
|
|
518
|
+
/** Session expiration time */
|
|
519
|
+
expiresAt: string;
|
|
520
|
+
/** Enabled features */
|
|
521
|
+
features: PortalFeature[];
|
|
522
|
+
/** Return URL after session */
|
|
523
|
+
returnUrl?: string;
|
|
524
|
+
/** Session creation time */
|
|
525
|
+
createdAt: string;
|
|
526
|
+
}
|
|
527
|
+
/**
|
|
528
|
+
* List portal sessions parameters
|
|
529
|
+
*/
|
|
530
|
+
interface ListPortalSessionsParams {
|
|
531
|
+
/** Filter by customer ID */
|
|
532
|
+
customerId?: string;
|
|
533
|
+
/** Maximum number of sessions to return */
|
|
534
|
+
limit?: number;
|
|
535
|
+
/** Include expired sessions */
|
|
536
|
+
includeExpired?: boolean;
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* List portal sessions response
|
|
540
|
+
*/
|
|
541
|
+
interface ListPortalSessionsResponse {
|
|
542
|
+
/** Array of portal sessions */
|
|
543
|
+
data: PortalSession[];
|
|
544
|
+
/** Whether there are more results */
|
|
545
|
+
hasMore: boolean;
|
|
546
|
+
}
|
|
547
|
+
interface ApiErrorResponse {
|
|
548
|
+
error: string;
|
|
549
|
+
message: string;
|
|
550
|
+
statusCode: number;
|
|
551
|
+
details?: Record<string, unknown>;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/**
|
|
555
|
+
* Input Validation Utilities
|
|
556
|
+
*/
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* API key type
|
|
560
|
+
*/
|
|
561
|
+
type ApiKeyType = 'secret' | 'publishable';
|
|
562
|
+
/**
|
|
563
|
+
* Parsed API key information
|
|
564
|
+
*/
|
|
565
|
+
interface ParsedApiKey {
|
|
566
|
+
type: ApiKeyType;
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Parse an API key to extract type
|
|
570
|
+
*
|
|
571
|
+
* @param apiKey - The API key to parse
|
|
572
|
+
* @returns Parsed key info or null if invalid format
|
|
573
|
+
*
|
|
574
|
+
* @example
|
|
575
|
+
* ```typescript
|
|
576
|
+
* const info = parseApiKey('mf_sk_xxx');
|
|
577
|
+
* // { type: 'secret' }
|
|
578
|
+
*
|
|
579
|
+
* const pub = parseApiKey('mf_pk_xxx');
|
|
580
|
+
* // { type: 'publishable' }
|
|
581
|
+
* ```
|
|
582
|
+
*/
|
|
583
|
+
declare function parseApiKey(apiKey: string): ParsedApiKey | null;
|
|
584
|
+
/**
|
|
585
|
+
* Check if an API key is a secret key (mf_sk_*)
|
|
586
|
+
*/
|
|
587
|
+
declare function isSecretKey(apiKey: string): boolean;
|
|
588
|
+
/**
|
|
589
|
+
* Check if an API key is a publishable key (mf_pk_*)
|
|
590
|
+
*/
|
|
591
|
+
declare function isPublishableKey(apiKey: string): boolean;
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* HTTP Client Wrapper
|
|
595
|
+
* Handles all API requests with proper error handling, authentication, retry logic, and telemetry
|
|
596
|
+
*/
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* HTTP client for making API requests to MarginFront
|
|
600
|
+
*/
|
|
601
|
+
declare class HttpClient {
|
|
602
|
+
private readonly client;
|
|
603
|
+
private readonly logger;
|
|
604
|
+
private readonly telemetry;
|
|
605
|
+
private readonly retries;
|
|
606
|
+
private readonly retryDelay;
|
|
607
|
+
constructor(config: MarginFrontConfig);
|
|
608
|
+
/**
|
|
609
|
+
* Make a request with retry logic
|
|
610
|
+
*/
|
|
611
|
+
private request;
|
|
612
|
+
/**
|
|
613
|
+
* Make a GET request
|
|
614
|
+
*/
|
|
615
|
+
get<T>(path: string, params?: Record<string, unknown>): Promise<T>;
|
|
616
|
+
/**
|
|
617
|
+
* Make a POST request
|
|
618
|
+
*/
|
|
619
|
+
post<T>(path: string, data?: unknown): Promise<T>;
|
|
620
|
+
/**
|
|
621
|
+
* Make a PUT request
|
|
622
|
+
*/
|
|
623
|
+
put<T>(path: string, data?: unknown): Promise<T>;
|
|
624
|
+
/**
|
|
625
|
+
* Make a PATCH request
|
|
626
|
+
*/
|
|
627
|
+
patch<T>(path: string, data?: unknown): Promise<T>;
|
|
628
|
+
/**
|
|
629
|
+
* Make a DELETE request
|
|
630
|
+
*/
|
|
631
|
+
delete<T = void>(path: string): Promise<T>;
|
|
632
|
+
/**
|
|
633
|
+
* Get telemetry statistics
|
|
634
|
+
*/
|
|
635
|
+
getTelemetryStats(): TelemetryStats;
|
|
636
|
+
/**
|
|
637
|
+
* Reset telemetry statistics
|
|
638
|
+
*/
|
|
639
|
+
resetTelemetryStats(): void;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
/**
|
|
643
|
+
* Usage Resource
|
|
644
|
+
* Handles usage tracking and event recording
|
|
645
|
+
*/
|
|
646
|
+
|
|
647
|
+
/**
|
|
648
|
+
* Resource for recording usage events
|
|
649
|
+
*/
|
|
650
|
+
declare class UsageResource {
|
|
651
|
+
private readonly http;
|
|
652
|
+
constructor(http: HttpClient);
|
|
653
|
+
/**
|
|
654
|
+
* Track events for a customer - supports both single record and batch operations
|
|
655
|
+
*
|
|
656
|
+
* @param params - Event tracking parameters (single record or batch)
|
|
657
|
+
* @returns Tracked event data
|
|
658
|
+
*
|
|
659
|
+
* @example
|
|
660
|
+
* ```typescript
|
|
661
|
+
* // Single event
|
|
662
|
+
* await client.usage.trackEvent({
|
|
663
|
+
* agentId: 'agent_123',
|
|
664
|
+
* customerExternalId: 'customer_456',
|
|
665
|
+
* signalName: 'api_call',
|
|
666
|
+
* quantity: 1
|
|
667
|
+
* });
|
|
668
|
+
*
|
|
669
|
+
* // Batch tracking
|
|
670
|
+
* await client.usage.trackEvent({
|
|
671
|
+
* records: [
|
|
672
|
+
* { customerExternalId: 'cust_1', agentId: 'agent_123', signalName: 'api_call', quantity: 10 },
|
|
673
|
+
* { customerExternalId: 'cust_2', agentId: 'agent_123', signalName: 'storage', quantity: 100 }
|
|
674
|
+
* ]
|
|
675
|
+
* });
|
|
676
|
+
* ```
|
|
677
|
+
*/
|
|
678
|
+
trackEvent(params: TrackEventParams): Promise<TrackEventResponse>;
|
|
679
|
+
/**
|
|
680
|
+
* Record a single usage event
|
|
681
|
+
*
|
|
682
|
+
* @param record - The usage record to track
|
|
683
|
+
* @returns The response containing processing results
|
|
684
|
+
*
|
|
685
|
+
* @example
|
|
686
|
+
* ```typescript
|
|
687
|
+
* const result = await client.usage.record({
|
|
688
|
+
* customerExternalId: 'cust_123',
|
|
689
|
+
* agentId: 'agent_abc',
|
|
690
|
+
* signalName: 'api_call',
|
|
691
|
+
* quantity: 1,
|
|
692
|
+
* metadata: { model: 'gpt-4' }
|
|
693
|
+
* });
|
|
694
|
+
* ```
|
|
695
|
+
*/
|
|
696
|
+
record(record: UsageRecord): Promise<UsageRecordResponse>;
|
|
697
|
+
/**
|
|
698
|
+
* Record multiple usage events in a batch
|
|
699
|
+
*
|
|
700
|
+
* @param records - Array of usage records to track
|
|
701
|
+
* @returns The response containing processing results for all records
|
|
702
|
+
*
|
|
703
|
+
* @example
|
|
704
|
+
* ```typescript
|
|
705
|
+
* const result = await client.usage.recordBatch([
|
|
706
|
+
* { customerExternalId: 'cust_123', agentId: 'agent_abc', signalName: 'api_call', quantity: 5 },
|
|
707
|
+
* { customerExternalId: 'cust_456', agentId: 'agent_abc', signalName: 'api_call', quantity: 3 },
|
|
708
|
+
* ]);
|
|
709
|
+
* console.log(`Processed ${result.successful} of ${result.processed} records`);
|
|
710
|
+
* ```
|
|
711
|
+
*/
|
|
712
|
+
recordBatch(records: UsageRecord[]): Promise<UsageRecordResponse>;
|
|
713
|
+
/**
|
|
714
|
+
* Normalize a usage record
|
|
715
|
+
*/
|
|
716
|
+
private normalizeRecord;
|
|
717
|
+
/**
|
|
718
|
+
* Convert native response to BatchEventResponse format
|
|
719
|
+
*/
|
|
720
|
+
private convertToBatchResponse;
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* Customers Resource
|
|
725
|
+
* Handles customer CRUD operations
|
|
726
|
+
*/
|
|
727
|
+
|
|
728
|
+
/**
|
|
729
|
+
* Resource for managing customers
|
|
730
|
+
*/
|
|
731
|
+
declare class CustomersResource {
|
|
732
|
+
private readonly http;
|
|
733
|
+
constructor(http: HttpClient);
|
|
734
|
+
/**
|
|
735
|
+
* Create a new customer
|
|
736
|
+
*
|
|
737
|
+
* @param params - Customer creation parameters
|
|
738
|
+
* @returns The created customer
|
|
739
|
+
*
|
|
740
|
+
* @example
|
|
741
|
+
* ```typescript
|
|
742
|
+
* const customer = await client.customers.create({
|
|
743
|
+
* name: 'Acme Corp',
|
|
744
|
+
* externalId: 'acme_123',
|
|
745
|
+
* email: 'billing@acme.com',
|
|
746
|
+
* agentId: 'agent_abc' // auto-creates subscription
|
|
747
|
+
* });
|
|
748
|
+
* ```
|
|
749
|
+
*/
|
|
750
|
+
create(params: CreateCustomerData): Promise<Customer>;
|
|
751
|
+
/**
|
|
752
|
+
* Get a single customer by ID
|
|
753
|
+
*
|
|
754
|
+
* @param id - The customer's ID
|
|
755
|
+
* @returns The customer with subscriptions
|
|
756
|
+
*
|
|
757
|
+
* @example
|
|
758
|
+
* ```typescript
|
|
759
|
+
* const customer = await client.customers.get('cust_123');
|
|
760
|
+
* console.log(customer.name);
|
|
761
|
+
* ```
|
|
762
|
+
*/
|
|
763
|
+
get(id: string): Promise<Customer>;
|
|
764
|
+
/**
|
|
765
|
+
* Update an existing customer
|
|
766
|
+
*
|
|
767
|
+
* @param id - The customer's ID
|
|
768
|
+
* @param params - Fields to update
|
|
769
|
+
* @returns The updated customer
|
|
770
|
+
*
|
|
771
|
+
* @example
|
|
772
|
+
* ```typescript
|
|
773
|
+
* const customer = await client.customers.update('cust_123', {
|
|
774
|
+
* name: 'New Company Name',
|
|
775
|
+
* email: 'new-email@company.com'
|
|
776
|
+
* });
|
|
777
|
+
* ```
|
|
778
|
+
*/
|
|
779
|
+
update(id: string, params: UpdateCustomerData): Promise<Customer>;
|
|
780
|
+
/**
|
|
781
|
+
* Delete a customer
|
|
782
|
+
*
|
|
783
|
+
* @param id - The customer's ID
|
|
784
|
+
*
|
|
785
|
+
* @example
|
|
786
|
+
* ```typescript
|
|
787
|
+
* await client.customers.delete('cust_123');
|
|
788
|
+
* ```
|
|
789
|
+
*/
|
|
790
|
+
delete(id: string): Promise<void>;
|
|
791
|
+
/**
|
|
792
|
+
* List customers with pagination and filtering
|
|
793
|
+
*
|
|
794
|
+
* @param params - List parameters
|
|
795
|
+
* @returns Paginated list of customers
|
|
796
|
+
*
|
|
797
|
+
* @example
|
|
798
|
+
* ```typescript
|
|
799
|
+
* const { data, totalResults, hasMore } = await client.customers.list({
|
|
800
|
+
* limit: 10,
|
|
801
|
+
* page: 1
|
|
802
|
+
* });
|
|
803
|
+
* ```
|
|
804
|
+
*/
|
|
805
|
+
list(params?: CustomerListParams): Promise<CustomerListResponse | Customer[]>;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* Invoices Resource
|
|
810
|
+
* Handles invoice retrieval operations
|
|
811
|
+
*/
|
|
812
|
+
|
|
813
|
+
/**
|
|
814
|
+
* Resource for managing invoices
|
|
815
|
+
*/
|
|
816
|
+
declare class InvoicesResource {
|
|
817
|
+
private readonly http;
|
|
818
|
+
constructor(http: HttpClient);
|
|
819
|
+
/**
|
|
820
|
+
* List invoices with optional filters
|
|
821
|
+
*
|
|
822
|
+
* @param params - Optional filter parameters
|
|
823
|
+
* @returns Paginated list of invoices
|
|
824
|
+
*
|
|
825
|
+
* @example
|
|
826
|
+
* ```typescript
|
|
827
|
+
* const { invoices, totalResults } = await client.invoices.list({
|
|
828
|
+
* customerId: 'cust_123',
|
|
829
|
+
* status: 'pending',
|
|
830
|
+
* page: 1,
|
|
831
|
+
* limit: 20
|
|
832
|
+
* });
|
|
833
|
+
* ```
|
|
834
|
+
*/
|
|
835
|
+
list(params?: ListInvoicesParams): Promise<ListInvoicesResponse>;
|
|
836
|
+
/**
|
|
837
|
+
* Get a single invoice by ID
|
|
838
|
+
*
|
|
839
|
+
* @param invoiceId - The invoice's ID
|
|
840
|
+
* @returns The invoice with full details including line items and payments
|
|
841
|
+
*
|
|
842
|
+
* @example
|
|
843
|
+
* ```typescript
|
|
844
|
+
* const invoice = await client.invoices.get('inv_abc');
|
|
845
|
+
* console.log(`Invoice ${invoice.invoiceNumber}: ${invoice.totalAmount}`);
|
|
846
|
+
* ```
|
|
847
|
+
*/
|
|
848
|
+
get(invoiceId: string): Promise<InvoiceDetail>;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
/**
|
|
852
|
+
* Analytics Resource
|
|
853
|
+
* Handles usage analytics and reporting
|
|
854
|
+
*/
|
|
855
|
+
|
|
856
|
+
/**
|
|
857
|
+
* Resource for accessing analytics data
|
|
858
|
+
*/
|
|
859
|
+
declare class AnalyticsResource {
|
|
860
|
+
private readonly http;
|
|
861
|
+
constructor(http: HttpClient);
|
|
862
|
+
/**
|
|
863
|
+
* Get usage analytics for a date range
|
|
864
|
+
*
|
|
865
|
+
* @param params - Analytics query parameters
|
|
866
|
+
* @returns Usage analytics with summary and time-series data
|
|
867
|
+
*
|
|
868
|
+
* @example
|
|
869
|
+
* ```typescript
|
|
870
|
+
* const analytics = await client.analytics.usage({
|
|
871
|
+
* startDate: '2024-01-01',
|
|
872
|
+
* endDate: '2024-01-31',
|
|
873
|
+
* groupBy: 'daily',
|
|
874
|
+
* customerId: 'cust_123'
|
|
875
|
+
* });
|
|
876
|
+
*
|
|
877
|
+
* console.log(`Total usage: ${analytics.summary.totalQuantity}`);
|
|
878
|
+
* console.log(`Total cost: $${analytics.summary.totalCost}`);
|
|
879
|
+
*
|
|
880
|
+
* // Time series data
|
|
881
|
+
* analytics.data.forEach(point => {
|
|
882
|
+
* console.log(`${point.date}: ${point.quantity} units, $${point.cost}`);
|
|
883
|
+
* });
|
|
884
|
+
* ```
|
|
885
|
+
*/
|
|
886
|
+
usage(params: UsageAnalyticsParams): Promise<UsageAnalyticsResponse>;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
/**
|
|
890
|
+
* Subscriptions Resource
|
|
891
|
+
* Handles subscription management operations
|
|
892
|
+
*/
|
|
893
|
+
|
|
894
|
+
/**
|
|
895
|
+
* Resource for managing subscriptions
|
|
896
|
+
*/
|
|
897
|
+
declare class SubscriptionsResource {
|
|
898
|
+
private readonly http;
|
|
899
|
+
constructor(http: HttpClient);
|
|
900
|
+
/**
|
|
901
|
+
* List subscriptions with optional filters
|
|
902
|
+
*
|
|
903
|
+
* @param params - Optional filter parameters
|
|
904
|
+
* @returns Paginated list of subscriptions
|
|
905
|
+
*
|
|
906
|
+
* @example
|
|
907
|
+
* ```typescript
|
|
908
|
+
* const { subscriptions, totalResults } = await client.subscriptions.list({
|
|
909
|
+
* status: 'active',
|
|
910
|
+
* customerId: 'cust_123',
|
|
911
|
+
* page: 1,
|
|
912
|
+
* limit: 20
|
|
913
|
+
* });
|
|
914
|
+
* ```
|
|
915
|
+
*/
|
|
916
|
+
list(params?: ListSubscriptionsParams): Promise<ListSubscriptionsResponse>;
|
|
917
|
+
/**
|
|
918
|
+
* Get a single subscription by ID
|
|
919
|
+
*
|
|
920
|
+
* @param subscriptionId - The subscription's ID
|
|
921
|
+
* @returns The subscription with full details including usage summary
|
|
922
|
+
*
|
|
923
|
+
* @example
|
|
924
|
+
* ```typescript
|
|
925
|
+
* const sub = await client.subscriptions.get('sub_abc');
|
|
926
|
+
* console.log(`Status: ${sub.status}`);
|
|
927
|
+
* console.log(`Usage this period: ${sub.usage.totalQuantity}`);
|
|
928
|
+
* ```
|
|
929
|
+
*/
|
|
930
|
+
get(subscriptionId: string): Promise<SubscriptionDetail>;
|
|
931
|
+
}
|
|
932
|
+
|
|
933
|
+
/**
|
|
934
|
+
* Portal Sessions Resource
|
|
935
|
+
*
|
|
936
|
+
* Create and manage portal sessions for your customers.
|
|
937
|
+
* Portal sessions provide secure, short-lived URLs that allow customers
|
|
938
|
+
* to access their billing information without exposing your API key.
|
|
939
|
+
*
|
|
940
|
+
* This follows the Stripe/Chargebee pattern:
|
|
941
|
+
* 1. Your backend creates a portal session using your secret key
|
|
942
|
+
* 2. You redirect the customer to the portal URL
|
|
943
|
+
* 3. Customer can view invoices, subscriptions, usage (1 hour expiry)
|
|
944
|
+
*
|
|
945
|
+
* @example
|
|
946
|
+
* ```typescript
|
|
947
|
+
* import { MarginFrontClient } from '@marginfront/sdk';
|
|
948
|
+
*
|
|
949
|
+
* const client = new MarginFrontClient('mf_sk_your_secret_key');
|
|
950
|
+
*
|
|
951
|
+
* // Create a portal session
|
|
952
|
+
* const session = await client.portalSessions.create({
|
|
953
|
+
* customerId: 'cust_123',
|
|
954
|
+
* returnUrl: 'https://myapp.com/account'
|
|
955
|
+
* });
|
|
956
|
+
*
|
|
957
|
+
* // Redirect customer to the portal
|
|
958
|
+
* res.redirect(session.url);
|
|
959
|
+
* ```
|
|
960
|
+
*
|
|
961
|
+
* IMPORTANT: Portal session creation requires a secret key (mf_sk_*).
|
|
962
|
+
* Publishable keys cannot create portal sessions.
|
|
963
|
+
*/
|
|
964
|
+
|
|
965
|
+
declare class PortalSessionsResource {
|
|
966
|
+
private readonly http;
|
|
967
|
+
private readonly assertSecretKey;
|
|
968
|
+
constructor(http: HttpClient, assertSecretKey: () => void);
|
|
969
|
+
/**
|
|
970
|
+
* Create a new portal session
|
|
971
|
+
*
|
|
972
|
+
* Creates a short-lived portal session for a customer.
|
|
973
|
+
* The returned URL can be used to redirect the customer to their billing portal.
|
|
974
|
+
*
|
|
975
|
+
* @param params - Portal session parameters
|
|
976
|
+
* @returns Created portal session with URL and token
|
|
977
|
+
* @throws ValidationError if neither customerId nor customerExternalId is provided
|
|
978
|
+
* @throws AuthenticationError if using a publishable key
|
|
979
|
+
*
|
|
980
|
+
* @example
|
|
981
|
+
* ```typescript
|
|
982
|
+
* // By customer ID
|
|
983
|
+
* const session = await client.portalSessions.create({
|
|
984
|
+
* customerId: 'cust_123',
|
|
985
|
+
* returnUrl: 'https://myapp.com/account'
|
|
986
|
+
* });
|
|
987
|
+
*
|
|
988
|
+
* // By external ID
|
|
989
|
+
* const session = await client.portalSessions.create({
|
|
990
|
+
* customerExternalId: 'your_customer_id',
|
|
991
|
+
* features: ['invoices', 'usage']
|
|
992
|
+
* });
|
|
993
|
+
*
|
|
994
|
+
* console.log(session.url); // Redirect customer here
|
|
995
|
+
* ```
|
|
996
|
+
*/
|
|
997
|
+
create(params: CreatePortalSessionParams): Promise<PortalSession>;
|
|
998
|
+
/**
|
|
999
|
+
* Get a portal session by ID
|
|
1000
|
+
*
|
|
1001
|
+
* @param sessionId - Portal session ID
|
|
1002
|
+
* @returns Portal session details
|
|
1003
|
+
*
|
|
1004
|
+
* @example
|
|
1005
|
+
* ```typescript
|
|
1006
|
+
* const session = await client.portalSessions.get('ps_123');
|
|
1007
|
+
* console.log(session.expiresAt);
|
|
1008
|
+
* ```
|
|
1009
|
+
*/
|
|
1010
|
+
get(sessionId: string): Promise<PortalSession>;
|
|
1011
|
+
/**
|
|
1012
|
+
* List portal sessions
|
|
1013
|
+
*
|
|
1014
|
+
* @param params - Optional filters
|
|
1015
|
+
* @returns List of portal sessions
|
|
1016
|
+
*
|
|
1017
|
+
* @example
|
|
1018
|
+
* ```typescript
|
|
1019
|
+
* // List all active sessions
|
|
1020
|
+
* const { data } = await client.portalSessions.list();
|
|
1021
|
+
*
|
|
1022
|
+
* // List sessions for a specific customer
|
|
1023
|
+
* const { data } = await client.portalSessions.list({
|
|
1024
|
+
* customerId: 'cust_123',
|
|
1025
|
+
* includeExpired: true
|
|
1026
|
+
* });
|
|
1027
|
+
* ```
|
|
1028
|
+
*/
|
|
1029
|
+
list(params?: ListPortalSessionsParams): Promise<ListPortalSessionsResponse>;
|
|
1030
|
+
/**
|
|
1031
|
+
* Revoke a portal session
|
|
1032
|
+
*
|
|
1033
|
+
* Immediately invalidates the session, preventing further access.
|
|
1034
|
+
*
|
|
1035
|
+
* @param sessionId - Portal session ID to revoke
|
|
1036
|
+
*
|
|
1037
|
+
* @example
|
|
1038
|
+
* ```typescript
|
|
1039
|
+
* await client.portalSessions.revoke('ps_123');
|
|
1040
|
+
* ```
|
|
1041
|
+
*/
|
|
1042
|
+
revoke(sessionId: string): Promise<void>;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
/**
|
|
1046
|
+
* MarginFront Client
|
|
1047
|
+
* Main entry point for the MarginFront SDK
|
|
1048
|
+
*/
|
|
1049
|
+
|
|
1050
|
+
/**
|
|
1051
|
+
* Organization information from API key verification
|
|
1052
|
+
*/
|
|
1053
|
+
interface OrganizationInfo {
|
|
1054
|
+
id: string;
|
|
1055
|
+
name: string;
|
|
1056
|
+
[key: string]: unknown;
|
|
1057
|
+
}
|
|
1058
|
+
/**
|
|
1059
|
+
* MarginFront SDK Client
|
|
1060
|
+
*
|
|
1061
|
+
* Provides access to all MarginFront API resources including usage tracking,
|
|
1062
|
+
* customer management, invoicing, analytics, and subscriptions.
|
|
1063
|
+
*
|
|
1064
|
+
* @example
|
|
1065
|
+
* ```typescript
|
|
1066
|
+
* import { MarginFrontClient } from '@marginfront/sdk';
|
|
1067
|
+
*
|
|
1068
|
+
* const client = new MarginFrontClient('mf_sk_your_secret_key');
|
|
1069
|
+
* await client.connect();
|
|
1070
|
+
*
|
|
1071
|
+
* // Track usage
|
|
1072
|
+
* await client.trackEvent({
|
|
1073
|
+
* agentId: 'agent_123',
|
|
1074
|
+
* customerExternalId: 'customer_456',
|
|
1075
|
+
* signalName: 'api_call',
|
|
1076
|
+
* quantity: 1
|
|
1077
|
+
* });
|
|
1078
|
+
*
|
|
1079
|
+
* // Or with full configuration
|
|
1080
|
+
* const client = new MarginFrontClient('mf_sk_your_secret_key', {
|
|
1081
|
+
* timeout: 10000,
|
|
1082
|
+
* retries: 3,
|
|
1083
|
+
* logging: { enabled: true, level: 'info' },
|
|
1084
|
+
* telemetry: { enabled: true }
|
|
1085
|
+
* });
|
|
1086
|
+
* ```
|
|
1087
|
+
*/
|
|
1088
|
+
declare class MarginFrontClient {
|
|
1089
|
+
private readonly http;
|
|
1090
|
+
private readonly _apiKey;
|
|
1091
|
+
private readonly _keyType;
|
|
1092
|
+
private _orgInfo;
|
|
1093
|
+
/**
|
|
1094
|
+
* Usage tracking resource
|
|
1095
|
+
*
|
|
1096
|
+
* @example
|
|
1097
|
+
* ```typescript
|
|
1098
|
+
* await client.usage.record({
|
|
1099
|
+
* customerExternalId: 'cust_123',
|
|
1100
|
+
* agentId: 'agent_abc',
|
|
1101
|
+
* signalName: 'api_call',
|
|
1102
|
+
* quantity: 1
|
|
1103
|
+
* });
|
|
1104
|
+
* ```
|
|
1105
|
+
*/
|
|
1106
|
+
readonly usage: UsageResource;
|
|
1107
|
+
/**
|
|
1108
|
+
* Customer management resource
|
|
1109
|
+
*
|
|
1110
|
+
* @example
|
|
1111
|
+
* ```typescript
|
|
1112
|
+
* const customer = await client.customers.create({
|
|
1113
|
+
* name: 'Acme Corp',
|
|
1114
|
+
* externalId: 'acme_123'
|
|
1115
|
+
* });
|
|
1116
|
+
* ```
|
|
1117
|
+
*/
|
|
1118
|
+
readonly customers: CustomersResource;
|
|
1119
|
+
/**
|
|
1120
|
+
* Invoice retrieval resource
|
|
1121
|
+
*
|
|
1122
|
+
* @example
|
|
1123
|
+
* ```typescript
|
|
1124
|
+
* const { invoices } = await client.invoices.list({
|
|
1125
|
+
* status: 'pending'
|
|
1126
|
+
* });
|
|
1127
|
+
* ```
|
|
1128
|
+
*/
|
|
1129
|
+
readonly invoices: InvoicesResource;
|
|
1130
|
+
/**
|
|
1131
|
+
* Analytics resource
|
|
1132
|
+
*
|
|
1133
|
+
* @example
|
|
1134
|
+
* ```typescript
|
|
1135
|
+
* const analytics = await client.analytics.usage({
|
|
1136
|
+
* startDate: '2024-01-01',
|
|
1137
|
+
* endDate: '2024-01-31'
|
|
1138
|
+
* });
|
|
1139
|
+
* ```
|
|
1140
|
+
*/
|
|
1141
|
+
readonly analytics: AnalyticsResource;
|
|
1142
|
+
/**
|
|
1143
|
+
* Subscription management resource
|
|
1144
|
+
*
|
|
1145
|
+
* @example
|
|
1146
|
+
* ```typescript
|
|
1147
|
+
* const { subscriptions } = await client.subscriptions.list({
|
|
1148
|
+
* status: 'active'
|
|
1149
|
+
* });
|
|
1150
|
+
* ```
|
|
1151
|
+
*/
|
|
1152
|
+
readonly subscriptions: SubscriptionsResource;
|
|
1153
|
+
/**
|
|
1154
|
+
* Portal sessions resource
|
|
1155
|
+
* Create and manage customer portal sessions
|
|
1156
|
+
*
|
|
1157
|
+
* IMPORTANT: Requires a secret key (mf_sk_*). Publishable keys cannot create portal sessions.
|
|
1158
|
+
*
|
|
1159
|
+
* @example
|
|
1160
|
+
* ```typescript
|
|
1161
|
+
* const session = await client.portalSessions.create({
|
|
1162
|
+
* customerId: 'cust_123',
|
|
1163
|
+
* returnUrl: 'https://myapp.com/account'
|
|
1164
|
+
* });
|
|
1165
|
+
*
|
|
1166
|
+
* // Redirect customer to the portal
|
|
1167
|
+
* res.redirect(session.url);
|
|
1168
|
+
* ```
|
|
1169
|
+
*/
|
|
1170
|
+
readonly portalSessions: PortalSessionsResource;
|
|
1171
|
+
/**
|
|
1172
|
+
* Create a new MarginFront client
|
|
1173
|
+
*
|
|
1174
|
+
* @param apiKeyOrConfig - Either an API key string or a configuration object
|
|
1175
|
+
* @param options - Optional client options (when first param is API key)
|
|
1176
|
+
*
|
|
1177
|
+
* @example
|
|
1178
|
+
* ```typescript
|
|
1179
|
+
* // Simple initialization
|
|
1180
|
+
* const client = new MarginFrontClient('mf_sk_your_secret_key');
|
|
1181
|
+
*
|
|
1182
|
+
* // With options
|
|
1183
|
+
* const client = new MarginFrontClient('mf_sk_your_secret_key', {
|
|
1184
|
+
* timeout: 10000,
|
|
1185
|
+
* retries: 3
|
|
1186
|
+
* });
|
|
1187
|
+
*
|
|
1188
|
+
* // With config object
|
|
1189
|
+
* const client = new MarginFrontClient({
|
|
1190
|
+
* apiKey: 'mf_sk_your_secret_key',
|
|
1191
|
+
* baseUrl: 'https://api.example.com/v1',
|
|
1192
|
+
* debug: true
|
|
1193
|
+
* });
|
|
1194
|
+
* ```
|
|
1195
|
+
*/
|
|
1196
|
+
constructor(apiKeyOrConfig: string | MarginFrontConfig, options?: ClientOptions);
|
|
1197
|
+
/**
|
|
1198
|
+
* Assert that the current API key is a secret key
|
|
1199
|
+
* @throws ValidationError if using a publishable key
|
|
1200
|
+
*/
|
|
1201
|
+
private assertSecretKey;
|
|
1202
|
+
/**
|
|
1203
|
+
* Connect to the MarginFront API and verify credentials
|
|
1204
|
+
*
|
|
1205
|
+
* This must be called once before using any API methods that require verification.
|
|
1206
|
+
* Optional but recommended for validating your API key.
|
|
1207
|
+
*
|
|
1208
|
+
* @returns Promise resolving to the client instance for chaining
|
|
1209
|
+
* @throws AuthenticationError if API key is invalid
|
|
1210
|
+
* @throws InitializationError for other initialization errors
|
|
1211
|
+
*
|
|
1212
|
+
* @example
|
|
1213
|
+
* ```typescript
|
|
1214
|
+
* const client = new MarginFrontClient('mf_sk_your_secret_key');
|
|
1215
|
+
*
|
|
1216
|
+
* try {
|
|
1217
|
+
* await client.connect();
|
|
1218
|
+
* console.log('Connected to MarginFront API');
|
|
1219
|
+
* } catch (error) {
|
|
1220
|
+
* console.error('Failed to connect:', error);
|
|
1221
|
+
* }
|
|
1222
|
+
* ```
|
|
1223
|
+
*/
|
|
1224
|
+
connect(): Promise<MarginFrontClient>;
|
|
1225
|
+
/**
|
|
1226
|
+
* Verify the API key and get organization details
|
|
1227
|
+
*
|
|
1228
|
+
* @returns Verification result with organization info
|
|
1229
|
+
*
|
|
1230
|
+
* @example
|
|
1231
|
+
* ```typescript
|
|
1232
|
+
* const result = await client.verify();
|
|
1233
|
+
* if (result.verified) {
|
|
1234
|
+
* console.log(`Connected to ${result.organization.name}`);
|
|
1235
|
+
* }
|
|
1236
|
+
* ```
|
|
1237
|
+
*/
|
|
1238
|
+
verify(): Promise<VerifyResponse>;
|
|
1239
|
+
/**
|
|
1240
|
+
* Get organization information
|
|
1241
|
+
*
|
|
1242
|
+
* @returns Organization information from API key verification
|
|
1243
|
+
* @throws Error if organization info is not available (call connect() first)
|
|
1244
|
+
*
|
|
1245
|
+
* @example
|
|
1246
|
+
* ```typescript
|
|
1247
|
+
* await client.connect();
|
|
1248
|
+
* const org = client.getOrganization();
|
|
1249
|
+
* console.log(`Organization: ${org.name}`);
|
|
1250
|
+
* ```
|
|
1251
|
+
*/
|
|
1252
|
+
getOrganization(): OrganizationInfo;
|
|
1253
|
+
/**
|
|
1254
|
+
* Track event for a customer (shorthand method)
|
|
1255
|
+
*
|
|
1256
|
+
* @param params - Event tracking parameters
|
|
1257
|
+
* @returns Tracked event data
|
|
1258
|
+
*
|
|
1259
|
+
* @example
|
|
1260
|
+
* ```typescript
|
|
1261
|
+
* // Simple event tracking
|
|
1262
|
+
* await client.trackEvent({
|
|
1263
|
+
* agentId: 'agent_123',
|
|
1264
|
+
* customerExternalId: 'customer_456',
|
|
1265
|
+
* signalName: 'api_call',
|
|
1266
|
+
* quantity: 1
|
|
1267
|
+
* });
|
|
1268
|
+
*
|
|
1269
|
+
* // Batch tracking
|
|
1270
|
+
* await client.trackEvent({
|
|
1271
|
+
* records: [
|
|
1272
|
+
* { customerExternalId: 'cust_1', agentId: 'agent_123', signalName: 'api_call', quantity: 10 },
|
|
1273
|
+
* { customerExternalId: 'cust_2', agentId: 'agent_123', signalName: 'storage', quantity: 100 }
|
|
1274
|
+
* ]
|
|
1275
|
+
* });
|
|
1276
|
+
* ```
|
|
1277
|
+
*/
|
|
1278
|
+
trackEvent(params: TrackEventParams): Promise<TrackEventResponse>;
|
|
1279
|
+
/**
|
|
1280
|
+
* Re-verify the API key
|
|
1281
|
+
*
|
|
1282
|
+
* Useful if you suspect the API key status might have changed
|
|
1283
|
+
*
|
|
1284
|
+
* @returns Updated organization information
|
|
1285
|
+
*/
|
|
1286
|
+
verifyApiKey(): Promise<OrganizationInfo>;
|
|
1287
|
+
/**
|
|
1288
|
+
* Get current telemetry statistics
|
|
1289
|
+
*
|
|
1290
|
+
* @returns Telemetry statistics
|
|
1291
|
+
*
|
|
1292
|
+
* @example
|
|
1293
|
+
* ```typescript
|
|
1294
|
+
* const stats = client.getTelemetryStats();
|
|
1295
|
+
* console.log(`Total Requests: ${stats.requestCount}`);
|
|
1296
|
+
* console.log(`Success Rate: ${(stats.successRate * 100).toFixed(2)}%`);
|
|
1297
|
+
* ```
|
|
1298
|
+
*/
|
|
1299
|
+
getTelemetryStats(): TelemetryStats;
|
|
1300
|
+
/**
|
|
1301
|
+
* Reset telemetry statistics
|
|
1302
|
+
*/
|
|
1303
|
+
resetTelemetryStats(): void;
|
|
1304
|
+
/**
|
|
1305
|
+
* Get the API key type (secret or publishable)
|
|
1306
|
+
*
|
|
1307
|
+
* @returns 'secret' for mf_sk_* keys, 'publishable' for mf_pk_* keys
|
|
1308
|
+
*
|
|
1309
|
+
* @example
|
|
1310
|
+
* ```typescript
|
|
1311
|
+
* if (client.getKeyType() === 'secret') {
|
|
1312
|
+
* const session = await client.portalSessions.create({ ... });
|
|
1313
|
+
* }
|
|
1314
|
+
* ```
|
|
1315
|
+
*/
|
|
1316
|
+
getKeyType(): ApiKeyType;
|
|
1317
|
+
/**
|
|
1318
|
+
* Check if the API key is a secret key (mf_sk_*)
|
|
1319
|
+
*
|
|
1320
|
+
* @returns true if the key can perform server-side operations
|
|
1321
|
+
*/
|
|
1322
|
+
isSecretKey(): boolean;
|
|
1323
|
+
/**
|
|
1324
|
+
* Check if the API key is a publishable key (mf_pk_*)
|
|
1325
|
+
*
|
|
1326
|
+
* @returns true if the key is safe for frontend use
|
|
1327
|
+
*/
|
|
1328
|
+
isPublishableKey(): boolean;
|
|
1329
|
+
/**
|
|
1330
|
+
* Get a masked version of the API key for debugging
|
|
1331
|
+
*
|
|
1332
|
+
* @returns Masked API key showing only prefix and last 4 characters
|
|
1333
|
+
*/
|
|
1334
|
+
getMaskedApiKey(): string;
|
|
1335
|
+
}
|
|
1336
|
+
|
|
1337
|
+
/**
|
|
1338
|
+
* MarginFront SDK Error Classes
|
|
1339
|
+
* Custom error types for different API error scenarios
|
|
1340
|
+
*/
|
|
1341
|
+
/**
|
|
1342
|
+
* Base error class for all MarginFront SDK errors
|
|
1343
|
+
*/
|
|
1344
|
+
declare class MarginFrontError extends Error {
|
|
1345
|
+
/** HTTP status code from the API response */
|
|
1346
|
+
readonly statusCode: number;
|
|
1347
|
+
/** Error code for programmatic handling */
|
|
1348
|
+
readonly code: string;
|
|
1349
|
+
/** Additional error details from the API */
|
|
1350
|
+
readonly details?: Record<string, unknown>;
|
|
1351
|
+
/** Additional error metadata */
|
|
1352
|
+
readonly metadata: Record<string, unknown>;
|
|
1353
|
+
/** Request ID associated with the error */
|
|
1354
|
+
readonly requestId?: string;
|
|
1355
|
+
constructor(message: string, statusCode?: number, code?: string, details?: Record<string, unknown>, metadata?: Record<string, unknown>);
|
|
1356
|
+
}
|
|
1357
|
+
/**
|
|
1358
|
+
* Thrown when API authentication fails (401)
|
|
1359
|
+
* Usually indicates an invalid or expired API key
|
|
1360
|
+
*/
|
|
1361
|
+
declare class AuthenticationError extends MarginFrontError {
|
|
1362
|
+
constructor(message?: string, metadata?: Record<string, unknown>);
|
|
1363
|
+
}
|
|
1364
|
+
/**
|
|
1365
|
+
* Thrown when the API key doesn't have permission for the requested action (403)
|
|
1366
|
+
*/
|
|
1367
|
+
declare class AuthorizationError extends MarginFrontError {
|
|
1368
|
+
constructor(message?: string, metadata?: Record<string, unknown>);
|
|
1369
|
+
}
|
|
1370
|
+
/**
|
|
1371
|
+
* Thrown when a requested resource is not found (404)
|
|
1372
|
+
*/
|
|
1373
|
+
declare class NotFoundError extends MarginFrontError {
|
|
1374
|
+
/** The type of resource that was not found */
|
|
1375
|
+
readonly resourceType?: string;
|
|
1376
|
+
/** The ID of the resource that was not found */
|
|
1377
|
+
readonly resourceId?: string;
|
|
1378
|
+
constructor(message?: string, resourceType?: string, resourceId?: string, metadata?: Record<string, unknown>);
|
|
1379
|
+
}
|
|
1380
|
+
/**
|
|
1381
|
+
* Thrown when request validation fails (400/422)
|
|
1382
|
+
* Contains details about which fields failed validation
|
|
1383
|
+
*/
|
|
1384
|
+
declare class ValidationError extends MarginFrontError {
|
|
1385
|
+
/** Object containing field-level validation errors */
|
|
1386
|
+
readonly validationErrors?: Record<string, string[]>;
|
|
1387
|
+
constructor(message?: string, validationErrors?: Record<string, string[]>, metadata?: Record<string, unknown>);
|
|
1388
|
+
}
|
|
1389
|
+
/**
|
|
1390
|
+
* Thrown when the API rate limit is exceeded (429)
|
|
1391
|
+
*/
|
|
1392
|
+
declare class RateLimitError extends MarginFrontError {
|
|
1393
|
+
/** Number of seconds to wait before retrying */
|
|
1394
|
+
readonly retryAfter?: number;
|
|
1395
|
+
constructor(message?: string, retryAfter?: number, metadata?: Record<string, unknown>);
|
|
1396
|
+
}
|
|
1397
|
+
/**
|
|
1398
|
+
* Thrown when there's a conflict with the current state (409)
|
|
1399
|
+
*/
|
|
1400
|
+
declare class ConflictError extends MarginFrontError {
|
|
1401
|
+
constructor(message?: string, metadata?: Record<string, unknown>);
|
|
1402
|
+
}
|
|
1403
|
+
/**
|
|
1404
|
+
* Thrown when a network error occurs (no response from server)
|
|
1405
|
+
*/
|
|
1406
|
+
declare class NetworkError extends MarginFrontError {
|
|
1407
|
+
/** The original error that caused the network failure */
|
|
1408
|
+
readonly originalError?: Error;
|
|
1409
|
+
constructor(message?: string, originalError?: Error, metadata?: Record<string, unknown>);
|
|
1410
|
+
}
|
|
1411
|
+
/**
|
|
1412
|
+
* Thrown when a request times out
|
|
1413
|
+
*/
|
|
1414
|
+
declare class TimeoutError extends MarginFrontError {
|
|
1415
|
+
/** The timeout value in milliseconds that was exceeded */
|
|
1416
|
+
readonly timeoutMs?: number;
|
|
1417
|
+
constructor(message?: string, timeoutMs?: number, metadata?: Record<string, unknown>);
|
|
1418
|
+
}
|
|
1419
|
+
/**
|
|
1420
|
+
* Thrown when an internal server error occurs (500)
|
|
1421
|
+
*/
|
|
1422
|
+
declare class InternalError extends MarginFrontError {
|
|
1423
|
+
constructor(message?: string, metadata?: Record<string, unknown>);
|
|
1424
|
+
}
|
|
1425
|
+
/**
|
|
1426
|
+
* Thrown when SDK initialization fails
|
|
1427
|
+
*/
|
|
1428
|
+
declare class InitializationError extends MarginFrontError {
|
|
1429
|
+
constructor(message?: string, metadata?: Record<string, unknown>);
|
|
1430
|
+
}
|
|
1431
|
+
/**
|
|
1432
|
+
* Generic API error
|
|
1433
|
+
*/
|
|
1434
|
+
declare class ApiError extends MarginFrontError {
|
|
1435
|
+
/** API error code if available */
|
|
1436
|
+
readonly errorCode?: string;
|
|
1437
|
+
constructor(message?: string, statusCode?: number, errorCode?: string, metadata?: Record<string, unknown>);
|
|
1438
|
+
}
|
|
1439
|
+
/**
|
|
1440
|
+
* Maps HTTP status codes to appropriate error classes
|
|
1441
|
+
*/
|
|
1442
|
+
declare function createErrorFromResponse(statusCode: number, message: string, details?: Record<string, unknown>, metadata?: Record<string, unknown>): MarginFrontError;
|
|
1443
|
+
/**
|
|
1444
|
+
* Parse API error response into appropriate error object
|
|
1445
|
+
*/
|
|
1446
|
+
declare function parseApiError(error: unknown): MarginFrontError;
|
|
1447
|
+
|
|
1448
|
+
export { ApiError, type ApiErrorResponse, type ApiKeyType, AuthenticationError, AuthorizationError, type BatchEventResponse, type ClientOptions, ConflictError, type CreateCustomerData, type CreatePortalSessionParams, type Customer, type CustomerCreateParams, type CustomerListParams, type CustomerListResponse, type CustomerStatus, type CustomerSubscription, type CustomerUpdateParams, type GroupBy, InitializationError, InternalError, type Invoice, type InvoiceCustomer, type InvoiceDetail, type InvoiceLineItem, type InvoiceStatus, type ListInvoicesParams, type ListInvoicesResponse, type ListPortalSessionsParams, type ListPortalSessionsResponse, type ListSubscriptionsParams, type ListSubscriptionsResponse, type LogHandler, type LogLevel, type LoggingOptions, MarginFrontClient, type MarginFrontConfig, MarginFrontError, NetworkError, NotFoundError, type Organization, type OrganizationInfo, type PortalFeature, type PortalSession, RateLimitError, type RequestMetrics, type SingleEventResponse, type Subscription, type SubscriptionAgent, type SubscriptionCustomer, type SubscriptionDetail, type SubscriptionPlan, type SubscriptionStatus, type SubscriptionUsage, type TelemetryHandler, type TelemetryOptions, type TelemetryStats, TimeoutError, type TrackEventParams, type TrackEventResponse, type UpdateCustomerData, type UsageAnalyticsDataPoint, type UsageAnalyticsParams, type UsageAnalyticsResponse, type UsageAnalyticsSummary, type UsageRecord, type UsageRecordFailure, type UsageRecordResponse, type UsageRecordSuccess, ValidationError, type VerifyResponse, createErrorFromResponse, isPublishableKey, isSecretKey, parseApiError, parseApiKey };
|