@signalhousellc/sdk 1.0.66 → 1.0.68

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.
@@ -1,8 +1,14 @@
1
+ /** @typedef {import('../SignalHouseSDK.js').RequestOptions} RequestOptions */
2
+ /**
3
+ * @template T
4
+ * @typedef {import('../SignalHouseSDK.js').SdkResponse<T>} SdkResponse
5
+ */
6
+
1
7
  /**
2
8
  * @typedef {Object} CreateCampaignData
3
9
  * @property {string} brandId - The ID of the brand associated with the campaign (required)
4
10
  * @property {string} usecase - The use case for the campaign (2FA, ACCOUNT_NOTIFICATION, AGENTS_FRANCHISES, CARRIER_EXEMPT, CHARITY, CUSTOMER_CARE, DELIVERY_NOTIFICATION, EMERGENCY, FRAUD_ALERT, HIGHER_EDUCATION, K12_EDUCATION, LOW_VOLUME, M2M, MARKETING, MIXED, POLITICAL, POLLING_VOTING, PROXY, PUBLIC_SAFETY_RESTRICTED, PUBLIC_SERVICE_ANNOUNCEMENT, SECURITY_ALERT, SOCIAL, SOLE_PROPRIETOR, SWEEPSTAKE, TRIAL, UCAAS_HIGH, UCAAS_LOW)
5
- * @property {Array<string>} [subUsecases] - An array of sub-use cases for the campaign (2FA, ACCOUNT_NOTIFICATION, AGENTS_FRANCHISES, CARRIER_EXEMPT, CHARITY, CUSTOMER_CARE, DELIVERY_NOTIFICATION, EMERGENCY, FRAUD_ALERT, HIGHER_EDUCATION, K12_EDUCATION, LOW_VOLUME, M2M, MARKETING, MIXED, POLITICAL, POLLING_VOTING, PROXY, PUBLIC_SAFETY_RESTRICTED, PUBLIC_SERVICE_ANNOUNCEMENT, SECURITY_ALERT, SOCIAL, SOLE_PROPRIETOR, SWEEPSTAKE, TRIAL, UCAAS_HIGH, UCAAS_LOW)
11
+ * @property {Array<string>} [subUsecases] - An array of sub-use cases for the campaign (2FA, ACCOUNT_NOTIFICATION, AGENTS_FRANCHISES, CARRIER_EXEMPT, CHARITY, CUSTOMER_CARE, DELIVERY_NOTIFICATION, EMERGENCY, FRAUD_ALERT, HIGHER_EDUCATION, K12_EDUCATION, LOW_VOLUME, M2M, MARKETING, MIXED, POLITICAL, POLLING_VOTING, PROXY, PUBLIC_SAFETY_RESTRICTED, PUBLIC_SERVICE_ANNOUNCEMENT, SECURITY_ALERT, SOLE_PROPRIETOR, SWEEPSTAKE, TRIAL, UCAAS_HIGH, UCAAS_LOW — NOT SOCIAL, which TCR rejects as a sub-usecase for every parent usecase even though it is valid as the top-level `usecase`)
6
12
  * @property {string} description - A detailed description of the campaign (required, must be between 40 and 4096 characters)
7
13
  * @property {boolean} [embeddedLink=true] - Whether the campaign includes an embedded link (optional, defaults to true)
8
14
  * @property {boolean} [embeddedPhone=false] - Whether the campaign includes an embedded phone number (optional, defaults to false)
@@ -36,7 +42,7 @@
36
42
  /**
37
43
  * @typedef {Object} UpdateCampaignData
38
44
  * @property {string} [usecase] - The use case for the campaign (2FA, ACCOUNT_NOTIFICATION, AGENTS_FRANCHISES, CARRIER_EXEMPT, CHARITY, CUSTOMER_CARE, DELIVERY_NOTIFICATION, EMERGENCY, FRAUD_ALERT, HIGHER_EDUCATION, K12_EDUCATION, LOW_VOLUME, M2M, MARKETING, MIXED, POLITICAL, POLLING_VOTING, PROXY, PUBLIC_SAFETY_RESTRICTED, PUBLIC_SERVICE_ANNOUNCEMENT, SECURITY_ALERT, SOCIAL, SOLE_PROPRIETOR, SWEEPSTAKE, TRIAL, UCAAS_HIGH, UCAAS_LOW)
39
- * @property {Array<string>} [subUsecases] - An array of sub-use cases for the campaign (2FA, ACCOUNT_NOTIFICATION, AGENTS_FRANCHISES, CARRIER_EXEMPT, CHARITY, CUSTOMER_CARE, DELIVERY_NOTIFICATION, EMERGENCY, FRAUD_ALERT, HIGHER_EDUCATION, K12_EDUCATION, LOW_VOLUME, M2M, MARKETING, MIXED, POLITICAL, POLLING_VOTING, PROXY, PUBLIC_SAFETY_RESTRICTED, PUBLIC_SERVICE_ANNOUNCEMENT, SECURITY_ALERT, SOCIAL, SOLE_PROPRIETOR, SWEEPSTAKE, TRIAL, UCAAS_HIGH, UCAAS_LOW)
45
+ * @property {Array<string>} [subUsecases] - An array of sub-use cases for the campaign (2FA, ACCOUNT_NOTIFICATION, AGENTS_FRANCHISES, CARRIER_EXEMPT, CHARITY, CUSTOMER_CARE, DELIVERY_NOTIFICATION, EMERGENCY, FRAUD_ALERT, HIGHER_EDUCATION, K12_EDUCATION, LOW_VOLUME, M2M, MARKETING, MIXED, POLITICAL, POLLING_VOTING, PROXY, PUBLIC_SAFETY_RESTRICTED, PUBLIC_SERVICE_ANNOUNCEMENT, SECURITY_ALERT, SOLE_PROPRIETOR, SWEEPSTAKE, TRIAL, UCAAS_HIGH, UCAAS_LOW — NOT SOCIAL, which TCR rejects as a sub-usecase for every parent usecase even though it is valid as the top-level `usecase`)
40
46
  * @property {string} [description] - A detailed description of the campaign (optional, must be between 40 and 4096 characters if provided)
41
47
  * @property {boolean} [embeddedLink] - Whether the campaign includes an embedded link (optional)
42
48
  * @property {boolean} [embeddedPhone] - Whether the campaign includes an embedded phone number (optional)
@@ -115,7 +121,8 @@
115
121
  * @property {string} [doubleOptInMessage] - Required when adultContent is true (20-1024 characters)
116
122
  * @property {string} programSummary - Generated-but-editable campaign/program summary (required, 40-2048 characters)
117
123
  * @property {string} optInConfirmationMessage - The opt-in confirmation message (required, 20-1024 characters)
118
- * @property {string} [optInUrl] - Public HTTPS URL for the live opt-in experience. When omitted, Signal House uses the brand's optInLink before capturing its screenshot asynchronously, retrying up to three times.
124
+ * @property {string} optInUrl - Public HTTPS URL for the live opt-in experience, shown to reviewers as a link (required; private, local, and credentialed URLs are rejected)
125
+ * @property {string} screenshotUrl - Hosted opt-in proof screenshot URL returned by `uploadOptInImage` (required). Must be a Signal House-hosted opt-in image owned by your group; external URLs are rejected
119
126
  */
120
127
 
121
128
  /**
@@ -129,7 +136,6 @@
129
136
  * @property {string} sample1 - Sample message 1 (required, 20-1024 characters)
130
137
  * @property {string} sample2 - Sample message 2 (required, 20-1024 characters)
131
138
  * @property {string} sample3 - Sample message 3 (required, 20-1024 characters)
132
- * @property {boolean} [autoRenewal=true] - Whether the campaign should auto-renew (optional, defaults to true)
133
139
  * @property {string} [tag] - A tag for the campaign (optional, at most 255 characters)
134
140
  * @property {ShortCodeDetails} shortCode - The Short Code campaign details (required)
135
141
  */
@@ -148,9 +154,9 @@ export class Campaigns {
148
154
  * @roles signalhouse
149
155
  * @param {Object} params - The parameters for approving the campaign
150
156
  * @param {string} params.campaignId - The ID of the campaign to approve
151
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
157
+ * @param {RequestOptions} [params.options] - Additional options for the request
152
158
  * @throws {Error} Throws an error if the campaignId parameter is missing
153
- * @returns {Promise<Object>} The response from the server
159
+ * @returns {Promise<SdkResponse<any>>} The response from the server
154
160
  */
155
161
  approveCampaign: async ({ campaignId, options = {} }) => {
156
162
  this.client._require({ campaignId });
@@ -163,9 +169,9 @@ export class Campaigns {
163
169
  * @roles signalhouse
164
170
  * @param {Object} params - The parameters for rejecting the campaign
165
171
  * @param {string} params.campaignId - The ID of the campaign to reject
166
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request (body should include { rejectionReason })
172
+ * @param {RequestOptions} [params.options] - Additional options for the request (body should include { rejectionReason })
167
173
  * @throws {Error} Throws an error if the campaignId parameter is missing
168
- * @returns {Promise<Object>} The response from the server
174
+ * @returns {Promise<SdkResponse<any>>} The response from the server
169
175
  */
170
176
  rejectCampaign: async ({ campaignId, options = {} }) => {
171
177
  this.client._require({ campaignId });
@@ -177,8 +183,8 @@ export class Campaigns {
177
183
  * @async
178
184
  * @roles signalhouse
179
185
  * @param {Object} params - The parameters for retrieving CNP campaigns
180
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
181
- * @returns {Promise<Array>} The response from the server
186
+ * @param {RequestOptions} [params.options] - Additional options for the request
187
+ * @returns {Promise<SdkResponse<Array>>} The response from the server
182
188
  */
183
189
  getCNPCampaigns: async ({ options = {} } = {}) => {
184
190
  return this.client(`/campaign/cnp`, { method: 'GET', ...options });
@@ -186,16 +192,17 @@ export class Campaigns {
186
192
  /**
187
193
  * Transition a Short Code campaign's review status (SHGHL-2225). A customer-visible reason is
188
194
  * required for both rejection states ("REJECTED" = Signal House Rejected, "DCA_REJECTED" =
189
- * Rejected). Fulfillment and carrier submission are separate staff operations.
195
+ * Rejected). Selecting "PENDING_DCA_APPROVAL" runs the guarded carrier-review transition;
196
+ * fulfillment remains a separate staff operation.
190
197
  * @async
191
198
  * @roles signalhouse
192
199
  * @param {Object} params - The parameters for the status transition
193
200
  * @param {string} params.campaignId - The ID of the campaign to transition
194
- * @param {string} params.status - The target status: "PENDING_REVIEW", "REJECTED", "PENDING_CREATION", "DCA_REJECTED", or "ACTIVE". Use submitShortCodeCampaignToCarrier for "PENDING_DCA_APPROVAL".
195
- * @param {string} [params.rejectionReason] - Required for "REJECTED"/"DCA_REJECTED" (10-1024 characters)
196
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
201
+ * @param {string} params.status - The target status: "PENDING_REVIEW", "REJECTED", "PENDING_DCA_APPROVAL", "DCA_REJECTED", or "ACTIVE". "PENDING_DCA_APPROVAL" requires a Signal House-approved Short Code brand, issued code, and captured opt-in proof.
202
+ * @param {string} [params.rejectionReason] - Required, nonblank reason for "REJECTED"/"DCA_REJECTED" (max 1024 characters)
203
+ * @param {RequestOptions} [params.options] - Additional options for the request
197
204
  * @throws {Error} Throws an error if the campaignId or status parameter is missing
198
- * @returns {Promise<Object>} The updated campaign
205
+ * @returns {Promise<SdkResponse<any>>} The updated campaign
199
206
  */
200
207
  updateShortCodeCampaignStatus: async ({ campaignId, status, rejectionReason, options = {} }) => {
201
208
  this.client._require({ campaignId, status });
@@ -213,16 +220,17 @@ export class Campaigns {
213
220
  * @param {Object} params - Fulfillment parameters.
214
221
  * @param {string} params.campaignId - Campaign identifier.
215
222
  * @param {string} params.actualCode - Issued five- or six-digit Short Code.
223
+ * @param {string} params.leaseEndDate - Fixed future lease end date. A YYYY-MM-DD value expires at 23:59:59 UTC; timestamps retain their supplied time.
216
224
  * @param {string} [params.internalNotes] - Staff-only fulfillment notes.
217
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options.
218
- * @returns {Promise<Object>} The updated campaign.
225
+ * @param {RequestOptions} [params.options] - Additional options.
226
+ * @returns {Promise<SdkResponse<any>>} The updated campaign.
219
227
  */
220
- fulfillShortCodeCampaign: async ({ campaignId, actualCode, internalNotes, options = {} }) => {
221
- this.client._require({ campaignId, actualCode });
228
+ fulfillShortCodeCampaign: async ({ campaignId, actualCode, leaseEndDate, internalNotes, options = {} }) => {
229
+ this.client._require({ campaignId, actualCode, leaseEndDate });
222
230
  const safeCampaignId = encodeURIComponent(campaignId);
223
231
  return this.client(`/campaign/short-code/${safeCampaignId}/fulfill`, {
224
232
  method: 'POST',
225
- body: { actualCode, internalNotes },
233
+ body: { actualCode, leaseEndDate, internalNotes },
226
234
  ...options,
227
235
  });
228
236
  },
@@ -232,8 +240,8 @@ export class Campaigns {
232
240
  * @roles signalhouse
233
241
  * @param {Object} params - Submission parameters.
234
242
  * @param {string} params.campaignId - Campaign identifier.
235
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options.
236
- * @returns {Promise<Object>} The updated campaign.
243
+ * @param {RequestOptions} [params.options] - Additional options.
244
+ * @returns {Promise<SdkResponse<any>>} The updated campaign.
237
245
  */
238
246
  submitShortCodeCampaignToCarrier: async ({ campaignId, options = {} }) => {
239
247
  this.client._require({ campaignId });
@@ -243,6 +251,73 @@ export class Campaigns {
243
251
  ...options,
244
252
  });
245
253
  },
254
+ /**
255
+ * Confirm Registry offboarding and complete a pending Short Code cancellation.
256
+ * @async
257
+ * @param {Object} params - Request parameters.
258
+ * @param {string} params.campaignId - Campaign identifier.
259
+ * @param {string} params.requestId - The pending cancellation request to complete.
260
+ * @param {string} [params.note] - Operator note recorded with the completion.
261
+ * @param {RequestOptions} [params.options] - Additional options.
262
+ * @returns {Promise<SdkResponse<any>>} The updated campaign.
263
+ */
264
+ completeShortCodeCancellation: async ({ campaignId, requestId, note, options = {} }) => {
265
+ this.client._require({ campaignId, requestId });
266
+ const safeCampaignId = encodeURIComponent(campaignId);
267
+ return this.client(`/campaign/short-code/${safeCampaignId}/cancellation/complete`, {
268
+ method: 'POST',
269
+ body: { requestId, note },
270
+ ...options,
271
+ });
272
+ },
273
+ /**
274
+ * Dismiss a pending Short Code cancellation and restore its prior lifecycle state.
275
+ * @async
276
+ * @param {Object} params - Request parameters.
277
+ * @param {string} params.campaignId - Campaign identifier.
278
+ * @param {string} params.requestId - The pending cancellation request to dismiss.
279
+ * @param {string} [params.note] - Operator note recorded with the dismissal.
280
+ * @param {RequestOptions} [params.options] - Additional options.
281
+ * @returns {Promise<SdkResponse<any>>} The updated campaign.
282
+ */
283
+ dismissShortCodeCancellation: async ({ campaignId, requestId, note, options = {} }) => {
284
+ this.client._require({ campaignId, requestId });
285
+ const safeCampaignId = encodeURIComponent(campaignId);
286
+ return this.client(`/campaign/short-code/${safeCampaignId}/cancellation/dismiss`, {
287
+ method: 'POST',
288
+ body: { requestId, note },
289
+ ...options,
290
+ });
291
+ },
292
+ /**
293
+ * Read expired Short Code leases awaiting manual Registry offboarding.
294
+ * @async
295
+ * @param {Object} [params] - Request parameters.
296
+ * @param {number} [params.page] - Page number for pagination.
297
+ * @param {number} [params.limit] - Results per page.
298
+ * @param {RequestOptions} [params.options] - Additional options.
299
+ * @returns {Promise<SdkResponse<any>>} The expired leases page.
300
+ */
301
+ getExpiredShortCodeLeases: async ({ page, limit, options = {} } = {}) => {
302
+ const query = this.client._getQueryString({ page, limit });
303
+ return this.client(`/campaign/short-code/expired-leases${query}`, { method: 'GET', ...options });
304
+ },
305
+ /**
306
+ * Confirm Registry offboarding and mark an expired Short Code released.
307
+ * @async
308
+ * @param {Object} params - Request parameters.
309
+ * @param {string} params.campaignId - Campaign identifier.
310
+ * @param {string} [params.note] - Operator note recorded with the release.
311
+ * @param {RequestOptions} [params.options] - Additional options.
312
+ * @returns {Promise<SdkResponse<any>>} The updated campaign.
313
+ */
314
+ releaseExpiredShortCodeLease: async ({ campaignId, note, options = {} }) => {
315
+ this.client._require({ campaignId });
316
+ const safeCampaignId = encodeURIComponent(campaignId);
317
+ return this.client(`/campaign/short-code/${safeCampaignId}/expired-lease/release`, {
318
+ method: 'POST', body: { note }, ...options,
319
+ });
320
+ },
246
321
  };
247
322
  }
248
323
  }
@@ -263,7 +338,7 @@ export class Campaigns {
263
338
  * @param {string} [params.sortBy] - Field to sort by (e.g. "createdAt", "campaignId", "brandId", "groupId", "subgroupId", "usecase", "status")
264
339
  * @param {string} [params.sortOrder] - Sort direction ("asc" or "desc")
265
340
  * @param {string} [params.registrationType] - Filter by registration type ("TEN_DLC", "TOLL_FREE", or "SHORT_CODE")
266
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
341
+ * @param {RequestOptions} [params.options] - Additional options for the request
267
342
  *
268
343
  * Every record carries a `sentiment` object -- trailing 7-day and 30-day inbound reply sentiment,
269
344
  * refreshed periodically from analytics rather than computed per request: `{ sevenDay, thirtyDay,
@@ -273,7 +348,15 @@ export class Campaigns {
273
348
  * window, which is not the same as a score of 0 -- null means nobody replied, 0 means replies
274
349
  * averaged neutral. `updatedAt` is null until the first rollup writes the record, and it tracks when
275
350
  * the figures last CHANGED, not when the job last ran.
276
- * @returns {Promise<Array|Object>} The response from the server - array when unpaginated, or { data, total, page, limit, totalPages } when paginated
351
+ *
352
+ * Every record also carries a `health` object -- trailing 7-day and 30-day delivery/opt-out health from
353
+ * the same periodic refresh: `{ sevenDay, thirtyDay, updatedAt }`, each window being `{ score,
354
+ * deliveryRate, optOutRate, deliveryScore, optOutScore, messagesSent, messagesDelivered, messagesFailed,
355
+ * optOuts }`. `score` is 1.0..10.0 (the mean of the two bucket scores) and is null when nothing was sent
356
+ * in the window; the volumes say how much traffic sits behind it. A campaign's figure is scored from the
357
+ * campaign's own summed counters, never averaged from its numbers. For a live figure use GET /number/health
358
+ * or GET /campaign/health.
359
+ * @returns {Promise<SdkResponse<Array|Object>>} The response from the server - array when unpaginated, or { data, total, page, limit, totalPages } when paginated
277
360
  */
278
361
  async getCampaigns({
279
362
  id,
@@ -313,8 +396,8 @@ export class Campaigns {
313
396
  * @param {Object} params - Parameters for reading campaign health
314
397
  * @param {string} params.campaignId - Campaign identifier
315
398
  * @param {boolean} [params.includeNumbers=false] - When true, include per-number health entries
316
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional request options
317
- * @returns {Promise<Object>} A promise that resolves to `{ campaignId, sevenDay, thirtyDay, numbers? }`
399
+ * @param {RequestOptions} [params.options] - Additional request options
400
+ * @returns {Promise<SdkResponse<any>>} A promise that resolves to `{ campaignId, sevenDay, thirtyDay, numbers? }`
318
401
  */
319
402
  async getCampaignHealth({ campaignId, includeNumbers = false, options = {} }) {
320
403
  this.client._require({ campaignId });
@@ -322,15 +405,34 @@ export class Campaigns {
322
405
  return this.client(`/campaign/health${queryString}`, { method: 'GET', ...options });
323
406
  }
324
407
 
408
+ /**
409
+ * Get the carrier throughput ceilings a campaign is currently sending under: the AT&T per-minute limit
410
+ * (per campaign, held 10% under the published ceiling) and the T-Mobile daily cap (per brand), each with
411
+ * its current tier and the next rung on the ladder, plus today's T-Mobile usage. Resolved from the same
412
+ * brand status / brand score rules the send path enforces with.
413
+ * @async
414
+ * @roles api, admin, developer, billing, user
415
+ * @param {Object} params - Parameters for reading campaign throughput limits
416
+ * @param {string} params.campaignId - Campaign identifier
417
+ * @param {RequestOptions} [params.options] - Additional request options
418
+ * @throws {Error} Throws an error if the campaignId parameter is missing
419
+ * @returns {Promise<SdkResponse<any>>} A promise that resolves to `{ campaignId, brandId, usecase, brand: { status, brandScore, entityType }, att: { tier, scope, unit, sms: { limit }, mms: { limit }, marginPercent, nextTier }, tmobile: { tier, scope, unit, dailyLimit, thresholds, nextTier, usedToday: { date, segments, resetsAt } | null } }`. A null tier/limit means the carrier ladder does not apply (unverified brand, GOVERNMENT entity, PUBLIC_SAFETY_RESTRICTED usecase); a null nextTier means the top rung or a usecase-capped (LOW_VOLUME) campaign.
420
+ */
421
+ async getCampaignThroughputLimits({ campaignId, options = {} }) {
422
+ this.client._require({ campaignId });
423
+ const queryString = this.client._getQueryString({ campaignId });
424
+ return this.client(`/campaign/throughput-limits${queryString}`, { method: 'GET', ...options });
425
+ }
426
+
325
427
  /**
326
428
  * Create a new campaign
327
429
  * @async
328
430
  * @roles api, admin, developer, billing, user
329
431
  * @param {Object} params - The parameters for creating the campaign (see CreateCampaignData typedef for details)
330
432
  * @param {CreateCampaignData} params.campaignData - The data for the campaign to be created (see CreateCampaignData typedef for details)
331
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
433
+ * @param {RequestOptions} [params.options] - Additional options for the request
332
434
  * @throws {Error} Throws an error if the campaignData parameter is missing or if required fields in campaignData are missing
333
- * @returns {Promise<Object>} The response from the server
435
+ * @returns {Promise<SdkResponse<any>>} The response from the server
334
436
  */
335
437
  async createCampaign({ campaignData, options = {} }) {
336
438
  this.client._require({ campaignData: campaignData });
@@ -343,9 +445,9 @@ export class Campaigns {
343
445
  * @roles api, admin, developer, user
344
446
  * @param {Object} params - The parameters for creating the toll-free campaign
345
447
  * @param {CreateTollFreeCampaignData} params.campaignData - The data for the toll-free campaign to be created (see CreateTollFreeCampaignData typedef for details)
346
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
448
+ * @param {RequestOptions} [params.options] - Additional options for the request
347
449
  * @throws {Error} Throws an error if the campaignData parameter is missing
348
- * @returns {Promise<Object>} The response from the server
450
+ * @returns {Promise<SdkResponse<any>>} The response from the server
349
451
  */
350
452
  async createTollFreeCampaign({ campaignData, options = {} }) {
351
453
  this.client._require({ campaignData });
@@ -354,16 +456,16 @@ export class Campaigns {
354
456
 
355
457
  /**
356
458
  * Create a new Short Code campaign and submit it for Signal House review (SHGHL-2225). Requires an
357
- * approved (VERIFIED) Short Code brand. `campaignData.shortCode.optInUrl` is optional; Signal House
358
- * uses the brand's `optInLink` when it is omitted, then captures its screenshot asynchronously, retrying up to three times. Request or register the
359
- * campaign's Short Code separately through `numbers.requestShortCodeAcquisition` after creation.
459
+ * approved (VERIFIED) Short Code brand. Upload the opt-in proof screenshot first with `uploadOptInImage`
460
+ * and pass the returned URL as `campaignData.shortCode.screenshotUrl` (required). Request or register the
461
+ * campaign's Short Code separately through `numbers.requestShortCodeAcquisition` after creation.
360
462
  * @async
361
463
  * @roles api, admin, developer, user
362
464
  * @param {Object} params - The parameters for creating the Short Code campaign
363
465
  * @param {CreateShortCodeCampaignData} params.campaignData - The Short Code campaign data (see CreateShortCodeCampaignData typedef for details)
364
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
466
+ * @param {RequestOptions} [params.options] - Additional options for the request
365
467
  * @throws {Error} Throws an error if the campaignData parameter is missing
366
- * @returns {Promise<Object>} The response from the server
468
+ * @returns {Promise<SdkResponse<any>>} The response from the server
367
469
  */
368
470
  async createShortCodeCampaign({ campaignData, options = {} }) {
369
471
  this.client._require({ campaignData });
@@ -379,10 +481,10 @@ export class Campaigns {
379
481
  * @roles api, admin, developer, user
380
482
  * @param {Object} params - The parameters for updating the Short Code campaign
381
483
  * @param {string} params.campaignId - The ID of the campaign to update
382
- * @param {Object} params.updateData - The fields to update (top-level campaign fields plus an optional `shortCode` object of editable Short Code fields)
383
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
484
+ * @param {Object} params.updateData - The fields to update (top-level campaign fields plus an optional `shortCode` object of editable Short Code fields; pass a new `uploadOptInImage` URL as `shortCode.screenshotUrl` to replace the opt-in proof)
485
+ * @param {RequestOptions} [params.options] - Additional options for the request
384
486
  * @throws {Error} Throws an error if the campaignId parameter is missing
385
- * @returns {Promise<Object>} The updated campaign
487
+ * @returns {Promise<SdkResponse<any>>} The updated campaign
386
488
  */
387
489
  async updateShortCodeCampaign({ campaignId, updateData, options = {} }) {
388
490
  this.client._require({ campaignId });
@@ -391,17 +493,16 @@ export class Campaigns {
391
493
  }
392
494
 
393
495
  /**
394
- * Cancel a Short Code campaign (SHGHL-2225). Customers may cancel only while the campaign is in Signal
395
- * House Review or Signal House Rejected status; Signal House staff may cancel from any non-terminal
396
- * status. Persists as "EXPIRED" (displayed as "Cancelled"). A real Registry lease (external or an
397
- * already-fulfilled Signal House request) is never auto-released — see SHGHL-2228 for offboarding.
496
+ * Cancel a Short Code campaign. A customer cancellation for an issued Short Code returns
497
+ * PENDING_DELETE (displayed as Cancellation Pending) until Signal House confirms Registry offboarding.
498
+ * Unissued RANDOM/VANITY requests, plus staff-confirmed cancellations, return EXPIRED immediately.
398
499
  * @async
399
500
  * @roles api, admin, developer, user
400
501
  * @param {Object} params - The parameters for cancelling the campaign
401
502
  * @param {string} params.campaignId - The ID of the campaign to cancel
402
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
503
+ * @param {RequestOptions} [params.options] - Additional options for the request
403
504
  * @throws {Error} Throws an error if the campaignId parameter is missing
404
- * @returns {Promise<Object>} The cancelled campaign
505
+ * @returns {Promise<SdkResponse<any>>} The cancelled campaign
405
506
  */
406
507
  async cancelShortCodeCampaign({ campaignId, options = {} }) {
407
508
  this.client._require({ campaignId });
@@ -418,9 +519,9 @@ export class Campaigns {
418
519
  * @roles api, admin, developer, user
419
520
  * @param {Object} params - The parameters for downloading the artifact
420
521
  * @param {string} params.artifactId - The receipt identifier from `numberSource.externalLease.receiptArtifactId`
421
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
522
+ * @param {RequestOptions} [params.options] - Additional options for the request
422
523
  * @throws {Error} Throws an error if the artifactId parameter is missing
423
- * @returns {Promise<Object>} The response from the server (raw file bytes as `data` when a binary responseType is used)
524
+ * @returns {Promise<SdkResponse<any>>} The response from the server (raw file bytes as `data` when a binary responseType is used)
424
525
  */
425
526
  async readCampaignArtifact({ artifactId, options = {} }) {
426
527
  this.client._require({ artifactId });
@@ -430,14 +531,14 @@ export class Campaigns {
430
531
 
431
532
  /**
432
533
  * Upload an opt-in proof image to be hosted on-platform, returning a publicly-fetchable URL suitable for a
433
- * Toll-Free campaign's optInImageURLs
534
+ * Toll-Free campaign's optInImageURLs or a Short Code campaign's shortCode.screenshotUrl
434
535
  * @async
435
536
  * @roles api, admin, developer, user
436
537
  * @param {Object} params - The parameters for uploading the opt-in image
437
- * @param {Buffer|Blob|File} params.file - The image file to upload, provided as a Buffer/Blob/File
438
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
538
+ * @param {Blob|File} params.file - The image file to upload, provided as a Blob/File
539
+ * @param {RequestOptions} [params.options] - Additional options for the request
439
540
  * @throws {Error} Throws an error if the file parameter is missing
440
- * @returns {Promise<Object>} The response from the server containing the hosted image's id and URL
541
+ * @returns {Promise<SdkResponse<any>>} The response from the server containing the hosted image's id and URL
441
542
  */
442
543
  async uploadOptInImage({ file, options = {} }) {
443
544
  this.client._require({ file });
@@ -456,9 +557,9 @@ export class Campaigns {
456
557
  * @param {string} [params.landingId] - The specific page to capture. Required for Toll-Free brands, which have
457
558
  * one page per campaign — omitted, the request is refused rather than guessing which page to shoot. A 10DLC
458
559
  * brand has a single page, so it may be omitted there
459
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
560
+ * @param {RequestOptions} [params.options] - Additional options for the request
460
561
  * @throws {Error} Throws an error if the brandId parameter is missing
461
- * @returns {Promise<Object>} The response from the server containing the hosted image's id and URL
562
+ * @returns {Promise<SdkResponse<any>>} The response from the server containing the hosted image's id and URL
462
563
  */
463
564
  async captureOptInImageFromLanding({ brandId, landingId, options = {} }) {
464
565
  this.client._require({ brandId });
@@ -474,9 +575,9 @@ export class Campaigns {
474
575
  * @param {Object} params - The parameters for updating the campaign (see UpdateCampaignData typedef for details)
475
576
  * @param {string} params.campaignId - The ID of the campaign to update
476
577
  * @param {UpdateCampaignData} params.campaignData - The data for the campaign to be updated (see UpdateCampaignData typedef for details)
477
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
578
+ * @param {RequestOptions} [params.options] - Additional options for the request
478
579
  * @throws {Error} Throws an error if the campaignId parameter is missing or if required fields in campaignData are missing
479
- * @returns {Promise<Object>} The response from the server
580
+ * @returns {Promise<SdkResponse<any>>} The response from the server
480
581
  */
481
582
  async updateCampaign({ campaignId, campaignData, options = {} }) {
482
583
  this.client._require({ campaignId: campaignId });
@@ -491,9 +592,9 @@ export class Campaigns {
491
592
  * @param {Object} params - The parameters for adding the comment
492
593
  * @param {string} params.campaignId - The ID of the campaign
493
594
  * @param {string} params.comment - The comment/note text
494
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
595
+ * @param {RequestOptions} [params.options] - Additional options for the request
495
596
  * @throws {Error} Throws an error if the campaignId or comment parameter is missing
496
- * @returns {Promise<Object>} The updated campaign object
597
+ * @returns {Promise<SdkResponse<any>>} The updated campaign object
497
598
  */
498
599
  async addCampaignComment({ campaignId, comment, options = {} }) {
499
600
  this.client._require({ campaignId, comment });
@@ -507,9 +608,9 @@ export class Campaigns {
507
608
  * @roles api, admin, developer, billing, user
508
609
  * @param {Object} params - The parameters for deleting the campaign
509
610
  * @param {string} params.campaignId - The ID of the campaign to delete
510
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
611
+ * @param {RequestOptions} [params.options] - Additional options for the request
511
612
  * @throws {Error} Throws an error if the campaignId parameter is missing
512
- * @returns {Promise<Object>} The response from the server
613
+ * @returns {Promise<SdkResponse<any>>} The response from the server
513
614
  */
514
615
  async deleteCampaign({ campaignId, options = {} }) {
515
616
  this.client._require({ campaignId: campaignId });
@@ -523,9 +624,9 @@ export class Campaigns {
523
624
  * @roles api, admin, developer, billing, user
524
625
  * @param {Object} params - The parameters for appealing the campaign rejection
525
626
  * @param {string} params.campaignId - The ID of the campaign to appeal
526
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request (body should include { reason })
627
+ * @param {RequestOptions} [params.options] - Additional options for the request (body should include { reason })
527
628
  * @throws {Error} Throws an error if the campaignId parameter is missing
528
- * @returns {Promise<Object>} The response from the server
629
+ * @returns {Promise<SdkResponse<any>>} The response from the server
529
630
  */
530
631
  async appealDcaRejection({ campaignId, options = {} }) {
531
632
  this.client._require({ campaignId: campaignId });
@@ -539,9 +640,9 @@ export class Campaigns {
539
640
  * @roles api, admin, developer, billing, user
540
641
  * @param {Object} params - The parameters for nudging the campaign
541
642
  * @param {string} params.campaignId - The ID of the campaign to nudge
542
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
643
+ * @param {RequestOptions} [params.options] - Additional options for the request
543
644
  * @throws {Error} Throws an error if the campaignId parameter is missing
544
- * @returns {Promise<Object>} The response from the server
645
+ * @returns {Promise<SdkResponse<any>>} The response from the server
545
646
  */
546
647
  async nudgeDcaForCampaign({ campaignId, options = {} }) {
547
648
  this.client._require({ campaignId: campaignId });
@@ -1,3 +1,9 @@
1
+ /** @typedef {import('../SignalHouseSDK.js').RequestOptions} RequestOptions */
2
+ /**
3
+ * @template T
4
+ * @typedef {import('../SignalHouseSDK.js').SdkResponse<T>} SdkResponse
5
+ */
6
+
1
7
  export class Groups {
2
8
  constructor(client, enableAdmin) {
3
9
  this.client = client;
@@ -15,8 +21,8 @@ export class Groups {
15
21
  * @param {string} [params.groupId] - Restrict results to a group.
16
22
  * @param {number} [params.limit] - Maximum rows to return.
17
23
  * @param {number} [params.offset] - Rows to skip; requires limit.
18
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request.
19
- * @returns {Promise<Object>} - Group-level resource count rows.
24
+ * @param {RequestOptions} [params.options] - Additional options for the request.
25
+ * @returns {Promise<SdkResponse<any>>} - Group-level resource count rows.
20
26
  */
21
27
  getGroupCounts: async ({ groupId, limit, offset, options = {} } = {}) => {
22
28
  const queryString = this.client._getQueryString({ groupId, limit, offset });
@@ -30,8 +36,8 @@ export class Groups {
30
36
  * @param {Object} params - The parameters for getting groups
31
37
  * @param {number} [params.page] - The page number for pagination
32
38
  * @param {number} [params.limit] - The number of items per page
33
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
34
- * @returns {Promise<Object>} - The list of groups returned from the server
39
+ * @param {RequestOptions} [params.options] - Additional options for the request
40
+ * @returns {Promise<SdkResponse<any>>} - The list of groups returned from the server
35
41
  */
36
42
  getGroups: async ({ page, limit, options = {} }) => {
37
43
  const filters = { page, limit };
@@ -45,24 +51,55 @@ export class Groups {
45
51
  * @roles signalhouse
46
52
  * @param {Object} params - The parameters for creating a new group
47
53
  * @param {Object} params.groupData - The data for the new group, including required fields such as groupName. Optionally accepts `psPartnerKey` and `ownerEmail` to credit a referring partner.
48
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
54
+ * @param {RequestOptions} [params.options] - Additional options for the request
49
55
  * @throws {Error} Throws an error if the groupData parameter is missing or if required fields within groupData are missing
50
- * @returns {Promise<Object>} - The created group object returned from the server
56
+ * @returns {Promise<SdkResponse<any>>} - The created group object returned from the server
51
57
  */
52
58
  createGroup: async ({ groupData, options = {} }) => {
53
59
  this.client._require({ groupData: groupData });
54
60
  return this.client(`/group`, { method: "POST", body: groupData, ...options });
55
61
  },
56
62
 
63
+ /**
64
+ * Record a GHL-app or Shopify-app install's registration for the per-surface
65
+ * customer-lifecycle webhook system. Call this right after admin.createGroup when
66
+ * provisioning a group outside the Portal's self-registration flow (which records
67
+ * itself automatically) — without it, the group never fires a registration webhook and
68
+ * is never eligible for the "registered but no brand submitted" staleness webhook.
69
+ * Internal-only: not documented in the public API reference (deliberate exception, see
70
+ * CLAUDE.md's API Change Propagation Rules — mirrors the /oauth exception).
71
+ * @async
72
+ * @roles signalhouse_api, signalhouse_admin
73
+ * @param {Object} params - The parameters for recording a registration
74
+ * @param {string} params.groupId - The just-provisioned group's ID
75
+ * @param {string} params.registrationSource - Which surface provisioned this group ("ghl" or "shopify")
76
+ * @param {string} [params.firstName] - The account owner's first name
77
+ * @param {string} [params.fullName] - The account owner's full name
78
+ * @param {string} [params.email] - The account owner's email
79
+ * @param {string} [params.phone] - The account owner's phone number
80
+ * @param {string} [params.estimatedVolume] - Estimated monthly message volume
81
+ * @param {RequestOptions} [params.options] - Additional options for the request
82
+ * @throws {Error} Throws an error if the groupId or registrationSource parameter is missing
83
+ * @returns {Promise<SdkResponse<any>>} - `{ success: true }`
84
+ */
85
+ recordLifecycleRegistration: async ({ groupId, registrationSource, firstName, fullName, email, phone, estimatedVolume, options = {} }) => {
86
+ this.client._require({ groupId, registrationSource });
87
+ return this.client(`/group/lifecycle/registration`, {
88
+ method: "POST",
89
+ body: { groupId, registrationSource, firstName, fullName, email, phone, estimatedVolume },
90
+ ...options,
91
+ });
92
+ },
93
+
57
94
  /**
58
95
  * Delete a group with the specified group ID
59
96
  * @async
60
97
  * @roles signalhouse
61
98
  * @param {Object} params - The parameters for deleting a group
62
99
  * @param {string} params.groupId - The ID of the group to delete
63
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
100
+ * @param {RequestOptions} [params.options] - Additional options for the request
64
101
  * @throws {Error} Throws an error if the groupId parameter is missing
65
- * @returns {Promise<Object>} - The deleted group object returned from the server
102
+ * @returns {Promise<SdkResponse<any>>} - The deleted group object returned from the server
66
103
  */
67
104
  deleteGroup: async ({ groupId, options = {} }) => {
68
105
  this.client._require({ groupId });
@@ -78,9 +115,9 @@ export class Groups {
78
115
  * @param {Object} params - The parameters for updating a group's compliance status
79
116
  * @param {string} params.groupId - The ID of the group to update
80
117
  * @param {string} params.complianceStatus - One of "unverified", "pending", "verified", "rejected"
81
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
118
+ * @param {RequestOptions} [params.options] - Additional options for the request
82
119
  * @throws {Error} Throws an error if the groupId or complianceStatus parameter is missing
83
- * @returns {Promise<Object>} - The updated group object returned from the server
120
+ * @returns {Promise<SdkResponse<any>>} - The updated group object returned from the server
84
121
  */
85
122
  updateComplianceStatus: async ({ groupId, complianceStatus, options = {} }) => {
86
123
  this.client._require({ groupId, complianceStatus });
@@ -99,9 +136,9 @@ export class Groups {
99
136
  * @param {string} params.externalSystem - The external system ("ghl" or "shopify")
100
137
  * @param {string} params.externalId - The external tenant identifier
101
138
  * @param {string} [params.existingGroupId] - An existing V2 group ID to repoint to, if any
102
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
139
+ * @param {RequestOptions} [params.options] - Additional options for the request
103
140
  * @throws {Error} Throws an error if linkToken, externalSystem, or externalId is missing
104
- * @returns {Promise<Object>} - The link outcome ({ status, canonicalGroupId, ... })
141
+ * @returns {Promise<SdkResponse<any>>} - The link outcome ({ status, canonicalGroupId, ... })
105
142
  */
106
143
  linkExternal: async ({ linkToken, externalSystem, externalId, existingGroupId, options = {} }) => {
107
144
  this.client._require({ linkToken, externalSystem, externalId });
@@ -121,8 +158,8 @@ export class Groups {
121
158
  * @roles api, admin, developer, billing, user
122
159
  * @param {Object} params - The parameters for getting a group
123
160
  * @param {string} params.id - The ID of the group to retrieve
124
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
125
- * @returns {Promise<Object>} - The group object returned from the server
161
+ * @param {RequestOptions} [params.options] - Additional options for the request
162
+ * @returns {Promise<SdkResponse<any>>} - The group object returned from the server
126
163
  */
127
164
  async getGroup({ id, options = {} }) {
128
165
  const filters = { id };
@@ -138,9 +175,9 @@ export class Groups {
138
175
  * @param {string} params.id - The ID of the group to update
139
176
  * @param {Object} params.groupData - The data for the group, including required fields such as groupName.
140
177
  * Optional CNP fields: cspId (string|null), defaultCnpSubgroupId (string|null)
141
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
178
+ * @param {RequestOptions} [params.options] - Additional options for the request
142
179
  * @throws {Error} Throws an error if the id or groupData parameter is missing
143
- * @returns {Promise<Object>} - The updated group object returned from the server
180
+ * @returns {Promise<SdkResponse<any>>} - The updated group object returned from the server
144
181
  */
145
182
  async updateGroup({ id, groupData, options = {} }) {
146
183
  this.client._require({ id, groupData: groupData });