@heymantle/core-api-client 0.1.6 → 0.1.7

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/README.md CHANGED
@@ -40,153 +40,800 @@ const client = new MantleCoreClient({
40
40
  });
41
41
  ```
42
42
 
43
+ ## Middleware
44
+
45
+ The client supports Koa-style middleware for intercepting requests and responses. Middleware can be used for logging, authentication refresh, retry logic, and more.
46
+
47
+ ### Creating Custom Middleware
48
+
49
+ ```typescript
50
+ import { MantleCoreClient, type Middleware } from '@heymantle/core-api-client';
51
+
52
+ // Logging middleware
53
+ const loggingMiddleware: Middleware = async (ctx, next) => {
54
+ const start = Date.now();
55
+ console.log(`[Request] ${ctx.request.method} ${ctx.request.url}`);
56
+
57
+ await next();
58
+
59
+ const duration = Date.now() - start;
60
+ console.log(`[Response] ${ctx.response?.status} (${duration}ms)`);
61
+ };
62
+
63
+ // Register middleware
64
+ const client = new MantleCoreClient({ apiKey: 'your-api-key' });
65
+ client.use(loggingMiddleware, { name: 'logging', priority: 10 });
66
+ ```
67
+
68
+ ### Auth Refresh Middleware
69
+
70
+ Automatically refresh expired access tokens:
71
+
72
+ ```typescript
73
+ import { MantleCoreClient, createAuthRefreshMiddleware } from '@heymantle/core-api-client';
74
+
75
+ const client = new MantleCoreClient({
76
+ accessToken: 'initial-token',
77
+ });
78
+
79
+ client.use(
80
+ createAuthRefreshMiddleware({
81
+ refreshToken: async () => {
82
+ // Call your token refresh endpoint
83
+ const response = await fetch('/api/refresh', { method: 'POST' });
84
+ const data = await response.json();
85
+ return data.accessToken;
86
+ },
87
+ onRefreshSuccess: (newToken) => {
88
+ // Persist the new token
89
+ localStorage.setItem('accessToken', newToken);
90
+ },
91
+ onRefreshFailed: (error) => {
92
+ // Redirect to login
93
+ window.location.href = '/login';
94
+ },
95
+ maxRefreshAttempts: 1,
96
+ }),
97
+ { name: 'auth-refresh' }
98
+ );
99
+ ```
100
+
101
+ ### Middleware at Construction
102
+
103
+ ```typescript
104
+ const client = new MantleCoreClient({
105
+ apiKey: 'your-api-key',
106
+ middleware: [
107
+ loggingMiddleware,
108
+ [retryMiddleware, { name: 'retry', priority: 5 }],
109
+ ],
110
+ });
111
+ ```
112
+
113
+ ### Middleware Context
114
+
115
+ ```typescript
116
+ interface MiddlewareContext<T = unknown> {
117
+ request: {
118
+ url: string;
119
+ method: 'GET' | 'POST' | 'PUT' | 'DELETE';
120
+ headers: Record<string, string>;
121
+ body?: string;
122
+ endpoint: string;
123
+ };
124
+ response?: {
125
+ data: T;
126
+ status: number;
127
+ headers: Headers;
128
+ };
129
+ error?: Error;
130
+ retry: boolean; // Set to true to retry the request
131
+ retryCount: number;
132
+ maxRetries: number;
133
+ updateAuth: (credentials: { apiKey?: string; accessToken?: string }) => void;
134
+ }
135
+ ```
136
+
43
137
  ## Resources
44
138
 
45
139
  ### Customers
46
140
 
47
141
  ```typescript
48
142
  // List customers with filters
49
- const { customers } = await client.customers.list({
143
+ const { customers, hasNextPage, total } = await client.customers.list({
50
144
  take: 25,
51
145
  search: 'acme',
52
146
  appIds: ['app_123'],
147
+ shopifyShopDomain: 'store.myshopify.com',
148
+ shopifyShopId: '12345',
149
+ includeUsageMetrics: true,
150
+ includeContactCount: true,
151
+ sort: 'createdAt',
152
+ sortDirection: 'desc',
153
+ });
154
+
155
+ // Retrieve a customer
156
+ const { customer } = await client.customers.retrieve('cust_123', {
157
+ includeContactCount: true,
158
+ includeCurrentInvoice: true,
53
159
  });
54
160
 
55
161
  // Create a customer
56
162
  const { customer } = await client.customers.create({
57
163
  name: 'Acme Inc',
58
164
  email: 'contact@acme.com',
59
- tags: ['enterprise'],
165
+ domain: 'acme.com',
166
+ shopifyDomain: 'acme.myshopify.com',
167
+ shopifyShopId: '12345',
168
+ countryCode: 'US',
169
+ preferredCurrency: 'USD',
170
+ description: 'Enterprise customer',
171
+ tags: ['enterprise', 'priority'],
172
+ customFields: { industry: 'Technology', employees: 500 },
173
+ companyId: 'company_123',
174
+ appInstallations: [
175
+ { appId: 'app_123', installedAt: '2024-01-15T00:00:00Z', test: false },
176
+ ],
60
177
  });
61
178
 
62
179
  // Update a customer
63
180
  const { customer } = await client.customers.update('cust_123', {
64
181
  name: 'Acme Corporation',
182
+ tags: ['enterprise', 'vip'],
65
183
  });
66
184
 
67
185
  // Add/remove tags
68
- await client.customers.addTags('cust_123', ['premium']);
186
+ await client.customers.addTags('cust_123', ['premium', 'partner']);
69
187
  await client.customers.removeTags('cust_123', ['trial']);
70
188
 
71
- // Get customer timeline
72
- const { events } = await client.customers.getTimeline('cust_123');
189
+ // Timeline events
190
+ const { events, hasNextPage } = await client.customers.getTimeline('cust_123', {
191
+ appId: 'app_123',
192
+ type: 'subscription.created',
193
+ limit: 50,
194
+ cursor: 'cursor_abc',
195
+ });
196
+
197
+ // Account owners
198
+ const { accountOwners } = await client.customers.listAccountOwners('cust_123');
199
+ const { accountOwner } = await client.customers.addAccountOwner('cust_123', {
200
+ email: 'owner@acme.com',
201
+ name: 'John Owner',
202
+ });
203
+ await client.customers.removeAccountOwner('cust_123', 'owner_123');
204
+
205
+ // Custom fields
206
+ const { customFields } = await client.customers.listCustomFields({ appId: 'app_123' });
207
+ const { customField } = await client.customers.createCustomField({
208
+ appId: 'app_123',
209
+ name: 'Industry',
210
+ type: 'select', // 'string' | 'number' | 'boolean' | 'date' | 'select'
211
+ options: ['Technology', 'Healthcare', 'Finance', 'Retail'],
212
+ defaultValue: 'Technology',
213
+ showOnCustomerDetail: true,
214
+ filterable: true,
215
+ private: false,
216
+ });
217
+ const { customField } = await client.customers.retrieveCustomField('field_123');
218
+ const { customField } = await client.customers.updateCustomField('field_123', {
219
+ name: 'Industry Type',
220
+ options: ['Technology', 'Healthcare', 'Finance', 'Retail', 'Other'],
221
+ });
222
+ await client.customers.deleteCustomField('field_123');
73
223
  ```
74
224
 
75
225
  ### Contacts
76
226
 
77
227
  ```typescript
78
- const { contacts } = await client.contacts.list();
228
+ // List contacts
229
+ const { contacts, hasNextPage } = await client.contacts.list({
230
+ take: 25,
231
+ search: 'john',
232
+ socialProfileType: 'linkedin', // 'linkedin' | 'x' | 'facebook' | 'instagram' | 'website'
233
+ socialProfileUrl: 'https://linkedin.com/in/johndoe',
234
+ });
235
+
236
+ // Create a contact with social profiles
79
237
  const { contact } = await client.contacts.create({
80
238
  name: 'John Doe',
81
- email: 'john@example.com',
239
+ email: 'john@acme.com',
240
+ phone: '+1-555-123-4567',
241
+ jobTitle: 'CTO',
242
+ notes: 'Primary technical contact',
243
+ tags: ['decision-maker', 'technical'],
244
+ customers: ['cust_123', 'cust_456'],
245
+ socialProfiles: [
246
+ { key: 'linkedin', value: 'https://linkedin.com/in/johndoe' },
247
+ { key: 'x', value: 'https://x.com/johndoe' },
248
+ { key: 'website', value: 'https://johndoe.com' },
249
+ ],
250
+ });
251
+
252
+ // Update a contact
253
+ const { contact } = await client.contacts.update('contact_123', {
254
+ jobTitle: 'VP of Engineering',
255
+ socialProfiles: [
256
+ { key: 'linkedin', value: 'https://linkedin.com/in/johndoe-updated' },
257
+ ],
82
258
  });
259
+
260
+ // Retrieve a contact
261
+ const { contact } = await client.contacts.retrieve('contact_123');
83
262
  ```
84
263
 
85
264
  ### Subscriptions
86
265
 
87
266
  ```typescript
88
- const { subscriptions } = await client.subscriptions.list({
267
+ // List subscriptions
268
+ const { subscriptions, hasNextPage } = await client.subscriptions.list({
89
269
  appId: 'app_123',
270
+ customerId: 'cust_123',
90
271
  active: true,
272
+ ids: ['sub_123', 'sub_456'],
273
+ startDate: '2024-01-01',
274
+ endDate: '2024-12-31',
91
275
  });
276
+
277
+ // Retrieve a subscription
92
278
  const { subscription } = await client.subscriptions.retrieve('sub_123');
93
279
  ```
94
280
 
95
- ### Apps & Plans
281
+ ### Deals
282
+
283
+ Deals support multiple ways to link customers and contacts:
284
+
285
+ ```typescript
286
+ // List deals with filters
287
+ const { deals, hasNextPage, total } = await client.deals.list({
288
+ customerId: 'cust_123',
289
+ appId: 'app_123',
290
+ planId: 'plan_123',
291
+ dealStageId: 'stage_123',
292
+ dealFlowId: 'flow_123',
293
+ affiliateId: 'aff_123',
294
+ partnershipId: 'partner_123',
295
+ acquirerId: 'user_123',
296
+ ownerId: 'user_456',
297
+ contactId: 'contact_123',
298
+ stage: 'negotiation',
299
+ minAmount: 1000,
300
+ maxAmount: 50000,
301
+ acquisitionChannel: 'inbound',
302
+ acquisitionSource: 'website',
303
+ includeArchived: false,
304
+ });
305
+
306
+ // Create a deal - Option 1: Link existing customer
307
+ const { deal } = await client.deals.create({
308
+ name: 'Enterprise Deal',
309
+ amount: 50000,
310
+ amountCurrencyCode: 'USD',
311
+ customerId: 'cust_123',
312
+ contactIds: ['contact_123', 'contact_456'],
313
+ dealFlowId: 'flow_123',
314
+ dealStageId: 'stage_123',
315
+ appId: 'app_123',
316
+ planId: 'plan_456',
317
+ ownerIds: ['user_123'],
318
+ acquisitionChannel: 'outbound',
319
+ acquisitionSource: 'sales_call',
320
+ firstInteractionAt: '2024-01-15T10:00:00Z',
321
+ closingAt: '2024-03-01T00:00:00Z',
322
+ notes: 'High priority enterprise deal',
323
+ });
324
+
325
+ // Create a deal - Option 2: Create/update customer inline
326
+ const { deal } = await client.deals.create({
327
+ name: 'New Prospect Deal',
328
+ amount: 25000,
329
+ // Customer will be matched by domain or created if not found
330
+ customer: {
331
+ name: 'Acme Corp',
332
+ email: 'info@acme.com',
333
+ domain: 'acme.com',
334
+ shopifyDomain: 'acme.myshopify.com',
335
+ shopifyShopId: '12345',
336
+ tags: ['prospect'],
337
+ countryCode: 'US',
338
+ preferredCurrency: 'USD',
339
+ },
340
+ // Contacts will be matched by email or created if not found
341
+ contacts: [
342
+ {
343
+ email: 'john@acme.com',
344
+ name: 'John Doe',
345
+ phone: '+1-555-123-4567',
346
+ jobTitle: 'CEO',
347
+ label: 'primary',
348
+ notes: 'Decision maker',
349
+ tags: ['executive'],
350
+ },
351
+ {
352
+ email: 'jane@acme.com',
353
+ name: 'Jane Smith',
354
+ jobTitle: 'CTO',
355
+ label: 'technical',
356
+ },
357
+ ],
358
+ dealFlowId: 'flow_123',
359
+ dealStageId: 'stage_123',
360
+ });
361
+
362
+ // Create a deal - Option 3: Find/create customer by domain
363
+ const { deal } = await client.deals.create({
364
+ name: 'Domain-based Deal',
365
+ shopifyDomain: 'newstore.myshopify.com',
366
+ dealFlowId: 'flow_123',
367
+ dealStageId: 'stage_123',
368
+ });
369
+
370
+ // Update a deal
371
+ const { deal } = await client.deals.update('deal_123', {
372
+ amount: 75000,
373
+ dealStageId: 'stage_456',
374
+ closedAt: '2024-02-15T00:00:00Z',
375
+ notes: 'Deal closed successfully!',
376
+ });
377
+
378
+ // Archive a deal
379
+ await client.deals.del('deal_123');
380
+
381
+ // Get deal timeline
382
+ const { events } = await client.deals.getTimeline('deal_123');
383
+
384
+ // Get deal events
385
+ const { events } = await client.deals.getEvents('deal_123');
386
+ ```
387
+
388
+ ### Deal Flows
389
+
390
+ Manage deal pipelines and stages:
391
+
392
+ ```typescript
393
+ // List deal flows
394
+ const { dealFlows } = await client.dealFlows.list();
395
+
396
+ // Retrieve a deal flow with stages
397
+ const { dealFlow } = await client.dealFlows.retrieve('flow_123');
398
+ // dealFlow.stages contains the ordered stages
399
+
400
+ // Create a deal flow
401
+ const { dealFlow } = await client.dealFlows.create({
402
+ name: 'Enterprise Sales Pipeline',
403
+ description: 'For deals over $10k',
404
+ });
405
+
406
+ // Update a deal flow
407
+ const { dealFlow } = await client.dealFlows.update('flow_123', {
408
+ name: 'Enterprise Sales Pipeline v2',
409
+ });
410
+
411
+ // Delete a deal flow
412
+ await client.dealFlows.del('flow_123');
413
+ ```
414
+
415
+ ### Deal Activities
416
+
417
+ Track activities within deal flows:
418
+
419
+ ```typescript
420
+ // List deal activities
421
+ const { dealActivities } = await client.dealActivities.list();
422
+
423
+ // Retrieve a deal activity
424
+ const { dealActivity } = await client.dealActivities.retrieve('activity_123');
425
+
426
+ // Create a deal activity
427
+ const { dealActivity } = await client.dealActivities.create({
428
+ name: 'Initial Call',
429
+ dealFlowId: 'flow_123',
430
+ description: 'First discovery call with prospect',
431
+ order: 1,
432
+ });
433
+
434
+ // Update a deal activity
435
+ const { dealActivity } = await client.dealActivities.update('activity_123', {
436
+ name: 'Discovery Call',
437
+ description: 'Updated description',
438
+ });
439
+
440
+ // Delete a deal activity
441
+ await client.dealActivities.del('activity_123');
442
+ ```
443
+
444
+ ### Apps
96
445
 
97
446
  ```typescript
98
447
  // List apps
99
- const { apps } = await client.apps.list();
448
+ const { apps } = await client.apps.list({
449
+ minUpdatedAt: '2024-01-01T00:00:00Z',
450
+ maxUpdatedAt: '2024-12-31T23:59:59Z',
451
+ });
452
+
453
+ // Retrieve an app
454
+ const { app } = await client.apps.retrieve('app_123');
455
+ ```
456
+
457
+ ### Plans
100
458
 
459
+ ```typescript
101
460
  // List plans for an app
102
- const { plans } = await client.apps.listPlans('app_123');
461
+ const { plans, total, hasMore } = await client.apps.listPlans('app_123', {
462
+ public: true,
463
+ page: 0,
464
+ perPage: 25,
465
+ search: 'pro',
466
+ });
467
+
468
+ // Retrieve a plan
469
+ const { plan } = await client.apps.retrievePlan('app_123', 'plan_123');
103
470
 
104
- // Create a plan
471
+ // Create a plan with usage charges and features
105
472
  const { plan } = await client.apps.createPlan('app_123', {
106
473
  name: 'Pro Plan',
107
- amount: 2900,
474
+ description: 'For growing businesses',
475
+ amount: 4900, // $49.00
108
476
  currencyCode: 'USD',
109
- interval: 'month',
477
+ interval: 'month', // 'month' | 'year' | 'one_time'
478
+ trialDays: 14,
479
+ public: true,
480
+ visible: true,
481
+ customerTags: ['premium'],
482
+ customerExcludeTags: ['churned'],
483
+ shopifyPlans: ['shopify', 'advanced'],
484
+ flexBilling: true,
485
+ flexBillingTerms: 'Charged at end of billing period',
486
+ // Usage-based pricing
487
+ planUsageCharges: [
488
+ {
489
+ usageMetricId: 'metric_123',
490
+ cappedAmount: 10000, // $100 cap
491
+ terms: '$0.01 per API call',
492
+ interval: 'month',
493
+ },
494
+ ],
495
+ // Feature flags
496
+ features: [
497
+ { featureId: 'feature_api', value: true },
498
+ { featureId: 'feature_seats', value: 10 },
499
+ ],
500
+ customFields: { tier: 'mid' },
110
501
  });
111
502
 
112
- // Manage features
503
+ // Update a plan
504
+ const { plan } = await client.apps.updatePlan('app_123', 'plan_123', {
505
+ amount: 5900,
506
+ description: 'Updated description',
507
+ });
508
+
509
+ // Archive/unarchive a plan
510
+ await client.apps.archivePlan('app_123', 'plan_123');
511
+ await client.apps.unarchivePlan('app_123', 'plan_123');
512
+ ```
513
+
514
+ ### Features
515
+
516
+ ```typescript
517
+ // List features
113
518
  const { features } = await client.apps.listFeatures('app_123');
519
+
520
+ // Retrieve a feature
521
+ const { feature } = await client.apps.retrieveFeature('app_123', 'feature_123');
522
+
523
+ // Create a feature
114
524
  const { feature } = await client.apps.createFeature('app_123', {
115
525
  name: 'API Access',
116
- type: 'boolean',
526
+ type: 'boolean', // 'boolean' | 'limit' | 'unlimited'
527
+ description: 'Access to REST API',
528
+ usageMetricId: 'metric_123', // Link to usage tracking
529
+ });
530
+
531
+ // Update a feature
532
+ const { feature } = await client.apps.updateFeature('app_123', 'feature_123', {
533
+ name: 'API Access v2',
534
+ description: 'Updated description',
117
535
  });
536
+
537
+ // Delete a feature
538
+ await client.apps.deleteFeature('app_123', 'feature_123');
118
539
  ```
119
540
 
120
- ### Deals
541
+ ### Usage Metrics
121
542
 
122
543
  ```typescript
123
- const { deals } = await client.deals.list({
124
- customerId: 'cust_123',
125
- stage: 'negotiation',
544
+ // List usage metrics
545
+ const { usageMetrics } = await client.apps.listUsageMetrics('app_123');
546
+
547
+ // Retrieve a usage metric
548
+ const { usageMetric } = await client.apps.retrieveUsageMetric('app_123', 'metric_123');
549
+
550
+ // Create a usage metric
551
+ const { usageMetric } = await client.apps.createUsageMetric('app_123', {
552
+ name: 'API Calls',
553
+ description: 'Number of API requests',
554
+ eventName: 'api_call',
555
+ aggregationType: 'count',
126
556
  });
127
557
 
128
- const { deal } = await client.deals.create({
129
- name: 'Enterprise Deal',
130
- amount: 50000,
558
+ // Update a usage metric
559
+ const { usageMetric } = await client.apps.updateUsageMetric('app_123', 'metric_123', {
560
+ name: 'API Requests',
561
+ });
562
+
563
+ // Delete a usage metric
564
+ await client.apps.deleteUsageMetric('app_123', 'metric_123');
565
+
566
+ // Get event names for an app
567
+ const { eventNames } = await client.apps.listEventNames('app_123');
568
+
569
+ // Get property keys for an event
570
+ const { propertyKeys } = await client.apps.listPropertyKeys('app_123', 'api_call');
571
+ ```
572
+
573
+ ### App Events
574
+
575
+ ```typescript
576
+ // List app events
577
+ const { appEvents, hasNextPage } = await client.apps.listAppEvents('app_123', {
131
578
  customerId: 'cust_123',
579
+ take: 50,
580
+ });
581
+ ```
582
+
583
+ ### Reviews
584
+
585
+ ```typescript
586
+ // List reviews
587
+ const { reviews } = await client.apps.listReviews('app_123');
588
+
589
+ // Retrieve a review
590
+ const { review } = await client.apps.retrieveReview('app_123', 'review_123');
591
+
592
+ // Create a review
593
+ const { review } = await client.apps.createReview('app_123', {
594
+ rating: 5,
595
+ title: 'Excellent app!',
596
+ body: 'This app transformed our workflow.',
597
+ });
598
+
599
+ // Update a review
600
+ const { review } = await client.apps.updateReview('app_123', 'review_123', {
601
+ rating: 4,
602
+ body: 'Updated review text',
132
603
  });
604
+
605
+ // Delete a review
606
+ await client.apps.deleteReview('app_123', 'review_123');
133
607
  ```
134
608
 
135
609
  ### Tickets
136
610
 
137
611
  ```typescript
138
- const { tickets } = await client.tickets.list({
139
- status: 'open',
140
- priority: 'high',
612
+ // List tickets with filters
613
+ const { tickets, hasNextPage, total } = await client.tickets.list({
614
+ status: 'open', // 'open' | 'pending' | 'resolved' | 'closed'
615
+ priority: 'high', // 'low' | 'medium' | 'high' | 'urgent'
616
+ assignedToId: 'user_123',
617
+ appId: 'app_123',
618
+ customerId: 'cust_123',
619
+ contactId: 'contact_123',
620
+ channelId: 'channel_123',
621
+ tags: ['billing', 'urgent'],
622
+ take: 25,
141
623
  });
142
624
 
625
+ // Retrieve a ticket
626
+ const { ticket } = await client.tickets.retrieve('ticket_123');
627
+
628
+ // Create a ticket - Option 1: Link existing contact
143
629
  const { ticket } = await client.tickets.create({
144
630
  subject: 'Need help with integration',
631
+ status: 'open',
632
+ priority: 'medium',
145
633
  customerId: 'cust_123',
634
+ contactId: 'contact_123',
635
+ appId: 'app_123',
636
+ channelId: 'channel_123',
637
+ assignedToId: 'user_123',
638
+ tags: ['integration', 'api'],
639
+ });
640
+
641
+ // Create a ticket - Option 2: Create contact inline
642
+ const { ticket } = await client.tickets.create({
643
+ subject: 'Billing question',
644
+ priority: 'high',
645
+ customerId: 'cust_123',
646
+ contact: {
647
+ email: 'support-requester@acme.com',
648
+ name: 'Support User',
649
+ },
146
650
  });
147
651
 
148
- // Add a message
652
+ // Update a ticket
653
+ const { ticket } = await client.tickets.update('ticket_123', {
654
+ status: 'pending',
655
+ priority: 'urgent',
656
+ assignedToId: 'user_456',
657
+ tags: ['escalated'],
658
+ });
659
+
660
+ // Delete a ticket
661
+ await client.tickets.del('ticket_123');
662
+
663
+ // List messages for a ticket
664
+ const { messages } = await client.tickets.listMessages('ticket_123');
665
+
666
+ // Retrieve a message
667
+ const { message } = await client.tickets.retrieveMessage('ticket_123', 'message_123');
668
+
669
+ // Create a message with attachments
149
670
  const { message } = await client.tickets.createMessage('ticket_123', {
150
- body: 'Here is the solution...',
151
- from: 'agent',
671
+ body: 'Here is the solution to your problem...',
672
+ from: 'agent', // 'customer' | 'agent'
673
+ attachments: [
674
+ {
675
+ filename: 'solution.pdf',
676
+ url: 'https://storage.example.com/solution.pdf',
677
+ contentType: 'application/pdf',
678
+ size: 102400,
679
+ },
680
+ ],
681
+ });
682
+
683
+ // Update a message
684
+ const { message } = await client.tickets.updateMessage('ticket_123', 'message_123', {
685
+ body: 'Updated message content',
686
+ });
687
+
688
+ // Delete a message
689
+ await client.tickets.deleteMessage('ticket_123', 'message_123');
690
+ ```
691
+
692
+ ### Channels
693
+
694
+ Manage CX channels for tickets:
695
+
696
+ ```typescript
697
+ // List channels
698
+ const { channels } = await client.channels.list({
699
+ type: 'email', // 'email' | 'chat'
700
+ });
701
+
702
+ // Create a channel
703
+ const { channel } = await client.channels.create({
704
+ type: 'email',
705
+ name: 'Support Email',
152
706
  });
153
707
  ```
154
708
 
709
+ ### Agents
710
+
711
+ List support agents:
712
+
713
+ ```typescript
714
+ // List agents
715
+ const { agents } = await client.agents.list();
716
+ ```
717
+
155
718
  ### Metrics
156
719
 
720
+ Retrieve analytics and business metrics:
721
+
157
722
  ```typescript
158
- // Get MRR
723
+ import type { DateRangeType } from '@heymantle/core-api-client';
724
+
725
+ // Date range options:
726
+ // 'last_30_minutes' | 'last_60_minutes' | 'last_12_hours' | 'last_24_hours'
727
+ // 'last_7_days' | 'last_14_days' | 'last_30_days' | 'last_90_days'
728
+ // 'last_12_months' | 'last_24_months'
729
+ // 'today' | 'yesterday' | 'last_month'
730
+ // 'month_to_date' | 'quarter_to_date' | 'year_to_date'
731
+ // 'all_time' | 'custom'
732
+
733
+ // Monthly Recurring Revenue
159
734
  const mrr = await client.metrics.mrr({
160
735
  appId: 'app_123',
161
736
  dateRange: 'last_30_days',
162
737
  });
738
+ console.log(mrr.total, mrr.formattedTotal); // 50000, "$500.00"
739
+ console.log(mrr.change, mrr.changePercentage); // 5000, 10
163
740
 
164
- // Get ARR
741
+ // Annual Recurring Revenue
165
742
  const arr = await client.metrics.arr({ appId: 'app_123' });
166
743
 
167
- // Other metrics
744
+ // Average Revenue Per User
168
745
  const arpu = await client.metrics.arpu({ appId: 'app_123' });
169
- const churn = await client.metrics.revenueChurn({ appId: 'app_123' });
746
+
747
+ // Customer Lifetime Value
170
748
  const ltv = await client.metrics.ltv({ appId: 'app_123' });
749
+
750
+ // Predicted LTV
751
+ const predictedLtv = await client.metrics.predictedLtv({ appId: 'app_123' });
752
+
753
+ // Revenue Churn
754
+ const revenueChurn = await client.metrics.revenueChurn({ appId: 'app_123' });
755
+
756
+ // Logo (Customer) Churn
757
+ const logoChurn = await client.metrics.logoChurn({ appId: 'app_123' });
758
+
759
+ // Revenue Retention
760
+ const revenueRetention = await client.metrics.revenueRetention({ appId: 'app_123' });
761
+
762
+ // Net Revenue Retention
171
763
  const nrr = await client.metrics.netRevenueRetention({ appId: 'app_123' });
172
764
 
765
+ // Net Revenue
766
+ const netRevenue = await client.metrics.netRevenue({ appId: 'app_123' });
767
+
768
+ // Active Subscriptions
769
+ const activeSubs = await client.metrics.activeSubscriptions({ appId: 'app_123' });
770
+
771
+ // Active Installs
772
+ const activeInstalls = await client.metrics.activeInstalls({ appId: 'app_123' });
773
+
774
+ // Net Installs
775
+ const netInstalls = await client.metrics.netInstalls({ appId: 'app_123' });
776
+
777
+ // Charges
778
+ const charges = await client.metrics.charges({ appId: 'app_123' });
779
+
780
+ // Payout
781
+ const payout = await client.metrics.payout({ appId: 'app_123' });
782
+
783
+ // Usage event metrics
784
+ const usageMetrics = await client.metrics.usageEvent({
785
+ appId: 'app_123',
786
+ eventName: 'api_call',
787
+ propertyKey: 'endpoint',
788
+ aggregation: 'count', // 'count' | 'sum' | 'avg' | 'min' | 'max'
789
+ dateRange: 'last_7_days',
790
+ });
791
+
792
+ // Usage metric by ID
793
+ const metricData = await client.metrics.usageMetric({
794
+ appId: 'app_123',
795
+ metricId: 'metric_123',
796
+ dateRange: 'last_30_days',
797
+ });
798
+
173
799
  // Custom metric query
174
800
  const data = await client.metrics.fetch({
175
801
  metric: 'PlatformApp.activeInstalls',
176
802
  appId: 'app_123',
177
803
  dateRange: 'last_90_days',
804
+ startDate: '2024-01-01',
805
+ endDate: '2024-03-31',
806
+ includes: ['includeTotal'],
807
+ appEventsForMrr: true,
178
808
  });
179
809
  ```
180
810
 
181
811
  ### Usage Events
182
812
 
813
+ Track customer usage for billing:
814
+
183
815
  ```typescript
816
+ // List usage events
817
+ const { usageEvents, hasNextPage } = await client.usageEvents.list({
818
+ appId: 'app_123',
819
+ customerId: 'cust_123',
820
+ eventName: 'api_call',
821
+ billingStatus: 'unbilled',
822
+ countryCode: 'US',
823
+ startDate: '2024-01-01',
824
+ endDate: '2024-01-31',
825
+ propertiesFilters: { endpoint: '/users' },
826
+ });
827
+
184
828
  // Track a single event
185
829
  await client.usageEvents.create({
186
830
  eventName: 'api_call',
187
831
  customerId: 'cust_123',
188
832
  appId: 'app_123',
189
- properties: { endpoint: '/users', method: 'GET' },
833
+ timestamp: new Date().toISOString(),
834
+ eventId: 'unique-event-id', // For deduplication
835
+ properties: { endpoint: '/users', method: 'GET', responseTime: 150 },
836
+ private: false,
190
837
  });
191
838
 
192
839
  // Track multiple events
@@ -194,6 +841,7 @@ await client.usageEvents.create({
194
841
  events: [
195
842
  { eventName: 'api_call', customerId: 'cust_123', appId: 'app_123' },
196
843
  { eventName: 'api_call', customerId: 'cust_456', appId: 'app_123' },
844
+ { eventName: 'file_upload', customerId: 'cust_123', appId: 'app_123', properties: { size: 1024 } },
197
845
  ],
198
846
  });
199
847
  ```
@@ -201,56 +849,341 @@ await client.usageEvents.create({
201
849
  ### Webhooks
202
850
 
203
851
  ```typescript
852
+ // List webhooks
204
853
  const { webhooks } = await client.webhooks.list();
205
854
 
855
+ // Retrieve a webhook
856
+ const { webhook } = await client.webhooks.retrieve('webhook_123');
857
+
858
+ // Create a webhook
206
859
  const { webhook } = await client.webhooks.create({
207
860
  topic: 'customer.created',
208
861
  address: 'https://your-app.com/webhooks',
209
862
  });
863
+
864
+ // Update a webhook
865
+ const { webhook } = await client.webhooks.update('webhook_123', {
866
+ address: 'https://your-app.com/webhooks/v2',
867
+ });
868
+
869
+ // Delete a webhook
870
+ await client.webhooks.del('webhook_123');
210
871
  ```
211
872
 
212
873
  ### Affiliates
213
874
 
214
875
  ```typescript
215
- const { affiliates } = await client.affiliates.list({
876
+ // List affiliates
877
+ const { affiliates, hasNextPage } = await client.affiliates.list({
878
+ affiliateProgramId: 'program_123',
879
+ status: 'active', // 'pending' | 'active' | 'rejected' | 'suspended'
880
+ appId: 'app_123',
881
+ email: 'affiliate@example.com',
882
+ });
883
+
884
+ // Retrieve an affiliate
885
+ const { affiliate } = await client.affiliates.retrieve('affiliate_123');
886
+
887
+ // Update an affiliate
888
+ const { affiliate } = await client.affiliates.update('affiliate_123', {
216
889
  status: 'active',
890
+ commissionRate: 0.25, // 25%
217
891
  });
892
+ ```
893
+
894
+ ### Affiliate Programs
218
895
 
896
+ ```typescript
897
+ // List affiliate programs
219
898
  const { affiliatePrograms } = await client.affiliatePrograms.list();
220
- const { commissions } = await client.affiliateCommissions.list();
221
- const { payouts } = await client.affiliatePayouts.list();
222
- const { referrals } = await client.affiliateReferrals.list();
899
+
900
+ // Retrieve an affiliate program
901
+ const { affiliateProgram } = await client.affiliatePrograms.retrieve('program_123');
902
+
903
+ // Create an affiliate program
904
+ const { affiliateProgram } = await client.affiliatePrograms.create({
905
+ name: 'Partner Program',
906
+ description: 'Earn 20% commission on referrals',
907
+ commissionType: 'percentage', // 'percentage' | 'fixed'
908
+ commissionValue: 20,
909
+ commissionDurationMonths: 12,
910
+ cookieDurationDays: 30,
911
+ minimumPayoutAmount: 5000, // $50.00
912
+ payoutCurrency: 'USD',
913
+ active: true,
914
+ });
915
+
916
+ // Update an affiliate program
917
+ const { affiliateProgram } = await client.affiliatePrograms.update('program_123', {
918
+ commissionValue: 25,
919
+ });
920
+
921
+ // Delete an affiliate program
922
+ await client.affiliatePrograms.del('program_123');
223
923
  ```
224
924
 
225
- ### Other Resources
925
+ ### Affiliate Commissions
226
926
 
227
927
  ```typescript
228
- // Current user & organization
229
- const { user, organization } = await client.me.retrieve();
230
- const { organization } = await client.organization.retrieve();
928
+ // List commissions
929
+ const { commissions, hasNextPage } = await client.affiliateCommissions.list({
930
+ affiliateId: 'affiliate_123',
931
+ status: 'pending', // 'pending' | 'approved' | 'paid' | 'rejected'
932
+ });
231
933
 
232
- // Users
233
- const { users } = await client.users.list();
934
+ // Retrieve a commission
935
+ const { commission } = await client.affiliateCommissions.retrieve('commission_123');
936
+
937
+ // Update a commission
938
+ const { commission } = await client.affiliateCommissions.update('commission_123', {
939
+ status: 'approved',
940
+ });
941
+ ```
942
+
943
+ ### Affiliate Payouts
944
+
945
+ ```typescript
946
+ // List payouts
947
+ const { payouts, hasNextPage } = await client.affiliatePayouts.list({
948
+ affiliateId: 'affiliate_123',
949
+ status: 'completed', // 'pending' | 'processing' | 'completed' | 'failed'
950
+ });
951
+
952
+ // Retrieve a payout
953
+ const { payout } = await client.affiliatePayouts.retrieve('payout_123');
954
+
955
+ // Create a payout
956
+ const { payout } = await client.affiliatePayouts.create({
957
+ affiliateId: 'affiliate_123',
958
+ amount: 10000, // $100.00
959
+ currencyCode: 'USD',
960
+ });
961
+ ```
962
+
963
+ ### Affiliate Referrals
964
+
965
+ ```typescript
966
+ // List referrals
967
+ const { referrals, hasNextPage } = await client.affiliateReferrals.list({
968
+ affiliateId: 'affiliate_123',
969
+ status: 'converted', // 'pending' | 'converted' | 'expired'
970
+ });
971
+
972
+ // Retrieve a referral
973
+ const { referral } = await client.affiliateReferrals.retrieve('referral_123');
974
+ ```
975
+
976
+ ### Companies
977
+
978
+ ```typescript
979
+ // List companies
980
+ const { companies, hasNextPage } = await client.companies.list({
981
+ take: 25,
982
+ search: 'acme',
983
+ });
984
+
985
+ // Retrieve a company
986
+ const { company } = await client.companies.retrieve('company_123');
234
987
 
235
- // Companies
236
- const { companies } = await client.companies.list();
988
+ // Create a company
989
+ const { company } = await client.companies.create({
990
+ name: 'Acme Holdings',
991
+ domain: 'acme.com',
992
+ });
993
+
994
+ // Update a company
995
+ const { company } = await client.companies.update('company_123', {
996
+ name: 'Acme Holdings Inc',
997
+ });
237
998
 
238
- // Customer segments
999
+ // Delete a company
1000
+ await client.companies.del('company_123');
1001
+ ```
1002
+
1003
+ ### Customer Segments
1004
+
1005
+ ```typescript
1006
+ // List customer segments
239
1007
  const { customerSegments } = await client.customerSegments.list();
240
1008
 
241
- // Tasks
242
- const { tasks } = await client.tasks.list({ status: 'pending' });
1009
+ // Retrieve a segment
1010
+ const { customerSegment } = await client.customerSegments.retrieve('segment_123');
1011
+
1012
+ // Create a segment
1013
+ const { customerSegment } = await client.customerSegments.create({
1014
+ name: 'Enterprise Customers',
1015
+ filters: { lifetimeValue: { gte: 10000 } },
1016
+ });
1017
+
1018
+ // Update a segment
1019
+ const { customerSegment } = await client.customerSegments.update('segment_123', {
1020
+ name: 'Enterprise Customers (Updated)',
1021
+ });
1022
+
1023
+ // Delete a segment
1024
+ await client.customerSegments.del('segment_123');
1025
+ ```
1026
+
1027
+ ### Tasks
243
1028
 
244
- // Flows (automation)
1029
+ ```typescript
1030
+ // List tasks
1031
+ const { tasks, hasNextPage } = await client.tasks.list({
1032
+ status: 'pending',
1033
+ assignedToId: 'user_123',
1034
+ customerId: 'cust_123',
1035
+ });
1036
+
1037
+ // Retrieve a task
1038
+ const { task } = await client.tasks.retrieve('task_123');
1039
+
1040
+ // Create a task
1041
+ const { task } = await client.tasks.create({
1042
+ title: 'Follow up with customer',
1043
+ description: 'Discuss renewal options',
1044
+ dueAt: '2024-02-15T10:00:00Z',
1045
+ assignedToId: 'user_123',
1046
+ customerId: 'cust_123',
1047
+ });
1048
+
1049
+ // Update a task
1050
+ const { task } = await client.tasks.update('task_123', {
1051
+ status: 'completed',
1052
+ });
1053
+
1054
+ // Delete a task
1055
+ await client.tasks.del('task_123');
1056
+ ```
1057
+
1058
+ ### Flows (Automation)
1059
+
1060
+ ```typescript
1061
+ // List flows
245
1062
  const { flows } = await client.flows.list();
246
1063
 
247
- // Transactions & Charges
248
- const { transactions } = await client.transactions.list();
249
- const { charges } = await client.charges.list();
1064
+ // Retrieve a flow
1065
+ const { flow } = await client.flows.retrieve('flow_123');
1066
+
1067
+ // Create a flow
1068
+ const { flow } = await client.flows.create({
1069
+ name: 'Onboarding Flow',
1070
+ trigger: 'customer.created',
1071
+ actions: [
1072
+ { type: 'email', template: 'welcome' },
1073
+ ],
1074
+ });
250
1075
 
251
- // Documentation
1076
+ // Update a flow
1077
+ const { flow } = await client.flows.update('flow_123', {
1078
+ name: 'Updated Onboarding Flow',
1079
+ enabled: true,
1080
+ });
1081
+
1082
+ // Delete a flow
1083
+ await client.flows.del('flow_123');
1084
+ ```
1085
+
1086
+ ### Transactions & Charges
1087
+
1088
+ ```typescript
1089
+ // List transactions
1090
+ const { transactions, hasNextPage } = await client.transactions.list({
1091
+ customerId: 'cust_123',
1092
+ appId: 'app_123',
1093
+ });
1094
+
1095
+ // Retrieve a transaction
1096
+ const { transaction } = await client.transactions.retrieve('txn_123');
1097
+
1098
+ // List charges
1099
+ const { charges, hasNextPage } = await client.charges.list({
1100
+ customerId: 'cust_123',
1101
+ appId: 'app_123',
1102
+ });
1103
+
1104
+ // Retrieve a charge
1105
+ const { charge } = await client.charges.retrieve('charge_123');
1106
+ ```
1107
+
1108
+ ### Users
1109
+
1110
+ ```typescript
1111
+ // List users in the organization
1112
+ const { users } = await client.users.list();
1113
+
1114
+ // Retrieve a user
1115
+ const { user } = await client.users.retrieve('user_123');
1116
+ ```
1117
+
1118
+ ### Me & Organization
1119
+
1120
+ ```typescript
1121
+ // Get current user and organization
1122
+ const { user, organization } = await client.me.retrieve();
1123
+
1124
+ // Get organization details
1125
+ const { organization } = await client.organization.retrieve();
1126
+ ```
1127
+
1128
+ ### Documentation
1129
+
1130
+ ```typescript
1131
+ // List documentation collections
252
1132
  const { collections } = await client.docs.listCollections();
253
- const { pages } = await client.docs.listPages();
1133
+
1134
+ // Retrieve a collection
1135
+ const { collection } = await client.docs.retrieveCollection('collection_123');
1136
+
1137
+ // List documentation pages
1138
+ const { pages } = await client.docs.listPages({
1139
+ collectionId: 'collection_123',
1140
+ });
1141
+
1142
+ // Retrieve a page
1143
+ const { page } = await client.docs.retrievePage('page_123');
1144
+
1145
+ // Create a page
1146
+ const { page } = await client.docs.createPage({
1147
+ title: 'Getting Started',
1148
+ content: '# Getting Started\n\nWelcome to our docs...',
1149
+ collectionId: 'collection_123',
1150
+ });
1151
+
1152
+ // Update a page
1153
+ const { page } = await client.docs.updatePage('page_123', {
1154
+ content: 'Updated content',
1155
+ });
1156
+
1157
+ // Delete a page
1158
+ await client.docs.deletePage('page_123');
1159
+ ```
1160
+
1161
+ ### Entities
1162
+
1163
+ Generic entity management:
1164
+
1165
+ ```typescript
1166
+ // List entities
1167
+ const { entities } = await client.entities.list({
1168
+ type: 'custom_entity',
1169
+ });
1170
+
1171
+ // Retrieve an entity
1172
+ const { entity } = await client.entities.retrieve('entity_123');
1173
+
1174
+ // Create an entity
1175
+ const { entity } = await client.entities.create({
1176
+ type: 'custom_entity',
1177
+ data: { field1: 'value1' },
1178
+ });
1179
+
1180
+ // Update an entity
1181
+ const { entity } = await client.entities.update('entity_123', {
1182
+ data: { field1: 'updated_value' },
1183
+ });
1184
+
1185
+ // Delete an entity
1186
+ await client.entities.del('entity_123');
254
1187
  ```
255
1188
 
256
1189
  ## Pagination
@@ -261,10 +1194,13 @@ All list methods return pagination metadata:
261
1194
  const { customers, hasNextPage, hasPreviousPage, cursor, total } =
262
1195
  await client.customers.list({ take: 25 });
263
1196
 
264
- // Fetch next page
1197
+ // Cursor-based pagination (recommended)
265
1198
  if (hasNextPage) {
266
1199
  const nextPage = await client.customers.list({ take: 25, cursor });
267
1200
  }
1201
+
1202
+ // Offset-based pagination
1203
+ const page2 = await client.customers.list({ take: 25, page: 1 });
268
1204
  ```
269
1205
 
270
1206
  ## Error Handling
@@ -283,17 +1219,19 @@ try {
283
1219
  } catch (error) {
284
1220
  if (error instanceof MantleAuthenticationError) {
285
1221
  // Handle authentication error (401)
1222
+ console.log('Please re-authenticate');
286
1223
  } else if (error instanceof MantlePermissionError) {
287
1224
  // Handle permission error (403)
1225
+ console.log('Access denied');
288
1226
  } else if (error instanceof MantleValidationError) {
289
1227
  // Handle validation error (422)
290
- console.log(error.details);
1228
+ console.log('Validation failed:', error.details);
291
1229
  } else if (error instanceof MantleRateLimitError) {
292
1230
  // Handle rate limit (429)
293
- console.log(`Retry after: ${error.retryAfter}s`);
1231
+ console.log(`Rate limited. Retry after: ${error.retryAfter}s`);
294
1232
  } else if (error instanceof MantleAPIError) {
295
1233
  // Handle other API errors
296
- console.log(error.statusCode, error.message);
1234
+ console.log(`Error ${error.statusCode}: ${error.message}`);
297
1235
  }
298
1236
  }
299
1237
  ```
@@ -304,28 +1242,85 @@ All types are exported for use in your application:
304
1242
 
305
1243
  ```typescript
306
1244
  import type {
1245
+ // Client config
1246
+ MantleCoreClientConfig,
1247
+
1248
+ // Entities
307
1249
  Customer,
308
- CustomerCreateParams,
1250
+ Contact,
309
1251
  Deal,
310
1252
  Subscription,
1253
+ Ticket,
1254
+ TicketMessage,
1255
+ App,
1256
+ Plan,
1257
+ Feature,
1258
+ Affiliate,
1259
+ AffiliateProgram,
1260
+ AffiliateCommission,
1261
+ AffiliatePayout,
1262
+ AffiliateReferral,
1263
+
1264
+ // Params
1265
+ CustomerCreateParams,
1266
+ CustomerUpdateParams,
1267
+ CustomerListParams,
1268
+ DealCreateParams,
1269
+ DealCustomerInput,
1270
+ DealContactInput,
1271
+ TicketCreateParams,
1272
+ PlanCreateParams,
1273
+
1274
+ // Responses
1275
+ CustomerListResponse,
1276
+ DealListResponse,
311
1277
  MetricsResponse,
312
- // ... and many more
1278
+ PaginatedResponse,
1279
+
1280
+ // Enums/Types
1281
+ DateRangeType,
1282
+ MetricType,
1283
+ SocialProfileType,
1284
+
1285
+ // Middleware
1286
+ Middleware,
1287
+ MiddlewareContext,
1288
+ MiddlewareOptions,
313
1289
  } from '@heymantle/core-api-client';
314
1290
  ```
315
1291
 
316
1292
  ## Configuration Options
317
1293
 
318
1294
  ```typescript
1295
+ import { MantleCoreClient, type Middleware } from '@heymantle/core-api-client';
1296
+
319
1297
  const client = new MantleCoreClient({
320
1298
  // Required: one of apiKey or accessToken
321
1299
  apiKey: 'your-api-key',
1300
+ // OR
1301
+ accessToken: 'your-oauth-token',
322
1302
 
323
1303
  // Optional: custom base URL (defaults to https://api.heymantle.com/v1)
324
1304
  baseURL: 'https://api.heymantle.com/v1',
325
1305
 
326
1306
  // Optional: request timeout in ms (defaults to 30000)
327
1307
  timeout: 30000,
1308
+
1309
+ // Optional: middleware to register on instantiation
1310
+ middleware: [
1311
+ loggingMiddleware,
1312
+ [authRefreshMiddleware, { name: 'auth', priority: 1 }],
1313
+ ],
328
1314
  });
1315
+
1316
+ // Update authentication at runtime
1317
+ client.updateAuth({ accessToken: 'new-token' });
1318
+
1319
+ // Add middleware at runtime
1320
+ client.use(newMiddleware, { name: 'custom', priority: 50 });
1321
+
1322
+ // Remove middleware by name
1323
+ client.removeMiddleware('custom');
329
1324
  ```
330
1325
 
331
1326
  ## License
package/dist/index.d.mts CHANGED
@@ -339,7 +339,7 @@ interface CustomFieldUpdateParams extends Partial<Omit<CustomFieldCreateParams,
339
339
  /**
340
340
  * Valid social profile types
341
341
  */
342
- type SocialProfileType = 'linkedin' | 'x' | 'facebook' | 'instagram' | 'website';
342
+ type SocialProfileType = "linkedin" | "x" | "facebook" | "instagram" | "website";
343
343
  /**
344
344
  * Social profile for a contact
345
345
  */
@@ -391,7 +391,10 @@ interface ContactCreateParams {
391
391
  jobTitle?: string;
392
392
  notes?: string;
393
393
  tags?: string[];
394
- customers?: string[];
394
+ customers?: string[] | Array<{
395
+ id: string;
396
+ name?: string;
397
+ }>;
395
398
  socialProfiles?: SocialProfile[];
396
399
  }
397
400
  /**
package/dist/index.d.ts CHANGED
@@ -339,7 +339,7 @@ interface CustomFieldUpdateParams extends Partial<Omit<CustomFieldCreateParams,
339
339
  /**
340
340
  * Valid social profile types
341
341
  */
342
- type SocialProfileType = 'linkedin' | 'x' | 'facebook' | 'instagram' | 'website';
342
+ type SocialProfileType = "linkedin" | "x" | "facebook" | "instagram" | "website";
343
343
  /**
344
344
  * Social profile for a contact
345
345
  */
@@ -391,7 +391,10 @@ interface ContactCreateParams {
391
391
  jobTitle?: string;
392
392
  notes?: string;
393
393
  tags?: string[];
394
- customers?: string[];
394
+ customers?: string[] | Array<{
395
+ id: string;
396
+ name?: string;
397
+ }>;
395
398
  socialProfiles?: SocialProfile[];
396
399
  }
397
400
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heymantle/core-api-client",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "TypeScript SDK for the Mantle Core API",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",