@unboundcx/sdk 4.8.9 → 4.8.11

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.
Files changed (57) hide show
  1. package/base.js +71 -29
  2. package/index.js +6 -3
  3. package/package.json +1 -4
  4. package/services/ai/playbooks.js +22 -21
  5. package/services/ai/settings.js +4 -2
  6. package/services/ai/translate.js +3 -1
  7. package/services/ai/vocabulary.js +4 -3
  8. package/services/ai.js +21 -20
  9. package/services/chat.js +124 -48
  10. package/services/developerApis.js +174 -0
  11. package/services/directory.js +109 -12
  12. package/services/documents.js +11 -10
  13. package/services/engagementMetrics.js +2 -1
  14. package/services/enroll.js +16 -15
  15. package/services/externalOAuth.js +12 -11
  16. package/services/fax.js +4 -3
  17. package/services/generateId.js +3 -2
  18. package/services/googleCalendar.js +7 -6
  19. package/services/inbox.js +59 -11
  20. package/services/knowledgeBase.js +9 -8
  21. package/services/layouts.js +15 -14
  22. package/services/login.js +8 -7
  23. package/services/lookup.js +4 -3
  24. package/services/messaging/EmailAddressesService.js +5 -4
  25. package/services/messaging/EmailAnalyticsService.js +5 -4
  26. package/services/messaging/EmailDomainsService.js +8 -7
  27. package/services/messaging/EmailMailboxesService.js +59 -9
  28. package/services/messaging/EmailQueueService.js +2 -1
  29. package/services/messaging/EmailService.js +12 -11
  30. package/services/messaging/EmailSuppressionService.js +5 -4
  31. package/services/messaging/EmailTemplatesService.js +6 -5
  32. package/services/messaging/SmsService.js +3 -2
  33. package/services/messaging/SmsTemplatesService.js +6 -5
  34. package/services/messaging/TenDlcBrandsService.js +11 -10
  35. package/services/messaging/TenDlcCampaignManagementService.js +14 -13
  36. package/services/messaging/TenDlcCampaignsService.js +2 -1
  37. package/services/messaging/TollFreeCampaignsService.js +13 -12
  38. package/services/notes.js +7 -6
  39. package/services/objects.js +97 -36
  40. package/services/permissions.js +34 -33
  41. package/services/phoneNumbers.js +28 -27
  42. package/services/portals.js +8 -7
  43. package/services/recordTypes.js +12 -11
  44. package/services/search.js +2 -1
  45. package/services/sipEndpoints.js +8 -7
  46. package/services/storage.js +16 -15
  47. package/services/subscriptions.js +4 -3
  48. package/services/taskRouter/CCService.js +303 -0
  49. package/services/taskRouter/MetricsService.js +56 -1
  50. package/services/taskRouter/TaskRouterService.js +2 -0
  51. package/services/taskRouter/TaskService.js +13 -12
  52. package/services/taskRouter/WorkerService.js +9 -8
  53. package/services/triggers.js +9 -8
  54. package/services/verification.js +5 -4
  55. package/services/video.js +230 -45
  56. package/services/voice.js +40 -11
  57. package/services/workflows.js +22 -21
@@ -1,3 +1,4 @@
1
+ import { internalRequest } from '../base.js';
1
2
  /**
2
3
  * SearchService -- cross-entity fan-out search (WP6.1).
3
4
  * Backed by GET /search on app1-api: parallel per-store LIKE/fulltext
@@ -43,6 +44,6 @@ export class SearchService {
43
44
  query.entities = Array.isArray(entities) ? entities.join(',') : entities;
44
45
  }
45
46
 
46
- return await this.sdk._fetch('/search', 'GET', { query });
47
+ return await internalRequest(this.sdk, '/search', 'GET', { query });
47
48
  }
48
49
  }
@@ -1,3 +1,4 @@
1
+ import { internalRequest } from '../base.js';
1
2
  export class SipEndpointsService {
2
3
  constructor(sdk) {
3
4
  this.sdk = sdk;
@@ -45,7 +46,7 @@ export class SipEndpointsService {
45
46
  },
46
47
  };
47
48
 
48
- const result = await this.sdk._fetch('/sipEndpoints', 'POST', params);
49
+ const result = await internalRequest(this.sdk, '/sipEndpoints', 'POST', params);
49
50
  return result;
50
51
  }
51
52
 
@@ -54,7 +55,7 @@ export class SipEndpointsService {
54
55
  * @returns {Promise<Object>} WebRTC endpoint configuration
55
56
  */
56
57
  async getWebRtcDetails() {
57
- const result = await this.sdk._fetch('/sipEndpoints/webrtc', 'GET');
58
+ const result = await internalRequest(this.sdk, '/sipEndpoints/webrtc', 'GET');
58
59
  return result;
59
60
  }
60
61
 
@@ -82,7 +83,7 @@ export class SipEndpointsService {
82
83
  body: { ...options }, // Pass all options through
83
84
  };
84
85
 
85
- const result = await this.sdk._fetch(
86
+ const result = await internalRequest(this.sdk,
86
87
  `/sipEndpoints/${endpointId}`,
87
88
  'PUT',
88
89
  params,
@@ -103,7 +104,7 @@ export class SipEndpointsService {
103
104
  },
104
105
  );
105
106
 
106
- const result = await this.sdk._fetch(
107
+ const result = await internalRequest(this.sdk,
107
108
  `/sipEndpoints/${endpointId}`,
108
109
  'DELETE',
109
110
  );
@@ -123,7 +124,7 @@ export class SipEndpointsService {
123
124
  },
124
125
  );
125
126
 
126
- const result = await this.sdk._fetch(
127
+ const result = await internalRequest(this.sdk,
127
128
  `/sipEndpoints/${endpointId}/reboot`,
128
129
  'POST',
129
130
  );
@@ -143,7 +144,7 @@ export class SipEndpointsService {
143
144
  },
144
145
  );
145
146
 
146
- const result = await this.sdk._fetch(
147
+ const result = await internalRequest(this.sdk,
147
148
  `/sipEndpoints/${endpointId}/secret`,
148
149
  'POST',
149
150
  );
@@ -163,7 +164,7 @@ export class SipEndpointsService {
163
164
  },
164
165
  );
165
166
 
166
- const result = await this.sdk._fetch(
167
+ const result = await internalRequest(this.sdk,
167
168
  `/sipEndpoints/${endpointId}/secret/provisioning`,
168
169
  'POST',
169
170
  );
@@ -1,3 +1,4 @@
1
+ import { internalRequest } from '../base.js';
1
2
  export class StorageService {
2
3
  constructor(sdk) {
3
4
  this.sdk = sdk;
@@ -327,7 +328,7 @@ export class StorageService {
327
328
  headers,
328
329
  };
329
330
 
330
- return await this.sdk._fetch(endpoint, method, params, true);
331
+ return await internalRequest(this.sdk, endpoint, method, params, true);
331
332
  }
332
333
 
333
334
  // Upload with progress tracking using XMLHttpRequest
@@ -655,7 +656,7 @@ Response:
655
656
  headers,
656
657
  };
657
658
 
658
- return await this.sdk._fetch('/storage/upload', 'POST', params, true);
659
+ return await internalRequest(this.sdk, '/storage/upload', 'POST', params, true);
659
660
  }
660
661
 
661
662
  async getFile(storageId, path, download = false) {
@@ -678,7 +679,7 @@ Response:
678
679
  url += `/storage/${path.startsWith('/') ? path.slice(1) : path}`;
679
680
  }
680
681
 
681
- const result = await this.sdk._fetch(url, 'GET', params, true);
682
+ const result = await internalRequest(this.sdk, url, 'GET', params, true);
682
683
  return result;
683
684
  }
684
685
 
@@ -713,7 +714,7 @@ Response:
713
714
  },
714
715
  );
715
716
 
716
- const result = await this.sdk._fetch(
717
+ const result = await internalRequest(this.sdk,
717
718
  `/storage/${storageId}`,
718
719
  'DELETE',
719
720
  );
@@ -721,7 +722,7 @@ Response:
721
722
  }
722
723
 
723
724
  async getStorageClassifications() {
724
- const result = await this.sdk._fetch('/storage/classifications', 'GET');
725
+ const result = await internalRequest(this.sdk, '/storage/classifications', 'GET');
725
726
  return result;
726
727
  }
727
728
 
@@ -771,7 +772,7 @@ Response:
771
772
  },
772
773
  );
773
774
 
774
- const result = await this.sdk._fetch(
775
+ const result = await internalRequest(this.sdk,
775
776
  `/storage/file/${storageId}/info`,
776
777
  'GET',
777
778
  );
@@ -791,7 +792,7 @@ Response:
791
792
  body: { metadata },
792
793
  };
793
794
 
794
- const result = await this.sdk._fetch(
795
+ const result = await internalRequest(this.sdk,
795
796
  `/storage/file/${storageId}/metadata`,
796
797
  'PUT',
797
798
  params,
@@ -822,7 +823,7 @@ Response:
822
823
  query: options,
823
824
  };
824
825
 
825
- const result = await this.sdk._fetch('/storage/files', 'GET', params);
826
+ const result = await internalRequest(this.sdk, '/storage/files', 'GET', params);
826
827
  return result;
827
828
  }
828
829
 
@@ -845,7 +846,7 @@ Response:
845
846
  body: { expiresIn },
846
847
  };
847
848
 
848
- const result = await this.sdk._fetch(
849
+ const result = await internalRequest(this.sdk,
849
850
  `/storage/${fileId}/accessKey`,
850
851
  'POST',
851
852
  params,
@@ -882,7 +883,7 @@ Response:
882
883
  query: options,
883
884
  };
884
885
 
885
- const result = await this.sdk._fetch(
886
+ const result = await internalRequest(this.sdk,
886
887
  '/storage/configurations',
887
888
  'GET',
888
889
  params,
@@ -933,7 +934,7 @@ Response:
933
934
  body: config,
934
935
  };
935
936
 
936
- const result = await this.sdk._fetch(
937
+ const result = await internalRequest(this.sdk,
937
938
  '/storage/configurations',
938
939
  'POST',
939
940
  params,
@@ -962,7 +963,7 @@ Response:
962
963
  body: updates,
963
964
  };
964
965
 
965
- const result = await this.sdk._fetch(
966
+ const result = await internalRequest(this.sdk,
966
967
  `/storage/configurations/${id}`,
967
968
  'PUT',
968
969
  params,
@@ -984,7 +985,7 @@ Response:
984
985
  },
985
986
  );
986
987
 
987
- const result = await this.sdk._fetch(
988
+ const result = await internalRequest(this.sdk,
988
989
  `/storage/configurations/${id}`,
989
990
  'DELETE',
990
991
  );
@@ -1091,7 +1092,7 @@ Response:
1091
1092
 
1092
1093
  const params = { body };
1093
1094
 
1094
- return await this.sdk._fetch(`/storage/${storageId}/convert`, 'POST', params);
1095
+ return await internalRequest(this.sdk, `/storage/${storageId}/convert`, 'POST', params);
1095
1096
  }
1096
1097
 
1097
1098
  /**
@@ -1174,7 +1175,7 @@ Response:
1174
1175
  body: updateData,
1175
1176
  };
1176
1177
 
1177
- const result = await this.sdk._fetch(
1178
+ const result = await internalRequest(this.sdk,
1178
1179
  `/storage/${storageId}`,
1179
1180
  'PUT',
1180
1181
  options,
@@ -1,3 +1,4 @@
1
+ import { internalRequest } from '../base.js';
1
2
  export class SubscriptionsService {
2
3
  constructor(sdk) {
3
4
  this.sdk = sdk;
@@ -24,7 +25,7 @@ export class SocketSubscriptionsService {
24
25
  },
25
26
  };
26
27
 
27
- const result = await this.sdk._fetch(
28
+ const result = await internalRequest(this.sdk,
28
29
  '/subscriptions/socket/connection',
29
30
  'GET',
30
31
  params,
@@ -52,7 +53,7 @@ export class SocketSubscriptionsService {
52
53
  if (subscriptionParams?.id) {
53
54
  uri = `/subscriptions/socket/${subscriptionParams.id}`;
54
55
  }
55
- const result = await this.sdk._fetch(uri, 'POST', params);
56
+ const result = await internalRequest(this.sdk, uri, 'POST', params);
56
57
  return result;
57
58
  }
58
59
 
@@ -71,7 +72,7 @@ export class SocketSubscriptionsService {
71
72
  },
72
73
  };
73
74
 
74
- const result = await this.sdk._fetch(
75
+ const result = await internalRequest(this.sdk,
75
76
  `/subscriptions/socket/${id}`,
76
77
  'DELETE',
77
78
  params,
@@ -0,0 +1,303 @@
1
+ import { internalRequest } from '../../base.js';
2
+ export class CCService {
3
+ constructor(sdk) {
4
+ this.sdk = sdk;
5
+ }
6
+
7
+ /**
8
+ * Resolve the caller's Contact Center queue scope + role.
9
+ * Managers see every non-deleted queue; agents see only the queues they
10
+ * belong to (queueUsers).
11
+ *
12
+ * @returns {Promise<Object>} result
13
+ * @returns {boolean} result.isManager - Whether the caller has queue-manager scope
14
+ * @returns {string|null} result.workerId - The caller's own worker id, if any
15
+ * @returns {Array<Object>} result.queues - Accessible queues [{id, name, slaThreshold, slaTargetPct, timezone}]
16
+ *
17
+ * @example
18
+ * const scope = await sdk.taskRouter.cc.getScope();
19
+ * console.log(scope.isManager, scope.queues.length);
20
+ */
21
+ async getScope() {
22
+ const result = await internalRequest(this.sdk, '/taskRouter/cc/scope', 'GET', {});
23
+ return result;
24
+ }
25
+
26
+ /**
27
+ * Get a live Contact Center snapshot (KPIs, per-queue summaries, team roster
28
+ * with active tasks) scoped to a set of queues.
29
+ *
30
+ * @param {Object} [options] - Parameters
31
+ * @param {string[]} [options.queueIds] - Queue ids to scope to (must be a subset of the caller's accessible queues). Omit/empty for full scope.
32
+ * @returns {Promise<Object>} result
33
+ * @returns {Object} result.kpis - Aggregate KPIs (inQueueNow, longestWaitSec, myHandledToday, myAvgHandleSecToday, slaTodayPct, slaTargetPct)
34
+ * @returns {Array<Object>} result.queues - Per-queue summaries (id, name, waiting, longestWaitSec, agentsAvailable, agentsTotal, slaPct, slaThreshold, slaTargetPct, timezone, health)
35
+ * @returns {Array<Object>} result.team - Team roster with active tasks
36
+ *
37
+ * @example
38
+ * const snapshot = await sdk.taskRouter.cc.getSnapshot({ queueIds: ['q1', 'q2'] });
39
+ * console.log(snapshot.kpis.inQueueNow);
40
+ */
41
+ async getSnapshot(options = {}) {
42
+ const { queueIds } = options;
43
+
44
+ this.sdk.validateParams(
45
+ { queueIds },
46
+ {
47
+ queueIds: { type: 'array', required: false },
48
+ },
49
+ );
50
+
51
+ const params = {};
52
+ if (queueIds && queueIds.length) {
53
+ params.query = { queueIds: queueIds.join(',') };
54
+ }
55
+
56
+ const result = await internalRequest(this.sdk,
57
+ '/taskRouter/cc/snapshot',
58
+ 'GET',
59
+ params,
60
+ );
61
+ return result;
62
+ }
63
+
64
+ /**
65
+ * Get on-queue session history for a worker (self allowed; another
66
+ * worker's sessions require the queue-manager scope).
67
+ *
68
+ * @param {Object} [options] - Parameters
69
+ * @param {string} [options.workerId] - Worker id to fetch sessions for (defaults to the caller's own worker)
70
+ * @param {string} [options.from] - ISO-8601 range start
71
+ * @param {string} [options.to] - ISO-8601 range end
72
+ * @returns {Promise<Object>} result
73
+ * @returns {Array<Object>} result.sessions - [{id, startedAt, endedAt, onQueueSec, breakSec, doneCount}]
74
+ *
75
+ * @example
76
+ * const { sessions } = await sdk.taskRouter.cc.getSessions({ workerId: 'w1', from: '2026-08-12T00:00:00Z', to: '2026-08-19T00:00:00Z' });
77
+ */
78
+ async getSessions(options = {}) {
79
+ const { workerId, from, to } = options;
80
+
81
+ this.sdk.validateParams(
82
+ { workerId, from, to },
83
+ {
84
+ workerId: { type: 'string', required: false },
85
+ from: { type: 'string', required: false },
86
+ to: { type: 'string', required: false },
87
+ },
88
+ );
89
+
90
+ const query = {};
91
+ if (workerId) query.workerId = workerId;
92
+ if (from) query.from = from;
93
+ if (to) query.to = to;
94
+
95
+ const result = await internalRequest(this.sdk, '/taskRouter/cc/sessions', 'GET', {
96
+ query,
97
+ });
98
+ return result;
99
+ }
100
+
101
+ /**
102
+ * Get windowed composite agent rankings (top/struggling) per queue + an
103
+ * 'all' rollup, scored from sentiment/SLA/volume/acceptance. `struggling`
104
+ * arrays are only present when the caller has the queue-manager scope
105
+ * (see `strugglingIncluded` on the result).
106
+ *
107
+ * @param {Object} [options] - Parameters
108
+ * @param {string[]} [options.queueIds] - Queue ids to scope to (must be a subset of the caller's accessible queues). Omit/empty for full scope.
109
+ * @param {string} options.from - ISO-8601 window start
110
+ * @param {string} options.to - ISO-8601 window end
111
+ * @returns {Promise<Object>} result
112
+ * @returns {Object} result.queues - Per-queue rankings, keyed by queueId: `{ top: [{workerId,name,score}], struggling?: [...] }`
113
+ * @returns {Object} result.all - Same shape, aggregated across every scoped queue
114
+ * @returns {boolean} result.strugglingIncluded - Whether `struggling` arrays were included
115
+ *
116
+ * @example
117
+ * const { queues, all } = await sdk.taskRouter.cc.getRankings({
118
+ * queueIds: ['q1'],
119
+ * from: '2026-08-12T00:00:00Z',
120
+ * to: '2026-08-19T00:00:00Z',
121
+ * });
122
+ * console.log(all.top[0].name, all.top[0].score);
123
+ */
124
+ async getRankings(options = {}) {
125
+ const { queueIds, from, to } = options;
126
+
127
+ this.sdk.validateParams(
128
+ { queueIds, from, to },
129
+ {
130
+ queueIds: { type: 'array', required: false },
131
+ from: { type: 'string', required: true },
132
+ to: { type: 'string', required: true },
133
+ },
134
+ );
135
+
136
+ const query = { from, to };
137
+ if (queueIds && queueIds.length) {
138
+ query.queueIds = queueIds.join(',');
139
+ }
140
+
141
+ const result = await internalRequest(this.sdk, '/taskRouter/cc/rankings', 'GET', {
142
+ query,
143
+ });
144
+ return result;
145
+ }
146
+
147
+ /**
148
+ * Set a queue's composite ranking-weights override. Manager-only
149
+ * (`taskrouter:queue:manage`). Weights must be integers 0-100 that sum to
150
+ * exactly 100.
151
+ *
152
+ * @param {Object} options - Parameters
153
+ * @param {string} options.queueId - Queue id to update
154
+ * @param {Object} options.weights - `{sentiment, aht, volume, acceptance}` ints summing to 100
155
+ * @returns {Promise<Object>} result
156
+ * @returns {string} result.queueId
157
+ * @returns {Object} result.rankingWeights - The stored weights
158
+ *
159
+ * @example
160
+ * await sdk.taskRouter.cc.setQueueRankingWeights({
161
+ * queueId: 'q1',
162
+ * weights: { sentiment: 40, aht: 30, volume: 5, acceptance: 25 },
163
+ * });
164
+ */
165
+ async setQueueRankingWeights(options = {}) {
166
+ const { queueId, weights } = options;
167
+
168
+ this.sdk.validateParams(
169
+ { queueId, weights },
170
+ {
171
+ queueId: { type: 'string', required: true },
172
+ weights: { type: 'object', required: true },
173
+ },
174
+ );
175
+
176
+ const result = await internalRequest(this.sdk,
177
+ `/taskRouter/cc/queues/${queueId}/rankingWeights`,
178
+ 'PUT',
179
+ { body: weights },
180
+ );
181
+ return result;
182
+ }
183
+
184
+ /**
185
+ * Get one agent's Contact Center performance summary (KPIs, per-day
186
+ * charts, live tasks, on-queue sessions) over a date/date-range, with a
187
+ * comparison window for deltas. Self allowed; another worker's summary
188
+ * requires the queue-manager scope.
189
+ *
190
+ * @param {Object} options - Parameters
191
+ * @param {string} options.workerId - Worker id to summarize
192
+ * @param {string} options.from - ISO-8601 window start
193
+ * @param {string} options.to - ISO-8601 window end
194
+ * @param {string} [options.compareFrom] - ISO-8601 comparison window start (defaults to the preceding equal-length period)
195
+ * @param {string} [options.compareTo] - ISO-8601 comparison window end
196
+ * @returns {Promise<Object>} result
197
+ * @returns {Object} result.kpis - tasksHandled, offersAccepted, avgHandleSec, slaMet, avgSentiment, composite, onQueue
198
+ * @returns {Array<Object>} result.tasksPerDay - [{date, count}]
199
+ * @returns {Array<Object>} result.trend - [{date, sentiment, slaPct}]
200
+ * @returns {Array<Object>} result.liveNow - Current tasks (only when the window includes today)
201
+ * @returns {Array<Object>} result.sessions - On-queue session log
202
+ *
203
+ * @example
204
+ * const summary = await sdk.taskRouter.cc.getAgentSummary({
205
+ * workerId: 'w1',
206
+ * from: '2026-08-12T00:00:00Z',
207
+ * to: '2026-08-19T00:00:00Z',
208
+ * });
209
+ * console.log(summary.kpis.tasksHandled.value);
210
+ */
211
+ async getAgentSummary(options = {}) {
212
+ const { workerId, from, to, compareFrom, compareTo } = options;
213
+
214
+ this.sdk.validateParams(
215
+ { workerId, from, to, compareFrom, compareTo },
216
+ {
217
+ workerId: { type: 'string', required: true },
218
+ from: { type: 'string', required: true },
219
+ to: { type: 'string', required: true },
220
+ compareFrom: { type: 'string', required: false },
221
+ compareTo: { type: 'string', required: false },
222
+ },
223
+ );
224
+
225
+ const query = { from, to };
226
+ if (compareFrom) query.compareFrom = compareFrom;
227
+ if (compareTo) query.compareTo = compareTo;
228
+
229
+ const result = await internalRequest(this.sdk,
230
+ `/taskRouter/cc/agents/${workerId}/summary`,
231
+ 'GET',
232
+ { query },
233
+ );
234
+ return result;
235
+ }
236
+
237
+ /**
238
+ * Log a worker into or out of a queue. Manager-only
239
+ * (`taskrouter:queue:manage`). Mutates the worker's queue membership
240
+ * through task-router (audited).
241
+ *
242
+ * @param {Object} options - Parameters
243
+ * @param {string} options.workerId - Worker id to update
244
+ * @param {string} options.queueId - Queue id to log in/out of
245
+ * @param {'login'|'logout'} options.action - Whether to add or remove the queue
246
+ * @returns {Promise<Object>} result
247
+ * @returns {string} result.workerId
248
+ * @returns {string} result.status
249
+ * @returns {Array<string>} result.queues - The worker's updated queue list
250
+ *
251
+ * @example
252
+ * await sdk.taskRouter.cc.setWorkerQueue({ workerId: 'w1', queueId: 'q1', action: 'login' });
253
+ */
254
+ async setWorkerQueue(options = {}) {
255
+ const { workerId, queueId, action } = options;
256
+
257
+ this.sdk.validateParams(
258
+ { workerId, queueId, action },
259
+ {
260
+ workerId: { type: 'string', required: true },
261
+ queueId: { type: 'string', required: true },
262
+ action: { type: 'string', required: true },
263
+ },
264
+ );
265
+
266
+ const result = await internalRequest(this.sdk,
267
+ `/taskRouter/cc/workers/${workerId}/queues`,
268
+ 'PUT',
269
+ { body: { queueId, action } },
270
+ );
271
+ return result;
272
+ }
273
+
274
+ /**
275
+ * Force a worker offline (out of every queue), closing their on-queue
276
+ * session. Manager-only (`taskrouter:queue:manage`, audited).
277
+ *
278
+ * @param {Object} options - Parameters
279
+ * @param {string} options.workerId - Worker id to log out
280
+ * @returns {Promise<Object>} result
281
+ * @returns {string} result.workerId
282
+ * @returns {string} result.status
283
+ * @returns {Array<string>} result.queues
284
+ *
285
+ * @example
286
+ * await sdk.taskRouter.cc.forceLogoutWorker({ workerId: 'w1' });
287
+ */
288
+ async forceLogoutWorker(options = {}) {
289
+ const { workerId } = options;
290
+
291
+ this.sdk.validateParams(
292
+ { workerId },
293
+ { workerId: { type: 'string', required: true } },
294
+ );
295
+
296
+ const result = await internalRequest(this.sdk,
297
+ `/taskRouter/cc/workers/${workerId}/forceLogout`,
298
+ 'POST',
299
+ {},
300
+ );
301
+ return result;
302
+ }
303
+ }
@@ -1,3 +1,4 @@
1
+ import { internalRequest } from '../../base.js';
1
2
  export class MetricsService {
2
3
  constructor(sdk) {
3
4
  this.sdk = sdk;
@@ -101,11 +102,65 @@ export class MetricsService {
101
102
  requestParams.body.metricType = metricType;
102
103
  }
103
104
 
104
- const result = await this.sdk._fetch(
105
+ const result = await internalRequest(this.sdk,
105
106
  '/taskRouter/metrics/current',
106
107
  'GET',
107
108
  requestParams,
108
109
  );
109
110
  return result;
110
111
  }
112
+
113
+ /**
114
+ * Get windowed queue/company metrics with a compare-window delta, per
115
+ * queue + an 'all' rollup (avg wait, avg handle, service level, longest
116
+ * wait, live depth/workers, and a waiting-count sparkline).
117
+ *
118
+ * @param {Object} params - Parameters
119
+ * @param {string[]} [params.queueIds] - Queue ids to scope to. Omit/empty for all queues.
120
+ * @param {string} params.from - ISO-8601 window start
121
+ * @param {string} params.to - ISO-8601 window end
122
+ * @param {string} params.compareFrom - ISO-8601 compare-window start
123
+ * @param {string} params.compareTo - ISO-8601 compare-window end
124
+ * @returns {Promise<Object>} result
125
+ * @returns {Object} result.window - `{from, to}`
126
+ * @returns {Object} result.compare - `{from, to}`
127
+ * @returns {Object} result.all - Rollup across every scoped queue (avgWaitSec, avgHandleSec, serviceLevelPct, longestWaitSec, depth, workersAvailable, workersTotal, waitingSparkline, deltas)
128
+ * @returns {Object} result.queues - Same shape as `result.all`, keyed by queueId
129
+ *
130
+ * @example
131
+ * const { all, queues } = await sdk.taskRouter.metrics.getWindow({
132
+ * queueIds: ['q1', 'q2'],
133
+ * from: '2026-08-19T22:00:00Z',
134
+ * to: '2026-08-19T23:00:00Z',
135
+ * compareFrom: '2026-08-19T21:00:00Z',
136
+ * compareTo: '2026-08-19T22:00:00Z',
137
+ * });
138
+ * console.log(all.serviceLevelPct, all.deltas.serviceLevelPct);
139
+ */
140
+ async getWindow(params = {}) {
141
+ const { queueIds, from, to, compareFrom, compareTo } = params;
142
+
143
+ this.sdk.validateParams(
144
+ { queueIds, from, to, compareFrom, compareTo },
145
+ {
146
+ queueIds: { type: 'array', required: false },
147
+ from: { type: 'string', required: true },
148
+ to: { type: 'string', required: true },
149
+ compareFrom: { type: 'string', required: false },
150
+ compareTo: { type: 'string', required: false },
151
+ },
152
+ );
153
+
154
+ const query = { from, to };
155
+ if (queueIds && queueIds.length) query.queueIds = queueIds.join(',');
156
+ if (compareFrom) query.compareFrom = compareFrom;
157
+ if (compareTo) query.compareTo = compareTo;
158
+
159
+ const result = await internalRequest(this.sdk,
160
+ '/taskRouter/metrics/window',
161
+ 'GET',
162
+ { query },
163
+ );
164
+ return result;
165
+ }
111
166
  }
@@ -1,6 +1,7 @@
1
1
  import { WorkerService } from './WorkerService.js';
2
2
  import { TaskService } from './TaskService.js';
3
3
  import { MetricsService } from './MetricsService.js';
4
+ import { CCService } from './CCService.js';
4
5
 
5
6
  export class TaskRouterService {
6
7
  constructor(sdk) {
@@ -8,5 +9,6 @@ export class TaskRouterService {
8
9
  this.worker = new WorkerService(sdk);
9
10
  this.task = new TaskService(sdk);
10
11
  this.metrics = new MetricsService(sdk);
12
+ this.cc = new CCService(sdk);
11
13
  }
12
14
  }