@unboundcx/sdk 2.7.4 → 2.7.6

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/base.js CHANGED
@@ -324,12 +324,14 @@ export class BaseSDK {
324
324
  responseHeaders?.get?.('x-request-id') ||
325
325
  responseHeaders?.['x-request-id'] || '';
326
326
 
327
+ const contentType = responseHeaders?.get?.('content-type') || response.headers['content-type'];
328
+
327
329
  if (!response.ok) {
328
330
  let errorBody;
329
331
  if (response?.body) {
330
332
  errorBody = response.body;
331
333
  } else if (response?.headers?.['content-type']) {
332
- const contentType = response.headers['content-type'];
334
+
333
335
  try {
334
336
  if (typeof response?.json === 'function' || typeof response?.text === 'function') {
335
337
  if (contentType.includes('application/json')) {
@@ -372,10 +374,10 @@ export class BaseSDK {
372
374
  }
373
375
 
374
376
  let responseBody;
375
- if (response?.body) {
377
+ if (response?.body && !contentType) {
376
378
  responseBody = response.body;
377
- } else if (response?.headers?.['content-type']) {
378
- const contentType = response.headers['content-type'];
379
+ } else if (contentType) {
380
+
379
381
  try {
380
382
  if (transport === 'https') {
381
383
  if (contentType.includes('application/json')) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unboundcx/sdk",
3
- "version": "2.7.4",
3
+ "version": "2.7.6",
4
4
  "description": "Official JavaScript SDK for the Unbound API - A comprehensive toolkit for integrating with Unbound's communication, AI, and data management services",
5
5
  "main": "index.js",
6
6
  "type": "module",
@@ -212,6 +212,7 @@ export class EmailService {
212
212
  this.templates = new EmailTemplatesService(sdk);
213
213
  this.domains = new EmailDomainsService(sdk);
214
214
  this.addresses = new EmailAddressesService(sdk);
215
+ this.analytics = new EmailAnalyticsService(sdk);
215
216
  }
216
217
 
217
218
  /**
@@ -557,13 +558,90 @@ export class EmailDomainsService {
557
558
 
558
559
  /**
559
560
  * List all verified domains
560
- * @returns {Promise<Array>} List of verified domains with status
561
+ * @returns {Promise<Array>} List of verified domains with status, regions, and portal information
562
+ * @example
563
+ * // Returns array of domain objects:
564
+ * // {
565
+ * // id: 'domain-id',
566
+ * // domain: 'mydomain.com',
567
+ * // primaryRegion: 'us-east-1',
568
+ * // secondaryRegion: 'us-west-2',
569
+ * // primaryRegionStatus: 'active',
570
+ * // secondaryRegionStatus: 'active',
571
+ * // portalId: 'portal-id',
572
+ * // portalName: 'My Portal',
573
+ * // recordTypeId: 'record-type-id',
574
+ * // isDeleted: false,
575
+ * // createdAt: '2023-...'
576
+ * // }
561
577
  */
562
578
  async list() {
563
579
  const result = await this.sdk._fetch('/messaging/email/validate/domain', 'GET');
564
580
  return result;
565
581
  }
566
582
 
583
+ /**
584
+ * Get domain details by ID including DNS configuration
585
+ * @param {string} domainId - Domain ID (required)
586
+ * @returns {Promise<Object>} Domain details with DNS records to configure
587
+ * @example
588
+ * // Returns domain object with DNS records:
589
+ * // {
590
+ * // id: 'domain-id',
591
+ * // domain: 'mydomain.com',
592
+ * // primaryRegion: 'us-east-1',
593
+ * // secondaryRegion: 'us-west-2',
594
+ * // primaryRegionStatus: 'active',
595
+ * // secondaryRegionStatus: 'active',
596
+ * // mailFrom: 'mail.mydomain.com',
597
+ * // portalId: 'portal-id',
598
+ * // portalName: 'My Portal',
599
+ * // brandId: 'brand-id',
600
+ * // recordTypeId: 'record-type-id',
601
+ * // createdAt: '2023-...',
602
+ * // dns: [
603
+ * // {
604
+ * // type: 'CNAME',
605
+ * // name: 'domainid._domainkey.mydomain.com',
606
+ * // value: 'domainid.dkim.example.com',
607
+ * // description: 'DKIM signature verification'
608
+ * // },
609
+ * // {
610
+ * // type: 'CNAME',
611
+ * // name: 'mail.mydomain.com',
612
+ * // value: 'mail.ses.amazonaws.com',
613
+ * // description: 'MAIL FROM domain routing'
614
+ * // },
615
+ * // {
616
+ * // type: 'TXT',
617
+ * // name: 'mydomain.com',
618
+ * // value: '"v=spf1 include:mail.mydomain.com ~all"',
619
+ * // description: 'SPF record for email authentication'
620
+ * // },
621
+ * // {
622
+ * // type: 'TXT',
623
+ * // name: '_dmarc.mydomain.com',
624
+ * // value: '"v=DMARC1; p=quarantine; rua=mailto:dmarc@...',
625
+ * // description: 'DMARC policy for email authentication and reporting'
626
+ * // }
627
+ * // ]
628
+ * // }
629
+ */
630
+ async get(domainId) {
631
+ this.sdk.validateParams(
632
+ { domainId },
633
+ {
634
+ domainId: { type: 'string', required: true },
635
+ },
636
+ );
637
+
638
+ const result = await this.sdk._fetch(
639
+ `/messaging/email/validate/domain/${domainId}`,
640
+ 'GET',
641
+ );
642
+ return result;
643
+ }
644
+
567
645
  /**
568
646
  * Validate DNS records for domain
569
647
  * @param {string} domain - Domain name (required)
@@ -1831,3 +1909,78 @@ export class TenDlcCampaignManagementService {
1831
1909
  return result;
1832
1910
  }
1833
1911
  }
1912
+
1913
+ export class EmailAnalyticsService {
1914
+ constructor(sdk) {
1915
+ this.sdk = sdk;
1916
+ }
1917
+
1918
+ /**
1919
+ * Get email queue time series analytics
1920
+ * @param {Object} [params] - Analytics parameters
1921
+ * @param {string} [params.period='24h'] - Time period: '1h', '6h', '24h', '7d', '30d'
1922
+ * @param {string} [params.granularity='hour'] - Data granularity: 'minute', 'hour', 'day'
1923
+ * @returns {Promise<Object>} Time series data with summary statistics
1924
+ * @example
1925
+ * // Get hourly analytics for last 24 hours
1926
+ * const analytics = await sdk.messaging.email.analytics.timeSeries({ period: '24h', granularity: 'hour' });
1927
+ * // Returns: { period, granularity, data: [{ timestamp, sent, delivered, failed, queued }], summary }
1928
+ */
1929
+ async timeSeries({ period, granularity } = {}) {
1930
+ const options = { query: {} };
1931
+ if (period) options.query.period = period;
1932
+ if (granularity) options.query.granularity = granularity;
1933
+
1934
+ const result = await this.sdk._fetch('/messaging/email/analytics/timeseries', 'GET', options);
1935
+ return result;
1936
+ }
1937
+
1938
+ /**
1939
+ * Get email queue summary statistics
1940
+ * @param {Object} [params] - Summary parameters
1941
+ * @param {string} [params.period='24h'] - Time period: '1h', '6h', '24h', '7d', '30d'
1942
+ * @returns {Promise<Object>} Summary statistics
1943
+ * @example
1944
+ * // Get summary stats for last 24 hours
1945
+ * const summary = await sdk.messaging.email.analytics.summary({ period: '24h' });
1946
+ * // Returns: { totalSent, deliveryRate, errorRate, avgEmailsPerMinute, avgProcessingSeconds }
1947
+ */
1948
+ async summary({ period } = {}) {
1949
+ const options = { query: {} };
1950
+ if (period) options.query.period = period;
1951
+
1952
+ const result = await this.sdk._fetch('/messaging/email/analytics/summary', 'GET', options);
1953
+ return result;
1954
+ }
1955
+
1956
+ /**
1957
+ * Get real-time email queue metrics
1958
+ * @returns {Promise<Object>} Real-time queue statistics
1959
+ * @example
1960
+ * // Get current queue status
1961
+ * const realtime = await sdk.messaging.email.analytics.realtime();
1962
+ * // Returns: { queueDepth, currentSendRatePerMinute, last5Minutes: { sent, delivered, failed } }
1963
+ */
1964
+ async realtime() {
1965
+ const result = await this.sdk._fetch('/messaging/email/analytics/realtime', 'GET');
1966
+ return result;
1967
+ }
1968
+
1969
+ /**
1970
+ * Get email error analysis by domain
1971
+ * @param {Object} [params] - Error analysis parameters
1972
+ * @param {string} [params.period='7d'] - Time period: '24h', '7d', '30d'
1973
+ * @returns {Promise<Object>} Error analysis with domain breakdown
1974
+ * @example
1975
+ * // Get error analysis for last 7 days
1976
+ * const errors = await sdk.messaging.email.analytics.errors({ period: '7d' });
1977
+ * // Returns: { overallErrorRate, topErrorDomains: [{ domain, errorRate, totalErrors }] }
1978
+ */
1979
+ async errors({ period } = {}) {
1980
+ const options = { query: {} };
1981
+ if (period) options.query.period = period;
1982
+
1983
+ const result = await this.sdk._fetch('/messaging/email/analytics/errors', 'GET', options);
1984
+ return result;
1985
+ }
1986
+ }