@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,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
  /**
2
8
  * @typedef {Object} TollFreeConsentBox
3
9
  * @property {string} useCase - The use case the checkbox covers
@@ -67,9 +73,9 @@ export class Landings {
67
73
  * @roles api, admin, developer, billing, user
68
74
  * @param {Object} params - The parameters for getting a landing page
69
75
  * @param {string} params.landingId - The ID of the landing page to retrieve
70
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
76
+ * @param {RequestOptions} [params.options] - Additional options for the request
71
77
  * @throws {Error} Throws an error if the landingId parameter is missing
72
- * @returns {Promise<Object>} - The landing page object returned from the server
78
+ * @returns {Promise<SdkResponse<any>>} - The landing page object returned from the server
73
79
  */
74
80
  async getLandings({ landingId, options = {} }) {
75
81
  this.client._require({ landingId });
@@ -82,9 +88,9 @@ export class Landings {
82
88
  * @async
83
89
  * @param {Object} params - The parameters for getting a public landing page
84
90
  * @param {string} params.landingId - The ID of the public landing page to retrieve
85
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
91
+ * @param {RequestOptions} [params.options] - Additional options for the request
86
92
  * @throws {Error} Throws an error if the landingId parameter is missing
87
- * @returns {Promise<Object>} - The public landing page object returned from the server
93
+ * @returns {Promise<SdkResponse<any>>} - The public landing page object returned from the server
88
94
  */
89
95
  async getPublicLanding({ landingId, options = {} }) {
90
96
  this.client._require({ landingId });
@@ -98,9 +104,9 @@ export class Landings {
98
104
  * @roles api, admin, developer, billing, user
99
105
  * @param {Object} params - The parameters for creating a new landing page (see CreateLandingData typedef for details)
100
106
  * @param {CreateLandingData} params.landingData - The data for the new landing page, including required fields such as brandId and description
101
- * @param {Buffer} params.file - A logo image file for the landing page, provided as a Buffer
102
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
103
- * @returns {Promise<Object>} - The newly created landing page object returned from the server
107
+ * @param {Blob|File} params.file - A logo image file for the landing page, provided as a Blob/File
108
+ * @param {RequestOptions} [params.options] - Additional options for the request
109
+ * @returns {Promise<SdkResponse<any>>} - The newly created landing page object returned from the server
104
110
  */
105
111
  async createLanding({ landingData, file, options = {} }) {
106
112
  const formData = new FormData();
@@ -111,7 +117,7 @@ export class Landings {
111
117
 
112
118
  Object.entries(landingData).forEach(([key, value]) => {
113
119
  if (value !== undefined) {
114
- formData.append(key, typeof value === "object" ? JSON.stringify(value) : value);
120
+ formData.append(key, typeof value === "object" ? JSON.stringify(value) : String(value));
115
121
  }
116
122
  });
117
123
 
@@ -125,10 +131,10 @@ export class Landings {
125
131
  * @param {Object} params - The parameters for updating a landing page (see UpdateLandingData typedef for details)
126
132
  * @param {string} params.landingId - The ID of the landing page to update
127
133
  * @param {UpdateLandingData} params.landingData - The data for the landing page, including required fields such as brandId and description
128
- * @param {Buffer} params.file - A logo image file for the landing page, provided as a Buffer
129
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
134
+ * @param {Blob|File} params.file - A logo image file for the landing page, provided as a Blob/File
135
+ * @param {RequestOptions} [params.options] - Additional options for the request
130
136
  * @throws {Error} Throws an error if the landingId parameter is missing
131
- * @returns {Promise<Object>} - The updated landing page object returned from the server
137
+ * @returns {Promise<SdkResponse<any>>} - The updated landing page object returned from the server
132
138
  */
133
139
  async updateLanding({ landingId, landingData, file, options = {} }) {
134
140
  this.client._require({ landingId });
@@ -141,32 +147,22 @@ export class Landings {
141
147
 
142
148
  Object.entries(landingData).forEach(([key, value]) => {
143
149
  if (value !== undefined) {
144
- formData.append(key, typeof value === "object" ? JSON.stringify(value) : value);
150
+ formData.append(key, typeof value === "object" ? JSON.stringify(value) : String(value));
145
151
  }
146
152
  });
147
153
 
148
154
  return this.multipartClient(`/landing/${safeLandingId}`, { method: "PUT", body: formData, ...options });
149
155
  }
150
156
 
151
- /**
152
- * Delete a landing page by its ID
153
- * @async
154
- * @roles api, admin, developer, billing, user
155
- * @param {Object} params - The parameters for deleting a landing page
156
- * @param {string} params.landingId - The ID of the landing page to delete
157
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
158
- * @throws {Error} Throws an error if the landingId parameter is missing
159
- * @returns {Promise<Object>} - The response from the server after deleting the landing page
160
- */
161
157
  /**
162
158
  * Get a landing page by its associated brand ID
163
159
  * @async
164
160
  * @roles api, admin, developer, billing, user
165
161
  * @param {Object} params - The parameters for getting a landing page by brand
166
162
  * @param {string} params.brandId - The brand ID to look up the landing page for
167
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
163
+ * @param {RequestOptions} [params.options] - Additional options for the request
168
164
  * @throws {Error} Throws an error if the brandId parameter is missing
169
- * @returns {Promise<Object>} - The landing page object returned from the server
165
+ * @returns {Promise<SdkResponse<any>>} - The landing page object returned from the server
170
166
  */
171
167
  async getLandingByBrandId({ brandId, options = {} }) {
172
168
  this.client._require({ brandId });
@@ -181,9 +177,9 @@ export class Landings {
181
177
  * @roles api, admin, developer, billing, user
182
178
  * @param {Object} params - The parameters for getting a landing page template
183
179
  * @param {string} params.brandId - The brand ID to look up the template for
184
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
180
+ * @param {RequestOptions} [params.options] - Additional options for the request
185
181
  * @throws {Error} Throws an error if the brandId parameter is missing
186
- * @returns {Promise<Object>} - The template returned from the server
182
+ * @returns {Promise<SdkResponse<any>>} - The template returned from the server
187
183
  */
188
184
  async getLandingTemplate({ brandId, options = {} }) {
189
185
  this.client._require({ brandId });
@@ -199,11 +195,11 @@ export class Landings {
199
195
  * @param {Object} params - The parameters for saving a landing page template
200
196
  * @param {string} params.brandId - The brand the template belongs to
201
197
  * @param {LandingTemplateData} params.templateData - The template fields (see LandingTemplateData typedef)
202
- * @param {Buffer} [params.file] - A logo image file, provided as a Buffer. Required the first time only;
198
+ * @param {Blob|File} [params.file] - A logo image file, provided as a Blob/File. Required the first time only;
203
199
  * omit it on a later save to keep the stored logo
204
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
200
+ * @param {RequestOptions} [params.options] - Additional options for the request
205
201
  * @throws {Error} Throws an error if the brandId parameter is missing
206
- * @returns {Promise<Object>} - The saved template returned from the server
202
+ * @returns {Promise<SdkResponse<any>>} - The saved template returned from the server
207
203
  */
208
204
  async upsertLandingTemplate({ brandId, templateData, file, options = {} }) {
209
205
  this.client._require({ brandId });
@@ -216,13 +212,23 @@ export class Landings {
216
212
 
217
213
  Object.entries(templateData).forEach(([key, value]) => {
218
214
  if (value !== undefined) {
219
- formData.append(key, typeof value === "object" ? JSON.stringify(value) : value);
215
+ formData.append(key, typeof value === "object" ? JSON.stringify(value) : String(value));
220
216
  }
221
217
  });
222
218
 
223
219
  return this.multipartClient(`/landing/template/${safeBrandId}`, { method: "PUT", body: formData, ...options });
224
220
  }
225
221
 
222
+ /**
223
+ * Delete a landing page by its ID
224
+ * @async
225
+ * @roles api, admin, developer, billing, user
226
+ * @param {Object} params - The parameters for deleting a landing page
227
+ * @param {string} params.landingId - The ID of the landing page to delete
228
+ * @param {RequestOptions} [params.options] - Additional options for the request
229
+ * @throws {Error} Throws an error if the landingId parameter is missing
230
+ * @returns {Promise<SdkResponse<any>>} - The response from the server after deleting the landing page
231
+ */
226
232
  async deleteLanding({ landingId, options = {} }) {
227
233
  this.client._require({ landingId });
228
234
  const safeLandingId = encodeURIComponent(landingId);
@@ -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 Messages {
2
8
  constructor(client, multipartClient, enableAdmin) {
3
9
  this.client = client;
@@ -5,6 +11,16 @@ export class Messages {
5
11
  this.enableAdmin = enableAdmin;
6
12
  }
7
13
 
14
+ /**
15
+ * Estimate Canadian SMS/MMS retail cost without sending or charging.
16
+ * @async
17
+ * @param {Object} params - Sender, up to 100 recipients, messageBody and request options.
18
+ * @returns {Promise<SdkResponse<any>>} - Per-recipient rates and total in microdollars; unknown carriers use the upper fallback.
19
+ */
20
+ async estimateMessage({ senderPhoneNumber, recipientPhoneNumbers, messageBody, messageType = "SMS", options = {} }) {
21
+ return this.client("/message/estimate", { method: "POST", body: { senderPhoneNumber, recipientPhoneNumbers, messageBody, messageType }, ...options });
22
+ }
23
+
8
24
  /**
9
25
  * Get a list of messages with optional filters and pagination parameters
10
26
  * @async
@@ -18,20 +34,22 @@ export class Messages {
18
34
  * @param {string} [params.status] - Filter messages by their status (ENQUEUED, DEQUEUED, SENT, FAILED, DELIVERED)
19
35
  * @param {string} [params.direction] - Filter messages by their direction (INBOUND, OUTBOUND)
20
36
  * @param {string|string[]} [params.messageType] - Filter messages by their type. Accepts a single value or an array (e.g. ["SMS", "MMS"]). Allowed values: SMS, MMS, RCS, WHATSAPP, VIBER, P2P. When omitted, defaults to all non-P2P types.
21
- * @param {string|string[]} [params.channel] - Filter messages by channel. Accepts a single value or an array. Allowed values: tenDLC, tollFree, shortCode, p2p. Each message records its channel when it is saved, and this filters on that stored value; older messages from before this feature have no channel and count as tenDLC. Ignored when matchAny is true (matchAny takes precedence).
37
+ * @param {string|string[]} [params.channel] - Filter messages by channel. Accepts a single value or an array. Allowed values: tenDLC, virtualLongCode, tollFree, shortCode, p2p. Each message records its channel when it is saved, and this filters on that stored value; older messages from before this feature have no channel and count as tenDLC. Ignored when matchAny is true (matchAny takes precedence).
22
38
  * @param {boolean} [params.matchAny] - When true, the provided campaignId/brandId/phoneNumber filters are OR'd (a message matches ANY of them) instead of the default most-specific-single behavior. subgroupId stays an AND scope. Opt-in/additive.
23
39
  * @param {string} [params.carrier] - Filter messages by the carrier used for sending
24
40
  * @param {string|string[]} [params.sentimentLabel] - Filter messages by sentiment bucket. Accepts a single value or an array (e.g. ["positive", "negative"]). Allowed values: positive, neutral, negative. Applied as the sentimentScore range the ±25 label threshold produces, so unscored messages match no bucket and outbound messages (never scored) are excluded.
41
+ * @param {string|string[]} [params.phoneNumber] - Filter messages by a business number on either side of the message. Accepts a single value or an array; OR'd with campaignId/brandId when matchAny is true
25
42
  * @param {string} [params.senderPhoneNumber] - Filter messages by the sender's 5-6 digit Short Code or 10+ digit phone number
26
43
  * @param {string} [params.recipientPhoneNumber] - Filter messages by the recipient's phone number
27
- * @param {string} [params.startDate] - ISO-8601 date or timestamp; normalized to start-of-UTC-day (inclusive)
28
- * @param {string} [params.endDate] - ISO-8601 date or timestamp; normalized to end-of-UTC-day (inclusive). Hourly resolution is not supported
44
+ * @param {string} [params.startDate] - ISO-8601 date or timestamp; bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode
45
+ * @param {string} [params.endDate] - ISO-8601 date or timestamp; bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode. In "exact" mode day buckets align to the UTC offset this bound carries, so a client that sends its own midnights gets its own calendar dates back
29
46
  * @param {string} [params.sortField] - The field to sort the messages by (createdAt, segmentCount, status, sentimentScore)
30
47
  * @param {string} [params.sortOrder] - The order to sort the messages (asc, desc)
31
48
  * @param {number} [params.page] - The page number for pagination
32
49
  * @param {number} [params.limit] - The number of messages per page
33
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
34
- * @returns {Promise<Object>} - A promise that resolves to the list of messages. Inbound messages also carry
50
+ * @param {("day"|"exact")} [params.dateBounds] - Which contract binds startDate/endDate. "day": each bound is widened to its whole UTC day. "exact": a timestamp is bound as the instant it names and a bare date is its whole UTC day. Omitted: "day".
51
+ * @param {RequestOptions} [params.options] - Additional options for the request
52
+ * @returns {Promise<SdkResponse<any>>} - A promise that resolves to the list of messages. Inbound messages also carry
35
53
  * sentimentScore (-100..100, null when unscored), sentimentLabel ("positive"|"neutral"|"negative", null when
36
54
  * sentimentScore is null) and sentimentScoredAt. Outbound messages are never scored.
37
55
  */
@@ -57,9 +75,10 @@ export class Messages {
57
75
  sortOrder,
58
76
  page,
59
77
  limit,
78
+ dateBounds,
60
79
  options = {},
61
80
  }) {
62
- const filters = { id, campaignId, brandId, subgroupId, groupId, phoneNumber, senderPhoneNumber, recipientPhoneNumber, status, direction, messageType, channel, matchAny, carrier, sentimentLabel, startDate, endDate, sortField, sortOrder, page, limit };
81
+ const filters = { id, campaignId, brandId, subgroupId, groupId, phoneNumber, senderPhoneNumber, recipientPhoneNumber, status, direction, messageType, channel, matchAny, carrier, sentimentLabel, startDate, endDate, sortField, sortOrder, page, limit, dateBounds };
63
82
  const queryString = this.client._getQueryString(filters);
64
83
  return this.client(`/message${queryString}`, { method: "GET", ...options });
65
84
  }
@@ -72,8 +91,8 @@ export class Messages {
72
91
  * @roles api, admin, developer, billing, user
73
92
  * @param {Object} params - The parameters for fetching delivery reports
74
93
  * @param {string[]} params.messageIds - The message IDs to fetch carrier delivery reports for (1-100)
75
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
76
- * @returns {Promise<Object>} - A promise that resolves to an array of carrier delivery reports
94
+ * @param {RequestOptions} [params.options] - Additional options for the request
95
+ * @returns {Promise<SdkResponse<any>>} - A promise that resolves to an array of carrier delivery reports
77
96
  */
78
97
  async getDeliveryReports({ messageIds, options = {} }) {
79
98
  this.client._require({ messageIds });
@@ -95,13 +114,15 @@ export class Messages {
95
114
  * @param {string|string[]} [params.campaignId] - Filter analytics by the ID of the associated campaign. Accepts a single value, an array, or a comma-separated string.
96
115
  * @param {string|string[]} [params.phoneNumber] - Filter analytics by the phone number involved in the messages. Accepts a single value, an array, or a comma-separated string.
97
116
  * @param {string|string[]} [params.carrier] - Filter analytics by the carrier used for sending. Accepts a single value, an array, or a comma-separated string.
98
- * @param {string} [params.startDate] - ISO-8601 date or timestamp; normalized to start-of-UTC-day (inclusive)
99
- * @param {string} [params.endDate] - ISO-8601 date or timestamp; normalized to end-of-UTC-day (inclusive). Hourly resolution is not supported
117
+ * @param {string|string[]} [params.carrierFamily] - Filter analytics by the recipient's resolved carrier family (Default, ATT, TMobile, Verizon, USCellular, GoogleVoice, ClearSky, Interop, RogueMobile, P2P). Accepts a single value, an array, or a comma-separated string. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400 -- omit the parameter unless it is wanted.
118
+ * @param {string} [params.startDate] - ISO-8601 date or timestamp; bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode
119
+ * @param {string} [params.endDate] - ISO-8601 date or timestamp; bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode. In "exact" mode day buckets align to the UTC offset this bound carries, so a client that sends its own midnights gets its own calendar dates back
100
120
  * @param {boolean} [params.matchAny] - When true, the provided campaignId/brandId/phoneNumber filters are OR'd (match ANY) instead of the default most-specific-single behavior. subgroupId stays an AND scope. Opt-in/additive.
101
121
  * @param {(string|string[])} [params.messageType] - Message type(s) the SENTIMENT figures are scoped to: SMS, MMS or P2P (single value, array, or comma-separated string). Omit for all scored types. Does NOT narrow the message counts, which are always returned split per type (smsInbound/mmsInbound/p2pInbound) and have no filterable type dimension.
102
- * @param {string|string[]} [params.channel] - Filter analytics by channel (tenDLC, tollFree, shortCode, p2p). Filters on the stored channel column; a tenDLC selection also includes older messages that have no channel, and p2p is a real channel here (matched by carrier). Accepts a single value or an array. Ignored when matchAny is true (matchAny takes precedence).
103
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
104
- * @returns {Promise<Object>} - A promise that resolves to the analytics data. Also includes inbound-message
122
+ * @param {string|string[]} [params.channel] - Filter analytics by channel (tenDLC, virtualLongCode, tollFree, shortCode, p2p). Filters on the stored channel column; a tenDLC selection also includes older messages that have no channel, and p2p is a real channel here (matched by carrier). Accepts a single value or an array. Ignored when matchAny is true (matchAny takes precedence).
123
+ * @param {("day"|"exact")} [params.dateBounds] - Which contract binds startDate/endDate. "day": each bound is widened to its whole UTC day. "exact": a timestamp is bound as the instant it names and a bare date is its whole UTC day. Omitted: "day".
124
+ * @param {RequestOptions} [params.options] - Additional options for the request
125
+ * @returns {Promise<SdkResponse<any>>} - A promise that resolves to the analytics data. Also includes inbound-message
105
126
  * sentiment for the requested scope: sentimentScore (volume-weighted average of every scored inbound message
106
127
  * in range, -100..100, null when nothing was scored), sentimentLabel ("positive"|"neutral"|"negative", null
107
128
  * when sentimentScore is null), sentimentScoredCount, sentimentPositive, sentimentNeutral, sentimentNegative.
@@ -110,8 +131,8 @@ export class Messages {
110
131
  * summed or re-averaged across types, rows or responses. To weight a subset of message types, pass
111
132
  * messageType and read sentimentScore.
112
133
  */
113
- async getAnalytics({ groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, channel, messageType, matchAny, options = {} }) {
114
- const filters = { groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, channel, messageType, matchAny };
134
+ async getAnalytics({ groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, carrierFamily, startDate, endDate, channel, messageType, matchAny, dateBounds, options = {} }) {
135
+ const filters = { groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, carrierFamily, startDate, endDate, channel, messageType, matchAny, dateBounds };
115
136
  const queryString = this.client._getQueryString(filters);
116
137
  return this.client(`/message/analytics${queryString}`, { method: "GET", ...options });
117
138
  }
@@ -127,12 +148,16 @@ export class Messages {
127
148
  * @param {string|string[]} [params.campaignId] - Filter analytics by the ID of the associated campaign. Accepts a single value, an array, or a comma-separated string.
128
149
  * @param {string|string[]} [params.phoneNumber] - Filter analytics by the phone number involved in the messages. Accepts a single value, an array, or a comma-separated string.
129
150
  * @param {string|string[]} [params.carrier] - Filter analytics by the carrier used for sending. Accepts a single value, an array, or a comma-separated string.
130
- * @param {string} [params.startDate] - ISO-8601 date or timestamp; normalized to start-of-UTC-day (inclusive)
131
- * @param {string} [params.endDate] - ISO-8601 date or timestamp; normalized to end-of-UTC-day (inclusive). Hourly resolution is not supported
151
+ * @param {string|string[]} [params.carrierFamily] - Filter analytics by the recipient's resolved carrier family (Default, ATT, TMobile, Verizon, USCellular, GoogleVoice, ClearSky, Interop, RogueMobile, P2P). Accepts a single value, an array, or a comma-separated string. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400 -- omit the parameter unless it is wanted.
152
+ * @param {string} [params.startDate] - ISO-8601 date or timestamp. It is bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode, then floored to the start of its hour at either granularity, because the hourly cube is keyed by hour and a mid-hour start would drop that hour's bucket.
153
+ * @param {string} [params.endDate] - ISO-8601 date or timestamp. At day granularity it is bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode. In "exact" mode day buckets align to the UTC offset this bound carries, so a client that sends its own midnights gets its own calendar dates back; at hour granularity it is honoured as given.
132
154
  * @param {(string|string[])} [params.messageType] - Message type(s) the SENTIMENT figures are scoped to: SMS, MMS or P2P (single value, array, or comma-separated string). Omit for all scored types. Does NOT narrow the message counts, which are always returned split per type (smsInbound/mmsInbound/p2pInbound) and have no filterable type dimension.
133
- * @param {string|string[]} [params.channel] - Filter analytics by channel (tenDLC, tollFree, shortCode, p2p). Filters on the stored channel column; a tenDLC selection also includes older messages that have no channel, and p2p is a real channel here. Accepts a single value or an array.
134
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
135
- * @returns {Promise<Array>} - A promise that resolves to an array of analytics snapshot records. cardTotals and
155
+ * @param {string|string[]} [params.channel] - Filter analytics by channel (tenDLC, virtualLongCode, tollFree, shortCode, p2p). Filters on the stored channel column; a tenDLC selection also includes older messages that have no channel, and p2p is a real channel here. Accepts a single value or an array.
156
+ * @param {("day"|"hour")} [params.granularity] - Time-bucket grain of the byDate rows. Omit for day (each row's _id is a "YYYY-MM-DD" date). "hour" buckets by hour (each row's _id is a "YYYY-MM-DD HH:MM:SS" UTC hour) and is capped to a 7-day span. Only accepted where the environment serves hourly analytics; elsewhere any value, including "day", is rejected with a 400 -- omit the parameter unless hour grain is wanted.
157
+ * @param {("carrier"|"carrierFamily")} [params.breakdown] - Adds a byBreakdown time × dimension series to the response ({ dimension, rows }: each row is one byDate bucket (_id) for one carrier or carrier family (key), over the top 50 keys by volume, 10DLC only) and caps the span at 31 days. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400 -- omit the parameter unless it is wanted.
158
+ * @param {("day"|"exact")} [params.dateBounds] - Which contract binds startDate/endDate. "day": each bound is widened to its whole UTC day. "exact": a timestamp is bound as the instant it names and a bare date is its whole UTC day. Omitted: "day".
159
+ * @param {RequestOptions} [params.options] - Additional options for the request
160
+ * @returns {Promise<SdkResponse<Array>>} - A promise that resolves to an array of analytics snapshot records. cardTotals and
136
161
  * every byDate/byPhoneNumber/byCarrier row also carry that row's own inbound-message sentiment: sentimentScore
137
162
  * (volume-weighted average, -100..100, null when nothing in that row's scope was scored), sentimentLabel,
138
163
  * sentimentScoredCount, sentimentPositive, sentimentNeutral, sentimentNegative. The fields are always present;
@@ -140,12 +165,39 @@ export class Messages {
140
165
  * score is divided server-side and the raw sums are never returned: a score is an average and must never be
141
166
  * summed or re-averaged across types, rows or responses.
142
167
  */
143
- async getAnalyticsDetail({ groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, channel, messageType, options = {} }) {
144
- const filters = { groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, channel, messageType };
168
+ async getAnalyticsDetail({ groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, carrierFamily, startDate, endDate, channel, messageType, granularity, breakdown, dateBounds, options = {} }) {
169
+ const filters = { groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, carrierFamily, startDate, endDate, channel, messageType, granularity, breakdown, dateBounds };
145
170
  const queryString = this.client._getQueryString(filters);
146
171
  return this.client(`/message/analytics/detail${queryString}`, { method: "GET", ...options });
147
172
  }
148
173
 
174
+ /**
175
+ * Get per-minute send throughput (peak segments per minute, sending minutes, minutes at a ceiling) for a
176
+ * campaign, brand, or group, per time bucket and per carrier family. Measured from SENT transitions at
177
+ * campaign × carrier-family grain -- the grain carrier ceilings are enforced at -- so a peak here is the
178
+ * figure a ceiling is compared against. Only accepted where the environment serves hourly analytics;
179
+ * elsewhere the request is rejected with a 400.
180
+ * @async
181
+ * @roles api, admin, developer, billing, user
182
+ * @param {Object} params - The parameters for the throughput read
183
+ * @param {string} params.groupId - The group to scope the read to (required)
184
+ * @param {string|string[]} [params.brandId] - Brand scope. Accepts a single value, an array, or a comma-separated string.
185
+ * @param {string|string[]} [params.campaignId] - Campaign scope; wins over brandId. Accepts a single value, an array, or a comma-separated string.
186
+ * @param {string|string[]} [params.carrierFamily] - Carrier-family filter (ATT, TMobile, Verizon, USCellular, ...). Accepts a single value, an array, or a comma-separated string.
187
+ * @param {string} params.startDate - ISO-8601 date or timestamp. It is bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode, then floored to the start of its hour at hour granularity and of its minute at day granularity (the cube is keyed by minute).
188
+ * @param {string} params.endDate - ISO-8601 date or timestamp. At hour granularity it is honoured as given; at day granularity it is bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode. In "exact" mode day buckets align to the UTC offset this bound carries, so a client that sends its own midnights gets its own calendar dates back. The span is capped at 35 days (the retention of the per-minute data).
189
+ * @param {("hour"|"day")} [params.granularity] - Bucket grain of the byDate and byBreakdown rows. Omit for hour (each row's _id is a "YYYY-MM-DD HH:MM:SS" UTC hour, span capped at 7 days); "day" buckets by calendar day on the end bound's offset.
190
+ * @param {number} [params.ceiling] - Segments-per-minute ceiling. When given, every row also reports minutesAtCeiling (sending minutes at or above it); otherwise minutesAtCeiling is null.
191
+ * @param {("day"|"exact")} [params.dateBounds] - Which contract binds startDate/endDate. "day": each bound is widened to its whole UTC day. "exact": a timestamp is bound as the instant it names and a bare date is its whole UTC day. Omitted: "day".
192
+ * @param {RequestOptions} [params.options] - Additional options for the request
193
+ * @returns {Promise<SdkResponse<any>>} - `{ totals, byDate, byCarrierFamily, byBreakdown: { dimension: "carrierFamily", rows } }`. Every row carries segments, messages, peakSegmentsPerMinute, peakMessagesPerMinute, peakMinute (UTC "YYYY-MM-DD HH:MM:SS", null when no traffic), sendingMinutes, averageSegmentsPerSendingMinute and minutesAtCeiling.
194
+ */
195
+ async getAnalyticsThroughput({ groupId, brandId, campaignId, carrierFamily, startDate, endDate, granularity, ceiling, dateBounds, options = {} }) {
196
+ const filters = { groupId, brandId, campaignId, carrierFamily, startDate, endDate, granularity, ceiling, dateBounds };
197
+ const queryString = this.client._getQueryString(filters);
198
+ return this.client(`/message/analytics/throughput${queryString}`, { method: "GET", ...options });
199
+ }
200
+
149
201
  /**
150
202
  * Get filter dropdown options (subgroups, brands, campaigns, phone numbers) for the Analytics page,
151
203
  * scoped to a single group. Sourced from ClickHouse — only items with at least one message are returned.
@@ -153,8 +205,8 @@ export class Messages {
153
205
  * @roles api, admin, developer, billing, user
154
206
  * @param {Object} params - The parameters for getting analytics filter options
155
207
  * @param {string} params.groupId - The ID of the group whose filter options to load
156
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
157
- * @returns {Promise<Object>} - A promise that resolves to { subgroups, brands, campaigns, phoneNumbers }
208
+ * @param {RequestOptions} [params.options] - Additional options for the request
209
+ * @returns {Promise<SdkResponse<any>>} - A promise that resolves to { subgroups, brands, campaigns, phoneNumbers }
158
210
  */
159
211
  async getAnalyticsFilterOptions({ groupId, options = {} }) {
160
212
  const filters = { groupId };
@@ -174,18 +226,20 @@ export class Messages {
174
226
  * @param {string|string[]} [params.campaignId]
175
227
  * @param {string|string[]} [params.phoneNumber]
176
228
  * @param {string|string[]} [params.carrier]
229
+ * @param {string|string[]} [params.carrierFamily] - Resolved carrier family of the recipient (Default, ATT, TMobile, Verizon, USCellular, GoogleVoice, ClearSky, Interop, RogueMobile, P2P); single value, array, or comma-separated. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400 -- omit the parameter unless it is wanted.
177
230
  * @param {string} [params.startDate]
178
231
  * @param {string} [params.endDate]
179
232
  * @param {number} [params.page=1]
180
233
  * @param {number} [params.limit=50] - max 50 per page
181
- * @param {("tenDLC"|"tollFree"|"shortCode"|"p2p"|"both")|Array<"tenDLC"|"tollFree"|"shortCode"|"p2p">} [params.channel="both"] - Filter and rank rows by the stored channel column. "both" (default) means all activity. tenDLC/tollFree/shortCode/p2p (single value or array) limit to the selected channel(s).
234
+ * @param {("tenDLC"|"virtualLongCode"|"tollFree"|"shortCode"|"p2p"|"both")|Array<"tenDLC"|"virtualLongCode"|"tollFree"|"shortCode"|"p2p">} [params.channel="both"] - Filter and rank rows by the stored channel column. "both" (default) means all activity. tenDLC/virtualLongCode/tollFree/shortCode/p2p (single value or array) limit to the selected channel(s).
182
235
  * @param {(string|string[])} [params.messageType] - Message type(s) the SENTIMENT figures are scoped to: SMS, MMS or P2P (single value, array, or comma-separated string). Omit for all scored types. Does NOT narrow the message counts, which are always returned split per type (smsInbound/mmsInbound/p2pInbound) and have no filterable type dimension.
183
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options]
184
- * @returns {Promise<Object>} - { rows, totalCount, page, limit }. Each row carries sms/mms/p2p metric columns plus `smsOptOuts` and `mmsOptOuts` from the DNC analytics MV (P2P has no opt-outs).
236
+ * @param {("day"|"exact")} [params.dateBounds] - Which contract binds startDate/endDate. "day": each bound is widened to its whole UTC day. "exact": a timestamp is bound as the instant it names and a bare date is its whole UTC day. Omitted: "day".
237
+ * @param {RequestOptions} [params.options]
238
+ * @returns {Promise<SdkResponse<any>>} - { rows, totalCount, page, limit }. Each row carries sms/mms/p2p metric columns plus `smsOptOuts` and `mmsOptOuts` from the DNC analytics MV (P2P has no opt-outs).
185
239
  * Each row also carries that subgroup's inbound-message sentiment: `sentimentScore` (volume-weighted average of every scored inbound message in that subgroup, -100..100, null when nothing was scored), `sentimentLabel`, `sentimentScoredCount`, `sentimentPositive`, `sentimentNeutral`, `sentimentNegative`, plus the same six per message type under `smsSentiment*`, `mmsSentiment*` and `p2pSentiment*` prefixes. The score is derived server-side and must never be re-averaged across rows — combine the counts, not the scores.
186
240
  */
187
- async getAnalyticsBySubgroup({ groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, page, limit, channel, messageType, options = {} }) {
188
- const filters = { groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, page, limit, channel, messageType };
241
+ async getAnalyticsBySubgroup({ groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, carrierFamily, startDate, endDate, page, limit, channel, messageType, dateBounds, options = {} }) {
242
+ const filters = { groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, carrierFamily, startDate, endDate, page, limit, channel, messageType, dateBounds };
189
243
  const queryString = this.client._getQueryString(filters);
190
244
  return this.client(`/message/analytics/by-subgroup${queryString}`, { method: "GET", ...options });
191
245
  }
@@ -202,16 +256,18 @@ export class Messages {
202
256
  * @param {string|string[]} [params.campaignId]
203
257
  * @param {string|string[]} [params.phoneNumber]
204
258
  * @param {string|string[]} [params.carrier]
259
+ * @param {string|string[]} [params.carrierFamily] - Resolved carrier family of the recipient (Default, ATT, TMobile, Verizon, USCellular, GoogleVoice, ClearSky, Interop, RogueMobile, P2P); single value, array, or comma-separated. Only accepted where the environment serves hourly analytics; elsewhere any value is rejected with a 400 -- omit the parameter unless it is wanted.
205
260
  * @param {string} [params.startDate]
206
261
  * @param {string} [params.endDate]
207
262
  * @param {number} [params.page=1]
208
263
  * @param {number} [params.limit=50] - max 50 per page
209
- * @param {("tenDLC"|"tollFree"|"shortCode"|"p2p"|"both")|Array<"tenDLC"|"tollFree"|"shortCode"|"p2p">} [params.channel="both"] - Filter and rank rows by the stored channel column. "both" (default) means every code. tenDLC/tollFree/shortCode/p2p (single value or array) limit to the selected channel(s); when one channel is selected, totalErrors reflects only that channel.
210
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options]
211
- * @returns {Promise<Object>} - { rows, totalCount, totalErrors: { sms, mms, p2p, all }, page, limit }
264
+ * @param {("tenDLC"|"virtualLongCode"|"tollFree"|"shortCode"|"p2p"|"both")|Array<"tenDLC"|"virtualLongCode"|"tollFree"|"shortCode"|"p2p">} [params.channel="both"] - Filter and rank rows by the stored channel column. "both" (default) means every code. tenDLC/virtualLongCode/tollFree/shortCode/p2p (single value or array) limit to the selected channel(s); when one channel is selected, totalErrors reflects only that channel.
265
+ * @param {("day"|"exact")} [params.dateBounds] - Which contract binds startDate/endDate. "day": each bound is widened to its whole UTC day. "exact": a timestamp is bound as the instant it names and a bare date is its whole UTC day. Omitted: "day".
266
+ * @param {RequestOptions} [params.options]
267
+ * @returns {Promise<SdkResponse<any>>} - { rows, totalCount, totalErrors: { sms, mms, p2p, all }, page, limit }
212
268
  */
213
- async getAnalyticsByErrorCode({ groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, page, limit, channel, options = {} }) {
214
- const filters = { groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, page, limit, channel };
269
+ async getAnalyticsByErrorCode({ groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, carrierFamily, startDate, endDate, page, limit, channel, dateBounds, options = {} }) {
270
+ const filters = { groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, carrierFamily, startDate, endDate, page, limit, channel, dateBounds };
215
271
  const queryString = this.client._getQueryString(filters);
216
272
  return this.client(`/message/analytics/by-error-code${queryString}`, { method: "GET", ...options });
217
273
  }
@@ -227,14 +283,15 @@ export class Messages {
227
283
  * @param {string} [params.campaignId] - Filter by the ID of the associated campaign
228
284
  * @param {string} [params.phoneNumber] - Filter by the phone number
229
285
  * @param {string} [params.carrier] - Filter by the carrier
230
- * @param {string} [params.startDate] - ISO-8601 date or timestamp; normalized to start-of-UTC-day (inclusive)
231
- * @param {string} [params.endDate] - ISO-8601 date or timestamp; normalized to end-of-UTC-day (inclusive). Hourly resolution is not supported
232
- * @param {string|string[]} [params.channel] - Filter by channel (tenDLC, tollFree, shortCode). Opt-outs are A2P-only, so p2p applies no filter. Filters on the stored channel column; a tenDLC selection also includes older opt-outs that have no channel.
233
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
234
- * @returns {Promise<Object>} - A promise that resolves to the DNC analytics data (totals, byDate, byPhoneNumber, byCarrier)
286
+ * @param {string} [params.startDate] - ISO-8601 date or timestamp; bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode
287
+ * @param {string} [params.endDate] - ISO-8601 date or timestamp; bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode. In "exact" mode day buckets align to the UTC offset this bound carries, so a client that sends its own midnights gets its own calendar dates back
288
+ * @param {string|string[]} [params.channel] - Filter by channel (tenDLC, virtualLongCode, tollFree, shortCode). Opt-outs are A2P-only, so p2p applies no filter. Filters on the stored channel column; a tenDLC selection also includes older opt-outs that have no channel.
289
+ * @param {("day"|"exact")} [params.dateBounds] - Which contract binds startDate/endDate. "day": each bound is widened to its whole UTC day. "exact": a timestamp is bound as the instant it names and a bare date is its whole UTC day. Omitted: "day".
290
+ * @param {RequestOptions} [params.options] - Additional options for the request
291
+ * @returns {Promise<SdkResponse<any>>} - A promise that resolves to the DNC analytics data (totals, byDate, byPhoneNumber, byCarrier, byKeyword). byKeyword breaks opt-outs down by the normalized keyword that revoked consent ({ optOutKeyword, total, sms, mms }); opt-outs recorded before keyword capture shipped appear as a single optOutKeyword: null bucket ("not recorded"). The distinct keyword set is open-ended (campaigns register their own keywords beyond the mandatory floor) — render top-N plus Other, never a fixed list.
235
292
  */
236
- async getDncAnalytics({ groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, channel, options = {} }) {
237
- const filters = { groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, channel };
293
+ async getDncAnalytics({ groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, channel, dateBounds, options = {} }) {
294
+ const filters = { groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, channel, dateBounds };
238
295
  const queryString = this.client._getQueryString(filters);
239
296
  return this.client(`/message/dnc/analytics${queryString}`, { method: "GET", ...options });
240
297
  }
@@ -250,18 +307,19 @@ export class Messages {
250
307
  * @param {string} [params.campaignId] - Filter by the ID of the associated campaign
251
308
  * @param {string} [params.phoneNumber] - Filter by the phone number
252
309
  * @param {string} [params.carrier] - Filter by the carrier
253
- * @param {string} [params.startDate] - ISO-8601 date or timestamp; normalized to start-of-UTC-day (inclusive)
254
- * @param {string} [params.endDate] - ISO-8601 date or timestamp; normalized to end-of-UTC-day (inclusive). Hourly resolution is not supported
310
+ * @param {string} [params.startDate] - ISO-8601 date or timestamp; bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode
311
+ * @param {string} [params.endDate] - ISO-8601 date or timestamp; bound per dateBounds: a bare date is always that whole UTC day (inclusive); a timestamp is widened to its whole UTC day in "day" mode and bound as the instant it names, in whatever offset it was written, in "exact" mode. In "exact" mode day buckets align to the UTC offset this bound carries, so a client that sends its own midnights gets its own calendar dates back
255
312
  * @param {number} [params.page] - Page number for pagination
256
313
  * @param {number} [params.limit] - Number of records per page
257
314
  * @param {string} [params.sortField] - Field to sort by
258
315
  * @param {string} [params.sortOrder] - Sort direction (asc, desc)
259
- * @param {string|string[]} [params.channel] - Filter by channel (tenDLC, tollFree, shortCode). Opt-outs are A2P-only, so p2p applies no filter. Filters on the stored channel column; a tenDLC selection also includes older opt-outs that have no channel.
260
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
261
- * @returns {Promise<Object>} - A promise that resolves to the paginated DNC records
316
+ * @param {string|string[]} [params.channel] - Filter by channel (tenDLC, virtualLongCode, tollFree, shortCode). Opt-outs are A2P-only, so p2p applies no filter. Filters on the stored channel column; a tenDLC selection also includes older opt-outs that have no channel.
317
+ * @param {("day"|"exact")} [params.dateBounds] - Which contract binds startDate/endDate. "day": each bound is widened to its whole UTC day. "exact": a timestamp is bound as the instant it names and a bare date is its whole UTC day. Omitted: "day".
318
+ * @param {RequestOptions} [params.options] - Additional options for the request
319
+ * @returns {Promise<SdkResponse<any>>} - A promise that resolves to the paginated DNC records. Each record carries optOutKeyword — the normalized keyword that revoked consent (e.g. "stop", "opt out"; a repeat opt-out records the most recent word), null for opt-outs recorded before keyword capture shipped — and carrierFamily, the resolved carrier family of the recipient number (Default, ATT, TMobile, Verizon, USCellular, GoogleVoice, ClearSky, Interop, RogueMobile), copied from the inbound message that triggered the opt-out.
262
320
  */
263
- async getDncRecords({ groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, page, limit, sortField, sortOrder, channel, options = {} }) {
264
- const filters = { groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, page, limit, sortField, sortOrder, channel };
321
+ async getDncRecords({ groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, page, limit, sortField, sortOrder, channel, dateBounds, options = {} }) {
322
+ const filters = { groupId, subgroupId, brandId, campaignId, phoneNumber, carrier, startDate, endDate, page, limit, sortField, sortOrder, channel, dateBounds };
265
323
  const queryString = this.client._getQueryString(filters);
266
324
  return this.client(`/message/dnc${queryString}`, { method: "GET", ...options });
267
325
  }
@@ -282,13 +340,13 @@ export class Messages {
282
340
  * @roles api, admin, developer, billing, user
283
341
  * @param {Object} params - The parameters for sending an SMS message
284
342
  * @param {string} params.senderPhoneNumber - The 5-6 digit Short Code or 10+ digit phone number to send the message from
285
- * @param {string|string[]} params.recipientPhoneNumbers - The phone number(s) to send the message to
343
+ * @param {string|string[]} params.recipientPhoneNumbers - The 10+ digit phone number(s) to send the message to. A Short Code sender permits exactly one recipient, and it must be a +1 (US/Canada) number; a bare 10-digit number is treated as +1. The API rejects Short Code sends with multiple recipients or a non-+1 recipient.
286
344
  * @param {string} params.messageBody - The body of the SMS message
287
345
  * @param {string} [params.statusCallbackUrl] - The URL to receive status callbacks
288
346
  * @param {boolean} [params.enableShortlink=false] - Whether to enable shortlink in the message
289
347
  * @param {boolean} [params.filterLandlinesAndInactiveNumbers=false] - Whether to filter out landline and inactive numbers before sending
290
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
291
- * @returns {Promise<Object>} - A promise that resolves to the response data from the server
348
+ * @param {RequestOptions} [params.options] - Additional options for the request
349
+ * @returns {Promise<SdkResponse<any>>} - A promise that resolves to the response data from the server
292
350
  */
293
351
  async sendSMS({ senderPhoneNumber, recipientPhoneNumbers, messageBody, statusCallbackUrl, enableShortlink = false, filterLandlinesAndInactiveNumbers = false, options = {} }) {
294
352
  this.client._require({ senderPhoneNumber, recipientPhoneNumbers, messageBody });
@@ -314,8 +372,8 @@ export class Messages {
314
372
  * @param {boolean} [params.useSignalHouseShortlinks] - When false, SignalHouse applies no link-shortening
315
373
  * or text-spin and your pre-spun links/content are sent verbatim (bring-your-own spinner). Defaults to
316
374
  * true server-side (the SignalHouse shortlink system, which mints unique per-recipient links).
317
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
318
- * @returns {Promise<Object>} - A promise that resolves to the response data from the server
375
+ * @param {RequestOptions} [params.options] - Additional options for the request
376
+ * @returns {Promise<SdkResponse<any>>} - A promise that resolves to the response data from the server
319
377
  */
320
378
  async sendP2P({ recipientPhoneNumbers, messageBody, statusCallbackUrl, groupId, subgroupId, useSignalHouseShortlinks, options = {} }) {
321
379
  this.client._require({ recipientPhoneNumbers, messageBody });
@@ -337,9 +395,9 @@ export class Messages {
337
395
  * @roles api, admin, developer, billing, user
338
396
  * @param {Object} params - The parameters for getting a P2P batch
339
397
  * @param {string} params.batchId - The ID of the P2P batch to retrieve
340
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
398
+ * @param {RequestOptions} [params.options] - Additional options for the request
341
399
  * @throws {Error} Throws an error if the batchId parameter is missing
342
- * @returns {Promise<Object>} - The P2P batch object returned from the server
400
+ * @returns {Promise<SdkResponse<any>>} - The P2P batch object returned from the server
343
401
  */
344
402
  async getP2PBatch({ batchId, options = {} }) {
345
403
  this.client._require({ batchId });
@@ -363,7 +421,7 @@ export class Messages {
363
421
  * @roles api, admin, developer, billing, user
364
422
  * @param {Object} params - The parameters for sending an MMS message
365
423
  * @param {string} params.senderPhoneNumber - The 5-6 digit Short Code or 10+ digit phone number to send the message from
366
- * @param {string[]} params.recipientPhoneNumbers - The phone number(s) to send the message to
424
+ * @param {string[]} params.recipientPhoneNumbers - The 10+ digit phone number(s) to send the message to. A Short Code sender permits exactly one recipient, and it must be a +1 (US/Canada) number; a bare 10-digit number is treated as +1. The API rejects Short Code sends with multiple recipients or a non-+1 recipient.
367
425
  * @param {string} params.messageBody - The body of the MMS message
368
426
  * @param {string[]} [params.mediaUrls] - The URLs of the media attachments
369
427
  * @param {string} [params.statusCallbackUrl] - The URL to receive status callbacks
@@ -371,8 +429,8 @@ export class Messages {
371
429
  * @param {boolean} [params.enableCompression=true] - Whether to enable image compression for the image attachments
372
430
  * @param {boolean} [params.filterLandlinesAndInactiveNumbers=false] - Whether to filter out landline and inactive numbers before sending
373
431
  * @param {File[]} [params.images] - The images to attach to the MMS message
374
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
375
- * @returns {Promise<Object>} - A promise that resolves to the response data from the server
432
+ * @param {RequestOptions} [params.options] - Additional options for the request
433
+ * @returns {Promise<SdkResponse<any>>} - A promise that resolves to the response data from the server
376
434
  */
377
435
  async sendMMS({
378
436
  senderPhoneNumber,
@@ -409,9 +467,9 @@ export class Messages {
409
467
  formData.append("statusCallbackUrl", statusCallbackUrl);
410
468
  }
411
469
 
412
- formData.append("enableShortlink", enableShortlink);
413
- formData.append("enableCompression", enableCompression);
414
- if (filterLandlinesAndInactiveNumbers) formData.append("filterLandlinesAndInactiveNumbers", filterLandlinesAndInactiveNumbers);
470
+ formData.append("enableShortlink", String(enableShortlink));
471
+ formData.append("enableCompression", String(enableCompression));
472
+ if (filterLandlinesAndInactiveNumbers) formData.append("filterLandlinesAndInactiveNumbers", String(filterLandlinesAndInactiveNumbers));
415
473
 
416
474
  return this.multipartClient(`/message/mms`, { method: "POST", body: formData, ...options });
417
475
  }
@@ -440,8 +498,8 @@ export class Messages {
440
498
  * @param {boolean} [params.enableCompression=true] - Whether to enable image compression for the image attachments
441
499
  * @param {boolean} [params.filterLandlinesAndInactiveNumbers=false] - Whether to filter out landline and inactive numbers before sending
442
500
  * @param {File[]} [params.images] - The images to attach to the MMS message
443
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
444
- * @returns {Promise<Object>} - A promise that resolves to the response data from the server
501
+ * @param {RequestOptions} [params.options] - Additional options for the request
502
+ * @returns {Promise<SdkResponse<any>>} - A promise that resolves to the response data from the server
445
503
  */
446
504
  async sendGroupMessage({
447
505
  senderPhoneNumber,
@@ -478,9 +536,9 @@ export class Messages {
478
536
  formData.append("statusCallbackUrl", statusCallbackUrl);
479
537
  }
480
538
 
481
- formData.append("enableShortlink", enableShortlink);
482
- formData.append("enableCompression", enableCompression);
483
- if (filterLandlinesAndInactiveNumbers) formData.append("filterLandlinesAndInactiveNumbers", filterLandlinesAndInactiveNumbers);
539
+ formData.append("enableShortlink", String(enableShortlink));
540
+ formData.append("enableCompression", String(enableCompression));
541
+ if (filterLandlinesAndInactiveNumbers) formData.append("filterLandlinesAndInactiveNumbers", String(filterLandlinesAndInactiveNumbers));
484
542
 
485
543
  return this.multipartClient(`/message/groupMessage`, { method: "POST", body: formData, ...options });
486
544
  }
@@ -491,8 +549,8 @@ export class Messages {
491
549
  * @roles api, admin, developer, billing, user
492
550
  * @param {Object} params - The parameters for looking up a carrier
493
551
  * @param {string} params.phoneNumber - The phone number to look up (10+ digits, no + prefix)
494
- * @param {import('../SignalHouseSDK').RequestOptions} [params.options] - Additional options for the request
495
- * @returns {Promise<Object>} - A promise that resolves to carrier information
552
+ * @param {RequestOptions} [params.options] - Additional options for the request
553
+ * @returns {Promise<SdkResponse<any>>} - A promise that resolves to carrier information
496
554
  */
497
555
  async carrierIdLookup({ phoneNumber, options = {} }) {
498
556
  this.client._require({ phoneNumber });