@unboundcx/sdk 4.13.95 → 4.13.97

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unboundcx/sdk",
3
- "version": "4.13.95",
3
+ "version": "4.13.97",
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",
@@ -80,9 +80,9 @@ export class AssistService {
80
80
  * @example
81
81
  * const { suggestions } = await sdk.ai.assist.listSuggestions({ queueId: 'queue_123', limit: 50 });
82
82
  */
83
- async listSuggestions({ queueId, limit } = {}) {
83
+ async listSuggestions({ queueId, limit, actorKind } = {}) {
84
84
  const result = await internalRequest(this.sdk, '/ai/assist/suggestions', 'GET', {
85
- query: { queueId, limit },
85
+ query: { queueId, limit, actorKind },
86
86
  });
87
87
  return result;
88
88
  }
@@ -97,9 +97,9 @@ export class AssistService {
97
97
  * @example
98
98
  * const stats = await sdk.ai.assist.suggestionStats({ queueId: 'queue_123' });
99
99
  */
100
- async suggestionStats({ queueId } = {}) {
100
+ async suggestionStats({ queueId, actorKind } = {}) {
101
101
  const result = await internalRequest(this.sdk, '/ai/assist/suggestions/stats', 'GET', {
102
- query: { queueId },
102
+ query: { queueId, actorKind },
103
103
  });
104
104
  return result;
105
105
  }
@@ -0,0 +1,18 @@
1
+ import { internalRequest } from '../../base.js';
2
+
3
+ /**
4
+ * Platform model catalog — product names only (no vendor provider/model).
5
+ */
6
+ export class ModelsService {
7
+ constructor(sdk) {
8
+ this.sdk = sdk;
9
+ }
10
+
11
+ /**
12
+ * List platform models available to this account.
13
+ * @returns {Promise<Object>} { models, features, recommended }
14
+ */
15
+ async list() {
16
+ return internalRequest(this.sdk, '/ai/models', 'GET');
17
+ }
18
+ }
package/services/ai.js CHANGED
@@ -4,6 +4,7 @@ import { BattleCardsService } from './ai/battleCards.js';
4
4
  import { AssistService } from './ai/assist.js';
5
5
  import { VocabularyService } from './ai/vocabulary.js';
6
6
  import { EmailService } from './ai/email.js';
7
+ import { ModelsService } from './ai/models.js';
7
8
  import { translate as translateItems } from './ai/translate.js';
8
9
  import {
9
10
  getSettings as getAiSettings,
@@ -22,6 +23,7 @@ export class AIService {
22
23
  this.assist = new AssistService(sdk);
23
24
  this.vocabulary = new VocabularyService(sdk);
24
25
  this.email = new EmailService(sdk);
26
+ this.models = new ModelsService(sdk);
25
27
  }
26
28
 
27
29
  /**
@@ -964,14 +966,16 @@ export class SpeechToTextService {
964
966
  * @param {Object} message - Message data
965
967
  * @param {string} message.text - Transcribed text
966
968
  * @param {Object} [message.transcriptionJson] - Full transcription metadata
969
+ * @param {string} [message.transcriptionJson.source] - 'tts' for synthetic bot ingest
967
970
  * @param {number} [message.duration] - Duration of this segment in seconds
968
- * @param {number} [message.confidence] - Confidence score (0-1)
971
+ * @param {number} [message.confidence] - Confidence score (0-1). Omit for TTS.
969
972
  * @param {string} [message.languageCode] - Language code for this segment
970
973
  * @param {string} [message.userId] - User associated with this message
971
974
  * @param {string} [message.role] - Speaker role
972
975
  * @param {string} [message.sipCallId] - SIP call identifier
973
976
  * @param {string} [message.side] - Stream side ('send' or 'recv')
974
977
  * @param {string} [message.bridgeId] - bridge id
978
+ * @param {string} [message.taskId] - Task id (stamped on the transcription session)
975
979
  * @param {Object} [message.sentiment] - Sentiment analysis data
976
980
  * @param {number} [message.sentiment.score] - Overall sentiment score (-100 to +100)
977
981
  * @param {number} [message.sentiment.previousScore] - Previous sentiment score (-100 to +100)
@@ -999,13 +1003,14 @@ export class SpeechToTextService {
999
1003
  sipCallId,
1000
1004
  side,
1001
1005
  bridgeId,
1006
+ taskId,
1002
1007
  sentiment,
1003
1008
  videoRoomId,
1004
1009
  videoParticipantId,
1005
1010
  },
1006
1011
  ) {
1007
1012
  this.sdk.validateParams(
1008
- { messageId, sessionId, text, bridgeId },
1013
+ { messageId, sessionId, text, bridgeId, taskId },
1009
1014
  {
1010
1015
  sessionId: { type: 'string', required: true },
1011
1016
  messageId: { type: 'string', required: false },
@@ -1020,6 +1025,7 @@ export class SpeechToTextService {
1020
1025
  sipCallId: { type: 'string', required: false },
1021
1026
  side: { type: 'string', required: false },
1022
1027
  bridgeId: { type: 'string', required: false },
1028
+ taskId: { type: 'string', required: false },
1023
1029
  sentiment: { type: 'object', required: false },
1024
1030
  videoRoomId: { type: 'string', required: false },
1025
1031
  videoParticipantId: { type: 'string', required: false },
@@ -1040,6 +1046,7 @@ export class SpeechToTextService {
1040
1046
  sipCallId,
1041
1047
  side,
1042
1048
  bridgeId,
1049
+ taskId,
1043
1050
  sentiment,
1044
1051
  videoRoomId,
1045
1052
  videoParticipantId,
@@ -19,19 +19,19 @@ export class ReportingAgentsService {
19
19
 
20
20
  /**
21
21
  * Agent summary rows (§6 metrics), grouped by agent, queue, or team.
22
- * @param {Object} params - { from, to, userIds, queueIds, teamIds, groupBy }
22
+ * @param {Object} params - { from, to, userIds, queueIds, teamIds, groupBy, agentKind }
23
23
  * @returns {Promise<Object>} { columns, rows, definitions, meta }
24
24
  * @example
25
25
  * await sdk.reporting.agents.summary({ from, to, groupBy: 'team' });
26
26
  */
27
- async summary({ from, to, userIds, queueIds, teamIds, groupBy } = {}) {
27
+ async summary({ from, to, userIds, queueIds, teamIds, groupBy, agentKind } = {}) {
28
28
  this.sdk.validateParams(
29
29
  { from, to },
30
30
  { from: { type: 'string', required: true }, to: { type: 'string', required: true } },
31
31
  );
32
32
  return internalRequest(
33
33
  this.sdk,
34
- `/reporting/agents/summary${queryString({ from, to, userIds, queueIds, teamIds, groupBy })}`,
34
+ `/reporting/agents/summary${queryString({ from, to, userIds, queueIds, teamIds, groupBy, agentKind })}`,
35
35
  'GET',
36
36
  );
37
37
  }
@@ -90,19 +90,19 @@ export class ReportingAgentsService {
90
90
  /**
91
91
  * Per-agent per-local-day timesheet rows (net paid hours), plus one
92
92
  * additive-sum row per agent (`agents`) for grouped totals.
93
- * @param {Object} params - { from, to, userIds, teamIds }
93
+ * @param {Object} params - { from, to, userIds, teamIds, agentKind }
94
94
  * @returns {Promise<Object>} { columns, rows, agents }
95
95
  * @example
96
96
  * await sdk.reporting.agents.timesheet({ from, to, userIds: ['u1'] });
97
97
  */
98
- async timesheet({ from, to, userIds, teamIds } = {}) {
98
+ async timesheet({ from, to, userIds, teamIds, agentKind } = {}) {
99
99
  this.sdk.validateParams(
100
100
  { from, to },
101
101
  { from: { type: 'string', required: true }, to: { type: 'string', required: true } },
102
102
  );
103
103
  return internalRequest(
104
104
  this.sdk,
105
- `/reporting/agents/timesheet${queryString({ from, to, userIds, teamIds })}`,
105
+ `/reporting/agents/timesheet${queryString({ from, to, userIds, teamIds, agentKind })}`,
106
106
  'GET',
107
107
  );
108
108
  }
@@ -111,7 +111,7 @@ export class ReportingAgentsService {
111
111
  * CSV export of any of the four views above. For view: 'timesheet', pass
112
112
  * `totals: true` to get one additive-sum row per agent instead of the
113
113
  * flat per-agent-per-day rows.
114
- * @param {Object} params - { view: 'summary'|'states'|'interactions'|'timesheet', from, to, userId, userIds, queueIds, teamIds, groupBy, totals }
114
+ * @param {Object} params - { view: 'summary'|'states'|'interactions'|'timesheet', from, to, userId, userIds, queueIds, teamIds, groupBy, agentKind, totals }
115
115
  * @returns {Promise<Object>} raw CSV response (transport-dependent)
116
116
  * @example
117
117
  * await sdk.reporting.agents.export({ view: 'timesheet', from, to });
@@ -126,6 +126,7 @@ export class ReportingAgentsService {
126
126
  queueIds,
127
127
  teamIds,
128
128
  groupBy,
129
+ agentKind,
129
130
  totals,
130
131
  } = {}) {
131
132
  this.sdk.validateParams(
@@ -141,6 +142,7 @@ export class ReportingAgentsService {
141
142
  queueIds,
142
143
  teamIds,
143
144
  groupBy,
145
+ agentKind,
144
146
  totals: totals ? '1' : undefined,
145
147
  format: 'csv',
146
148
  });
@@ -0,0 +1,247 @@
1
+ import { internalRequest } from '../../base.js';
2
+
3
+ /**
4
+ * CC worker bots — Setup → Bots (K21). Not Graham /chat/bots.
5
+ */
6
+ export class CcBotsService {
7
+ constructor(sdk) {
8
+ this.sdk = sdk;
9
+ }
10
+
11
+ /**
12
+ * Platform defaults for When to get help + model pickers.
13
+ * @returns {Promise<Object>}
14
+ */
15
+ async defaults() {
16
+ return internalRequest(this.sdk, '/taskRouter/ccBots/defaults', 'GET');
17
+ }
18
+
19
+ /**
20
+ * List CC worker bots for the account.
21
+ * @returns {Promise<Object>} { results }
22
+ */
23
+ async list() {
24
+ return internalRequest(this.sdk, '/taskRouter/ccBots', 'GET');
25
+ }
26
+
27
+ /**
28
+ * Create a named CC worker bot (user + worker, capacity 1).
29
+ * @param {Object} params
30
+ * @param {string} params.name
31
+ * @param {string} params.slug
32
+ * @param {string} [params.soulMd]
33
+ * @param {string} [params.modelId] platform catalog id
34
+ * @param {string} [params.provider]
35
+ * @param {string} [params.model]
36
+ * @param {string} [params.queueId]
37
+ * @param {string} [params.mailboxId]
38
+ * @returns {Promise<Object>}
39
+ */
40
+ async create({
41
+ name,
42
+ slug,
43
+ soulMd,
44
+ modelId,
45
+ provider,
46
+ model,
47
+ queueId,
48
+ mailboxId,
49
+ } = {}) {
50
+ this.sdk.validateParams(
51
+ { name, slug },
52
+ {
53
+ name: { type: 'string', required: true },
54
+ slug: { type: 'string', required: true },
55
+ },
56
+ );
57
+ const body = { name, slug };
58
+ if (soulMd !== undefined) body.soulMd = soulMd;
59
+ if (modelId !== undefined) body.modelId = modelId;
60
+ if (provider !== undefined) body.provider = provider;
61
+ if (model !== undefined) body.model = model;
62
+ if (queueId !== undefined) body.queueId = queueId;
63
+ if (mailboxId !== undefined) body.mailboxId = mailboxId;
64
+ return internalRequest(this.sdk, '/taskRouter/ccBots', 'POST', { body });
65
+ }
66
+
67
+ /**
68
+ * Get one CC worker bot.
69
+ * @param {string} id
70
+ * @returns {Promise<Object>}
71
+ */
72
+ async get(id) {
73
+ this.sdk.validateParams({ id }, { id: { type: 'string', required: true } });
74
+ return internalRequest(this.sdk, `/taskRouter/ccBots/${id}`, 'GET');
75
+ }
76
+
77
+ /**
78
+ * Patch name / soul / model / pause kill-switch.
79
+ * @param {string} id
80
+ * @param {Object} [params]
81
+ * @returns {Promise<Object>}
82
+ */
83
+ async update(id, params = {}) {
84
+ this.sdk.validateParams({ id }, { id: { type: 'string', required: true } });
85
+ const body = {};
86
+ for (const key of [
87
+ 'name',
88
+ 'soulMd',
89
+ 'additionalDetails',
90
+ 'provider',
91
+ 'model',
92
+ 'modelId',
93
+ 'mediaProvider',
94
+ 'mediaModel',
95
+ 'voiceId',
96
+ 'profilePhoto',
97
+ 'paused',
98
+ 'acceptChannels',
99
+ 'useChannels',
100
+ 'groupId',
101
+ 'groupOverrides',
102
+ 'inherit',
103
+ ]) {
104
+ if (key in params) body[key] = params[key];
105
+ }
106
+ return internalRequest(this.sdk, `/taskRouter/ccBots/${id}`, 'PATCH', {
107
+ body,
108
+ });
109
+ }
110
+
111
+ /**
112
+ * Clone a CC worker bot (new user + worker, copied config).
113
+ * @param {string} id
114
+ * @param {Object} [params]
115
+ * @param {string} [params.name]
116
+ * @returns {Promise<Object>}
117
+ */
118
+ async clone(id, { name } = {}) {
119
+ this.sdk.validateParams({ id }, { id: { type: 'string', required: true } });
120
+ const body = {};
121
+ if (name !== undefined) body.name = name;
122
+ return internalRequest(this.sdk, `/taskRouter/ccBots/${id}/clone`, 'POST', {
123
+ body,
124
+ });
125
+ }
126
+
127
+ /**
128
+ * Enable or disable many CC bots.
129
+ * @param {Object} params
130
+ * @param {string[]} params.ids
131
+ * @param {boolean} params.paused
132
+ * @returns {Promise<Object>}
133
+ */
134
+ async bulkPaused({ ids, paused } = {}) {
135
+ this.sdk.validateParams(
136
+ { ids, paused },
137
+ {
138
+ ids: { type: 'object', required: true },
139
+ paused: { type: 'boolean', required: true },
140
+ },
141
+ );
142
+ return internalRequest(this.sdk, '/taskRouter/ccBots/bulkPaused', 'POST', {
143
+ body: { ids, paused },
144
+ });
145
+ }
146
+
147
+ /**
148
+ * List bot groups.
149
+ * @returns {Promise<Object>}
150
+ */
151
+ async listGroups() {
152
+ return internalRequest(this.sdk, '/taskRouter/ccBotGroups', 'GET');
153
+ }
154
+
155
+ /**
156
+ * Create a bot group.
157
+ * @param {Object} params
158
+ * @returns {Promise<Object>}
159
+ */
160
+ async createGroup(params = {}) {
161
+ this.sdk.validateParams(
162
+ { name: params.name },
163
+ { name: { type: 'string', required: true } },
164
+ );
165
+ return internalRequest(this.sdk, '/taskRouter/ccBotGroups', 'POST', {
166
+ body: params,
167
+ });
168
+ }
169
+
170
+ /**
171
+ * Get one bot group.
172
+ * @param {string} id
173
+ * @returns {Promise<Object>}
174
+ */
175
+ async getGroup(id) {
176
+ this.sdk.validateParams({ id }, { id: { type: 'string', required: true } });
177
+ return internalRequest(this.sdk, `/taskRouter/ccBotGroups/${id}`, 'GET');
178
+ }
179
+
180
+ /**
181
+ * Patch a bot group (propagates inherited fields to member bots).
182
+ * @param {string} id
183
+ * @param {Object} [params]
184
+ * @returns {Promise<Object>}
185
+ */
186
+ async updateGroup(id, params = {}) {
187
+ this.sdk.validateParams({ id }, { id: { type: 'string', required: true } });
188
+ const body = {};
189
+ for (const key of [
190
+ 'name',
191
+ 'soulMd',
192
+ 'provider',
193
+ 'model',
194
+ 'modelId',
195
+ 'mediaProvider',
196
+ 'mediaModel',
197
+ 'voiceId',
198
+ 'paused',
199
+ 'acceptChannels',
200
+ 'useChannels',
201
+ 'queueIds',
202
+ 'skillIds',
203
+ ]) {
204
+ if (key in params) body[key] = params[key];
205
+ }
206
+ return internalRequest(this.sdk, `/taskRouter/ccBotGroups/${id}`, 'PATCH', {
207
+ body,
208
+ });
209
+ }
210
+
211
+ /**
212
+ * Soft-delete a bot group and detach members.
213
+ * @param {string} id
214
+ * @returns {Promise<Object>}
215
+ */
216
+ async deleteGroup(id) {
217
+ this.sdk.validateParams({ id }, { id: { type: 'string', required: true } });
218
+ return internalRequest(
219
+ this.sdk,
220
+ `/taskRouter/ccBotGroups/${id}`,
221
+ 'DELETE',
222
+ );
223
+ }
224
+
225
+ /**
226
+ * Login a CC bot into a queue (queueUsers + worker addQueues).
227
+ * @param {string} id
228
+ * @param {Object} params
229
+ * @param {string} params.queueId
230
+ * @returns {Promise<Object>}
231
+ */
232
+ async addToQueue(id, { queueId } = {}) {
233
+ this.sdk.validateParams(
234
+ { id, queueId },
235
+ {
236
+ id: { type: 'string', required: true },
237
+ queueId: { type: 'string', required: true },
238
+ },
239
+ );
240
+ return internalRequest(
241
+ this.sdk,
242
+ `/taskRouter/ccBots/${id}/queues`,
243
+ 'POST',
244
+ { body: { queueId } },
245
+ );
246
+ }
247
+ }
@@ -4,6 +4,7 @@ import { MetricsService } from './MetricsService.js';
4
4
  import { CCService } from './CCService.js';
5
5
  import { OfferService } from './OfferService.js';
6
6
  import { ParticipantService } from './ParticipantService.js';
7
+ import { CcBotsService } from './CcBotsService.js';
7
8
 
8
9
  export class TaskRouterService {
9
10
  constructor(sdk) {
@@ -14,5 +15,6 @@ export class TaskRouterService {
14
15
  this.cc = new CCService(sdk);
15
16
  this.offer = new OfferService(sdk);
16
17
  this.participants = new ParticipantService(sdk);
18
+ this.ccBots = new CcBotsService(sdk);
17
19
  }
18
20
  }
@@ -409,6 +409,64 @@ export class TaskService {
409
409
  return result;
410
410
  }
411
411
 
412
+ /**
413
+ * Unassign a task back to pending (worker unlinked). Used by CC bot
414
+ * drain for short-lived connected tasks — not park.
415
+ *
416
+ * @param {Object} options
417
+ * @param {string} options.taskId
418
+ * @returns {Promise<Object>}
419
+ */
420
+ async unassign(options = {}) {
421
+ const { taskId, userId } = options;
422
+
423
+ this.sdk.validateParams(
424
+ { taskId, userId },
425
+ {
426
+ taskId: { type: 'string', required: true },
427
+ userId: { type: 'string', required: false },
428
+ },
429
+ );
430
+
431
+ const params = { body: { taskId } };
432
+ if (userId) params.body.userId = userId;
433
+
434
+ return internalRequest(
435
+ this.sdk,
436
+ '/taskRouter/tasks/unassign',
437
+ 'PUT',
438
+ params,
439
+ );
440
+ }
441
+
442
+ /**
443
+ * Staff-only internal note on a task (webchat/SMS/voice feed, or
444
+ * timeline). Never sent to the customer.
445
+ *
446
+ * @param {Object} options
447
+ * @param {string} options.taskId
448
+ * @param {string} options.message
449
+ * @returns {Promise<Object>}
450
+ */
451
+ async note(options = {}) {
452
+ const { taskId, message } = options;
453
+
454
+ this.sdk.validateParams(
455
+ { taskId, message },
456
+ {
457
+ taskId: { type: 'string', required: true },
458
+ message: { type: 'string', required: true },
459
+ },
460
+ );
461
+
462
+ return internalRequest(
463
+ this.sdk,
464
+ `/taskRouter/tasks/${taskId}/notes`,
465
+ 'POST',
466
+ { body: { message } },
467
+ );
468
+ }
469
+
412
470
  /**
413
471
  * Change task priority
414
472
  * Modify the priority of a task to increase or decrease its routing priority.
@@ -730,12 +788,13 @@ export class TaskService {
730
788
  * console.log(result.taskId); // "task456"
731
789
  */
732
790
  async complete(options = {}) {
733
- const { taskId } = options;
791
+ const { taskId, completedReason } = options;
734
792
 
735
793
  this.sdk.validateParams(
736
- { taskId },
794
+ { taskId, completedReason },
737
795
  {
738
796
  taskId: { type: 'string', required: true },
797
+ completedReason: { type: 'string', required: false },
739
798
  },
740
799
  );
741
800
 
@@ -745,6 +804,10 @@ export class TaskService {
745
804
  },
746
805
  };
747
806
 
807
+ if (completedReason) {
808
+ params.body.completedReason = completedReason;
809
+ }
810
+
748
811
  const result = await internalRequest(this.sdk,
749
812
  '/taskRouter/tasks/complete',
750
813
  'PUT',
@@ -281,4 +281,98 @@ export class WebchatService {
281
281
  // instance with just `{namespace}` and uses only this namespace.
282
282
  this.visitor = new WebchatVisitorService(sdk);
283
283
  }
284
+
285
+ /**
286
+ * Send an agent webchat message on a task. The server resolves the
287
+ * widget + engagement from the task — callers must not UOQL
288
+ * webchatConversations for widgetId.
289
+ *
290
+ * @param {Object} options
291
+ * @param {string} options.taskId
292
+ * @param {string} [options.message]
293
+ * @param {Object} [options.media]
294
+ * @param {Object|Array} [options.card]
295
+ * @returns {Promise<Object>}
296
+ */
297
+ async sendOnTask(options = {}) {
298
+ const { taskId, message, media, card } = options;
299
+
300
+ this.sdk.validateParams(
301
+ { taskId, message, media, card },
302
+ {
303
+ taskId: { type: 'string', required: true },
304
+ message: { type: 'string', required: false },
305
+ media: { type: 'object', required: false },
306
+ card: { type: 'object', required: false },
307
+ },
308
+ );
309
+
310
+ const body = {};
311
+ if (message !== undefined) body.message = message;
312
+ if (media !== undefined) body.media = media;
313
+ if (card !== undefined) body.card = card;
314
+
315
+ return internalRequest(
316
+ this.sdk,
317
+ `/webchat/tasks/${taskId}/messages`,
318
+ 'POST',
319
+ { body },
320
+ );
321
+ }
322
+
323
+ /**
324
+ * Agent/bot typing indicator on a task's webchat. Server resolves the
325
+ * engagement from the task — callers must not UOQL widgetId.
326
+ *
327
+ * @param {Object} options
328
+ * @param {string} options.taskId
329
+ * @param {boolean} options.isTyping
330
+ * @returns {Promise<Object>}
331
+ */
332
+ async typingOnTask(options = {}) {
333
+ const { taskId, isTyping } = options;
334
+
335
+ this.sdk.validateParams(
336
+ { taskId, isTyping },
337
+ {
338
+ taskId: { type: 'string', required: true },
339
+ isTyping: { type: 'boolean', required: true },
340
+ },
341
+ );
342
+
343
+ return internalRequest(
344
+ this.sdk,
345
+ `/webchat/tasks/${taskId}/typing`,
346
+ 'POST',
347
+ { body: { isTyping } },
348
+ );
349
+ }
350
+
351
+ /**
352
+ * Staff-only system note on a task's webchat feed (visibility=internal).
353
+ * Not sent to the visitor. Server resolves engagement from the task.
354
+ *
355
+ * @param {Object} options
356
+ * @param {string} options.taskId
357
+ * @param {string} options.message
358
+ * @returns {Promise<Object>}
359
+ */
360
+ async noteOnTask(options = {}) {
361
+ const { taskId, message } = options;
362
+
363
+ this.sdk.validateParams(
364
+ { taskId, message },
365
+ {
366
+ taskId: { type: 'string', required: true },
367
+ message: { type: 'string', required: true },
368
+ },
369
+ );
370
+
371
+ return internalRequest(
372
+ this.sdk,
373
+ `/webchat/tasks/${taskId}/notes`,
374
+ 'POST',
375
+ { body: { message } },
376
+ );
377
+ }
284
378
  }