@zavudev/sdk 0.56.0 → 0.57.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/client.d.mts +0 -3
  3. package/client.d.mts.map +1 -1
  4. package/client.d.ts +0 -3
  5. package/client.d.ts.map +1 -1
  6. package/client.js +0 -3
  7. package/client.js.map +1 -1
  8. package/client.mjs +0 -3
  9. package/client.mjs.map +1 -1
  10. package/internal/qs/formats.d.mts +7 -0
  11. package/internal/qs/formats.d.mts.map +1 -0
  12. package/internal/qs/formats.d.ts +7 -0
  13. package/internal/qs/formats.d.ts.map +1 -0
  14. package/internal/qs/formats.js +13 -0
  15. package/internal/qs/formats.js.map +1 -0
  16. package/internal/qs/formats.mjs +9 -0
  17. package/internal/qs/formats.mjs.map +1 -0
  18. package/internal/qs/index.d.mts +10 -0
  19. package/internal/qs/index.d.mts.map +1 -0
  20. package/internal/qs/index.d.ts +10 -0
  21. package/internal/qs/index.d.ts.map +1 -0
  22. package/internal/qs/index.js +14 -0
  23. package/internal/qs/index.js.map +1 -0
  24. package/internal/qs/index.mjs +10 -0
  25. package/internal/qs/index.mjs.map +1 -0
  26. package/internal/qs/stringify.d.mts +3 -0
  27. package/internal/qs/stringify.d.mts.map +1 -0
  28. package/internal/qs/stringify.d.ts +3 -0
  29. package/internal/qs/stringify.d.ts.map +1 -0
  30. package/internal/qs/stringify.js +277 -0
  31. package/internal/qs/stringify.js.map +1 -0
  32. package/internal/qs/stringify.mjs +274 -0
  33. package/internal/qs/stringify.mjs.map +1 -0
  34. package/internal/qs/types.d.mts +57 -0
  35. package/internal/qs/types.d.mts.map +1 -0
  36. package/internal/qs/types.d.ts +57 -0
  37. package/internal/qs/types.d.ts.map +1 -0
  38. package/internal/qs/types.js +3 -0
  39. package/internal/qs/types.js.map +1 -0
  40. package/internal/qs/types.mjs +2 -0
  41. package/internal/qs/types.mjs.map +1 -0
  42. package/internal/qs/utils.d.mts +15 -0
  43. package/internal/qs/utils.d.mts.map +1 -0
  44. package/internal/qs/utils.d.ts +15 -0
  45. package/internal/qs/utils.d.ts.map +1 -0
  46. package/internal/qs/utils.js +230 -0
  47. package/internal/qs/utils.js.map +1 -0
  48. package/internal/qs/utils.mjs +217 -0
  49. package/internal/qs/utils.mjs.map +1 -0
  50. package/internal/tslib.js +17 -17
  51. package/internal/utils/query.d.mts +0 -3
  52. package/internal/utils/query.d.mts.map +1 -1
  53. package/internal/utils/query.d.ts +0 -3
  54. package/internal/utils/query.d.ts.map +1 -1
  55. package/internal/utils/query.js +3 -16
  56. package/internal/utils/query.js.map +1 -1
  57. package/internal/utils/query.mjs +2 -16
  58. package/internal/utils/query.mjs.map +1 -1
  59. package/package.json +1 -1
  60. package/resources/broadcasts/broadcasts.d.mts +16 -9
  61. package/resources/broadcasts/broadcasts.d.mts.map +1 -1
  62. package/resources/broadcasts/broadcasts.d.ts +16 -9
  63. package/resources/broadcasts/broadcasts.d.ts.map +1 -1
  64. package/resources/broadcasts/broadcasts.js +16 -9
  65. package/resources/broadcasts/broadcasts.js.map +1 -1
  66. package/resources/broadcasts/broadcasts.mjs +16 -9
  67. package/resources/broadcasts/broadcasts.mjs.map +1 -1
  68. package/resources/calls.d.mts +9 -0
  69. package/resources/calls.d.mts.map +1 -1
  70. package/resources/calls.d.ts +9 -0
  71. package/resources/calls.d.ts.map +1 -1
  72. package/resources/calls.js +9 -0
  73. package/resources/calls.js.map +1 -1
  74. package/resources/calls.mjs +9 -0
  75. package/resources/calls.mjs.map +1 -1
  76. package/resources/contacts/contacts.d.mts +32 -13
  77. package/resources/contacts/contacts.d.mts.map +1 -1
  78. package/resources/contacts/contacts.d.ts +32 -13
  79. package/resources/contacts/contacts.d.ts.map +1 -1
  80. package/resources/contacts/contacts.js +0 -14
  81. package/resources/contacts/contacts.js.map +1 -1
  82. package/resources/contacts/contacts.mjs +0 -14
  83. package/resources/contacts/contacts.mjs.map +1 -1
  84. package/resources/messages.d.mts +35 -0
  85. package/resources/messages.d.mts.map +1 -1
  86. package/resources/messages.d.ts +35 -0
  87. package/resources/messages.d.ts.map +1 -1
  88. package/resources/messages.js +30 -0
  89. package/resources/messages.js.map +1 -1
  90. package/resources/messages.mjs +30 -0
  91. package/resources/messages.mjs.map +1 -1
  92. package/resources/number-10dlc/brands.d.mts +10 -5
  93. package/resources/number-10dlc/brands.d.mts.map +1 -1
  94. package/resources/number-10dlc/brands.d.ts +10 -5
  95. package/resources/number-10dlc/brands.d.ts.map +1 -1
  96. package/resources/number-10dlc/brands.js +10 -5
  97. package/resources/number-10dlc/brands.js.map +1 -1
  98. package/resources/number-10dlc/brands.mjs +10 -5
  99. package/resources/number-10dlc/brands.mjs.map +1 -1
  100. package/resources/number-10dlc/campaigns/campaigns.d.mts +8 -7
  101. package/resources/number-10dlc/campaigns/campaigns.d.mts.map +1 -1
  102. package/resources/number-10dlc/campaigns/campaigns.d.ts +8 -7
  103. package/resources/number-10dlc/campaigns/campaigns.d.ts.map +1 -1
  104. package/resources/number-10dlc/campaigns/campaigns.js +8 -7
  105. package/resources/number-10dlc/campaigns/campaigns.js.map +1 -1
  106. package/resources/number-10dlc/campaigns/campaigns.mjs +8 -7
  107. package/resources/number-10dlc/campaigns/campaigns.mjs.map +1 -1
  108. package/resources/phone-numbers.d.mts +6 -1
  109. package/resources/phone-numbers.d.mts.map +1 -1
  110. package/resources/phone-numbers.d.ts +6 -1
  111. package/resources/phone-numbers.d.ts.map +1 -1
  112. package/src/client.ts +0 -3
  113. package/src/internal/qs/LICENSE.md +13 -0
  114. package/src/internal/qs/README.md +3 -0
  115. package/src/internal/qs/formats.ts +10 -0
  116. package/src/internal/qs/index.ts +13 -0
  117. package/src/internal/qs/stringify.ts +385 -0
  118. package/src/internal/qs/types.ts +71 -0
  119. package/src/internal/qs/utils.ts +265 -0
  120. package/src/internal/utils/query.ts +2 -18
  121. package/src/resources/broadcasts/broadcasts.ts +16 -9
  122. package/src/resources/calls.ts +9 -0
  123. package/src/resources/contacts/contacts.ts +35 -20
  124. package/src/resources/messages.ts +36 -0
  125. package/src/resources/number-10dlc/brands.ts +10 -5
  126. package/src/resources/number-10dlc/campaigns/campaigns.ts +8 -7
  127. package/src/resources/phone-numbers.ts +6 -1
  128. package/src/version.ts +1 -1
  129. package/version.d.mts +1 -1
  130. package/version.d.ts +1 -1
  131. package/version.js +1 -1
  132. package/version.mjs +1 -1
@@ -0,0 +1,265 @@
1
+ import { RFC1738 } from './formats';
2
+ import type { DefaultEncoder, Format } from './types';
3
+ import { isArray } from '../utils/values';
4
+
5
+ export let has = (obj: object, key: PropertyKey): boolean => (
6
+ (has = (Object as any).hasOwn ?? Function.prototype.call.bind(Object.prototype.hasOwnProperty)),
7
+ has(obj, key)
8
+ );
9
+
10
+ const hex_table = /* @__PURE__ */ (() => {
11
+ const array = [];
12
+ for (let i = 0; i < 256; ++i) {
13
+ array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase());
14
+ }
15
+
16
+ return array;
17
+ })();
18
+
19
+ function compact_queue<T extends Record<string, any>>(queue: Array<{ obj: T; prop: string }>) {
20
+ while (queue.length > 1) {
21
+ const item = queue.pop();
22
+ if (!item) continue;
23
+
24
+ const obj = item.obj[item.prop];
25
+
26
+ if (isArray(obj)) {
27
+ const compacted: unknown[] = [];
28
+
29
+ for (let j = 0; j < obj.length; ++j) {
30
+ if (typeof obj[j] !== 'undefined') {
31
+ compacted.push(obj[j]);
32
+ }
33
+ }
34
+
35
+ // @ts-ignore
36
+ item.obj[item.prop] = compacted;
37
+ }
38
+ }
39
+ }
40
+
41
+ function array_to_object(source: any[], options: { plainObjects: boolean }) {
42
+ const obj = options && options.plainObjects ? Object.create(null) : {};
43
+ for (let i = 0; i < source.length; ++i) {
44
+ if (typeof source[i] !== 'undefined') {
45
+ obj[i] = source[i];
46
+ }
47
+ }
48
+
49
+ return obj;
50
+ }
51
+
52
+ export function merge(
53
+ target: any,
54
+ source: any,
55
+ options: { plainObjects?: boolean; allowPrototypes?: boolean } = {},
56
+ ) {
57
+ if (!source) {
58
+ return target;
59
+ }
60
+
61
+ if (typeof source !== 'object') {
62
+ if (isArray(target)) {
63
+ target.push(source);
64
+ } else if (target && typeof target === 'object') {
65
+ if ((options && (options.plainObjects || options.allowPrototypes)) || !has(Object.prototype, source)) {
66
+ target[source] = true;
67
+ }
68
+ } else {
69
+ return [target, source];
70
+ }
71
+
72
+ return target;
73
+ }
74
+
75
+ if (!target || typeof target !== 'object') {
76
+ return [target].concat(source);
77
+ }
78
+
79
+ let mergeTarget = target;
80
+ if (isArray(target) && !isArray(source)) {
81
+ // @ts-ignore
82
+ mergeTarget = array_to_object(target, options);
83
+ }
84
+
85
+ if (isArray(target) && isArray(source)) {
86
+ source.forEach(function (item, i) {
87
+ if (has(target, i)) {
88
+ const targetItem = target[i];
89
+ if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') {
90
+ target[i] = merge(targetItem, item, options);
91
+ } else {
92
+ target.push(item);
93
+ }
94
+ } else {
95
+ target[i] = item;
96
+ }
97
+ });
98
+ return target;
99
+ }
100
+
101
+ return Object.keys(source).reduce(function (acc, key) {
102
+ const value = source[key];
103
+
104
+ if (has(acc, key)) {
105
+ acc[key] = merge(acc[key], value, options);
106
+ } else {
107
+ acc[key] = value;
108
+ }
109
+ return acc;
110
+ }, mergeTarget);
111
+ }
112
+
113
+ export function assign_single_source(target: any, source: any) {
114
+ return Object.keys(source).reduce(function (acc, key) {
115
+ acc[key] = source[key];
116
+ return acc;
117
+ }, target);
118
+ }
119
+
120
+ export function decode(str: string, _: any, charset: string) {
121
+ const strWithoutPlus = str.replace(/\+/g, ' ');
122
+ if (charset === 'iso-8859-1') {
123
+ // unescape never throws, no try...catch needed:
124
+ return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape);
125
+ }
126
+ // utf-8
127
+ try {
128
+ return decodeURIComponent(strWithoutPlus);
129
+ } catch (e) {
130
+ return strWithoutPlus;
131
+ }
132
+ }
133
+
134
+ const limit = 1024;
135
+
136
+ export const encode: (
137
+ str: any,
138
+ defaultEncoder: DefaultEncoder,
139
+ charset: string,
140
+ type: 'key' | 'value',
141
+ format: Format,
142
+ ) => string = (str, _defaultEncoder, charset, _kind, format: Format) => {
143
+ // This code was originally written by Brian White for the io.js core querystring library.
144
+ // It has been adapted here for stricter adherence to RFC 3986
145
+ if (str.length === 0) {
146
+ return str;
147
+ }
148
+
149
+ let string = str;
150
+ if (typeof str === 'symbol') {
151
+ string = Symbol.prototype.toString.call(str);
152
+ } else if (typeof str !== 'string') {
153
+ string = String(str);
154
+ }
155
+
156
+ if (charset === 'iso-8859-1') {
157
+ return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) {
158
+ return '%26%23' + parseInt($0.slice(2), 16) + '%3B';
159
+ });
160
+ }
161
+
162
+ let out = '';
163
+ for (let j = 0; j < string.length; j += limit) {
164
+ const segment = string.length >= limit ? string.slice(j, j + limit) : string;
165
+ const arr = [];
166
+
167
+ for (let i = 0; i < segment.length; ++i) {
168
+ let c = segment.charCodeAt(i);
169
+ if (
170
+ c === 0x2d || // -
171
+ c === 0x2e || // .
172
+ c === 0x5f || // _
173
+ c === 0x7e || // ~
174
+ (c >= 0x30 && c <= 0x39) || // 0-9
175
+ (c >= 0x41 && c <= 0x5a) || // a-z
176
+ (c >= 0x61 && c <= 0x7a) || // A-Z
177
+ (format === RFC1738 && (c === 0x28 || c === 0x29)) // ( )
178
+ ) {
179
+ arr[arr.length] = segment.charAt(i);
180
+ continue;
181
+ }
182
+
183
+ if (c < 0x80) {
184
+ arr[arr.length] = hex_table[c];
185
+ continue;
186
+ }
187
+
188
+ if (c < 0x800) {
189
+ arr[arr.length] = hex_table[0xc0 | (c >> 6)]! + hex_table[0x80 | (c & 0x3f)];
190
+ continue;
191
+ }
192
+
193
+ if (c < 0xd800 || c >= 0xe000) {
194
+ arr[arr.length] =
195
+ hex_table[0xe0 | (c >> 12)]! + hex_table[0x80 | ((c >> 6) & 0x3f)] + hex_table[0x80 | (c & 0x3f)];
196
+ continue;
197
+ }
198
+
199
+ i += 1;
200
+ c = 0x10000 + (((c & 0x3ff) << 10) | (segment.charCodeAt(i) & 0x3ff));
201
+
202
+ arr[arr.length] =
203
+ hex_table[0xf0 | (c >> 18)]! +
204
+ hex_table[0x80 | ((c >> 12) & 0x3f)] +
205
+ hex_table[0x80 | ((c >> 6) & 0x3f)] +
206
+ hex_table[0x80 | (c & 0x3f)];
207
+ }
208
+
209
+ out += arr.join('');
210
+ }
211
+
212
+ return out;
213
+ };
214
+
215
+ export function compact(value: any) {
216
+ const queue = [{ obj: { o: value }, prop: 'o' }];
217
+ const refs = [];
218
+
219
+ for (let i = 0; i < queue.length; ++i) {
220
+ const item = queue[i];
221
+ // @ts-ignore
222
+ const obj = item.obj[item.prop];
223
+
224
+ const keys = Object.keys(obj);
225
+ for (let j = 0; j < keys.length; ++j) {
226
+ const key = keys[j]!;
227
+ const val = obj[key];
228
+ if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) {
229
+ queue.push({ obj: obj, prop: key });
230
+ refs.push(val);
231
+ }
232
+ }
233
+ }
234
+
235
+ compact_queue(queue);
236
+
237
+ return value;
238
+ }
239
+
240
+ export function is_regexp(obj: any) {
241
+ return Object.prototype.toString.call(obj) === '[object RegExp]';
242
+ }
243
+
244
+ export function is_buffer(obj: any) {
245
+ if (!obj || typeof obj !== 'object') {
246
+ return false;
247
+ }
248
+
249
+ return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj));
250
+ }
251
+
252
+ export function combine(a: any, b: any) {
253
+ return [].concat(a, b);
254
+ }
255
+
256
+ export function maybe_map<T>(val: T[], fn: (v: T) => T) {
257
+ if (isArray(val)) {
258
+ const mapped = [];
259
+ for (let i = 0; i < val.length; i += 1) {
260
+ mapped.push(fn(val[i]!));
261
+ }
262
+ return mapped;
263
+ }
264
+ return fn(val);
265
+ }
@@ -1,23 +1,7 @@
1
1
  // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2
2
 
3
- import { ZavudevError } from '../../core/error';
3
+ import * as qs from '../qs/stringify';
4
4
 
5
- /**
6
- * Basic re-implementation of `qs.stringify` for primitive types.
7
- */
8
5
  export function stringifyQuery(query: object | Record<string, unknown>) {
9
- return Object.entries(query)
10
- .filter(([_, value]) => typeof value !== 'undefined')
11
- .map(([key, value]) => {
12
- if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
13
- return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
14
- }
15
- if (value === null) {
16
- return `${encodeURIComponent(key)}=`;
17
- }
18
- throw new ZavudevError(
19
- `Cannot stringify type ${typeof value}; Expected string, number, boolean, or null. If you need to pass nested query parameters, you can manually encode them, e.g. { query: { 'foo[key1]': value1, 'foo[key2]': value2 } }, and please open a GitHub issue requesting better support for your use case.`,
20
- );
21
- })
22
- .join('&');
6
+ return qs.stringify(query, { arrayFormat: 'comma' });
23
7
  }
@@ -182,15 +182,22 @@ export class Broadcasts extends APIResource {
182
182
  /**
183
183
  * Start sending the broadcast immediately or schedule for later.
184
184
  *
185
- * **Verification is required to send, except on WhatsApp.** On every channel other
186
- * than `whatsapp`, the team must have completed both identity verification (KYC)
187
- * and business verification (KYB); passing one is not enough. A `whatsapp`
188
- * broadcast requires neither: it can only be built on a template, and Meta vets
189
- * the business and the content when it approves that template, so an unapproved
190
- * template is refused instead. `smart` is not exempt — it can route a contact to
191
- * SMS or email. Drafts can be created, edited and kept without any check. Every
192
- * send path — dashboard, API and CLI alike — enforces the same rule, returning
193
- * `403` with code `kyc_required` or `kyb_required` for whichever is outstanding.
185
+ * **The account must be past the unverified level to send, except on WhatsApp.**
186
+ * An account that has verified nothing is refused with `403` and code
187
+ * `kyc_required` on every channel other than `whatsapp`. Any one of these lifts
188
+ * it: identity verification (KYC), a saved payment method, a settled deposit, or a
189
+ * paid plan. Business verification (KYB) is not required to broadcast; it gates
190
+ * 10DLC registration only. A `whatsapp` broadcast is exempt: it can only be built
191
+ * on a template, and Meta vets the business and the content when it approves that
192
+ * template, so an unapproved template is refused instead. `smart` is not exempt,
193
+ * since it can route a contact to SMS or email. Drafts can be created, edited and
194
+ * kept without any check. Every send path (dashboard, API and CLI) enforces the
195
+ * same rule.
196
+ *
197
+ * **Daily ceilings apply per recipient.** Each message a broadcast sends counts
198
+ * against the channel's daily ceiling (see `POST /v1/messages`). Once the ceiling
199
+ * is reached, the remaining recipients are marked `failed` with `errorCode`
200
+ * `DAILY_LIMIT_EXCEEDED`; they are not retried the next day.
194
201
  *
195
202
  * **Review depends on the channel, and cannot be bypassed.** A draft is submitted
196
203
  * to automated content review here; it does not go straight out. A WhatsApp
@@ -16,6 +16,15 @@ export class Calls extends APIResource {
16
16
  * **Requirements:**
17
17
  *
18
18
  * - The Voice Agents feature must be enabled for your team (otherwise `403`).
19
+ * - An account that has verified nothing may only call the phone numbers the
20
+ * project has verified (`403` with code `destination_not_verified`, and
21
+ * `details.verifiedNumbers` lists them), and at most 5 calls a day (`429` with
22
+ * code `daily_limit_exceeded`). A number is verified from the dashboard's
23
+ * Sandbox screen by sending the pre-filled WhatsApp message from that phone; the
24
+ * same verification covers SMS and calls. Verify your identity, add a payment
25
+ * method, settle a deposit or subscribe to call any destination. That raises the
26
+ * ceiling to 50 calls a day on Free; paid plans have no daily call ceiling. Full
27
+ * reference: https://docs.zavu.dev/concepts/sending-limits
19
28
  * - The sender's agent must have `voice.enabled` set to `true`.
20
29
  * - Not available with test-mode API keys.
21
30
  *
@@ -104,21 +104,6 @@ export class Contacts extends APIResource {
104
104
  });
105
105
  }
106
106
 
107
- /**
108
- * Dismiss the merge suggestion for a contact.
109
- *
110
- * @example
111
- * ```ts
112
- * await client.contacts.dismissMergeSuggestion('contactId');
113
- * ```
114
- */
115
- dismissMergeSuggestion(contactID: string, options?: RequestOptions): APIPromise<void> {
116
- return this._client.delete(path`/v1/contacts/${contactID}/merge-suggestion`, {
117
- ...options,
118
- headers: buildHeaders([{ Accept: '*/*' }, options?.headers]),
119
- });
120
- }
121
-
122
107
  /**
123
108
  * Merge a source contact into this contact. All channels from the source contact
124
109
  * will be moved to the target contact, and the source contact will be marked as
@@ -206,11 +191,6 @@ export interface Contact {
206
191
  */
207
192
  profileName?: string | null;
208
193
 
209
- /**
210
- * ID of a contact suggested for merging.
211
- */
212
- suggestedMergeWith?: string;
213
-
214
194
  updatedAt?: string;
215
195
  }
216
196
 
@@ -339,11 +319,46 @@ export interface ContactUpdateParams {
339
319
  */
340
320
  defaultChannel?: 'sms' | 'whatsapp' | 'telegram' | 'email' | 'instagram' | 'messenger' | 'voice' | null;
341
321
 
322
+ /**
323
+ * Human-readable name for this contact. Set to null to clear it and fall back to
324
+ * the contact's identifier. Contacts created automatically from an inbound message
325
+ * have no display name until you set one.
326
+ */
327
+ displayName?: string | null;
328
+
342
329
  metadata?: { [key: string]: string };
343
330
  }
344
331
 
345
332
  export interface ContactListParams extends CursorParams {
333
+ /**
334
+ * Exact match on the contact's primary phone number, in E.164.
335
+ */
346
336
  phoneNumber?: string;
337
+
338
+ /**
339
+ * Free-text match over the contact's name (`displayName` and the WhatsApp profile
340
+ * name), phone numbers and email addresses. Case- and accent-insensitive. A phone
341
+ * number matches on a trailing fragment too, so `5551234` finds `+14155551234`.
342
+ *
343
+ * Contacts created automatically from an inbound message have no `displayName` —
344
+ * they are matched by their identifier until you set one with
345
+ * `PATCH /v1/contacts/{contactId}`.
346
+ *
347
+ * Results come back in relevance order rather than newest-first. `cursor` is
348
+ * opaque in both modes; pass back exactly what the previous response returned, and
349
+ * start a new pagination run when the search term changes.
350
+ */
351
+ search?: string;
352
+
353
+ /**
354
+ * Tag name. Repeatable: `?tag=vip&tag=chile` returns contacts carrying **every**
355
+ * tag given, not any of them — the same rule the dashboard filter applies.
356
+ *
357
+ * Tags are matched by name, case-insensitively. An unknown tag returns 400 rather
358
+ * than being ignored, because a typo that silently matched every contact would be
359
+ * a worse answer than an error.
360
+ */
361
+ tag?: Array<string>;
347
362
  }
348
363
 
349
364
  export interface ContactMergeParams {
@@ -115,6 +115,36 @@ export class Messages extends APIResource {
115
115
  * 100/day. Teams on earlier plans keep their original email quotas instead
116
116
  * - SMS and voice are billed per message from your balance on every plan
117
117
  *
118
+ * **Account verification and daily limits:**
119
+ *
120
+ * - A brand-new account can send on every channel immediately, but `sms`,
121
+ * `sms_oneway` and `voice` reach only the phone numbers the project has
122
+ * verified. Sending elsewhere returns `403` with code
123
+ * `destination_not_verified`; `details.verifiedNumbers` lists the numbers that
124
+ * are reachable. A number is verified from the dashboard's Sandbox screen:
125
+ * generate a code and send the pre-filled WhatsApp message from that phone to
126
+ * Zavu's sandbox number. One verification covers WhatsApp, SMS and calls, up to
127
+ * 5 numbers per project. To send to any destination, do any one of these: verify
128
+ * your identity, add a payment method, settle a deposit, or subscribe to a paid
129
+ * plan. Business verification (KYB) is never required to send
130
+ * - Daily ceilings apply per channel group and rise with verification. An account
131
+ * that has verified nothing: 25/day across `sms` + `sms_oneway`, 5/day for
132
+ * `voice`, 100/day across WhatsApp, Telegram, Instagram and Messenger combined.
133
+ * Past that floor: 200/day for SMS, or 10,000/day once identity or business
134
+ * verification is approved (or a higher limit agreed for your account); 50/day
135
+ * voice and 250/day conversational on Free. **Paid plans have no voice or
136
+ * conversational daily ceiling.** Over a ceiling, sends return `429` with code
137
+ * `daily_limit_exceeded` and `details.limit`; the count resets at 00:00 UTC
138
+ * - The daily ceiling never reduces the monthly allowance: 100/day on the
139
+ * conversational group still reaches the 2,000 monthly A2P messages Free
140
+ * includes
141
+ * - Email needs no account verification here: a sender with a verified domain
142
+ * sends from day one, within the plan quota (100/day and 3,000/month on Free).
143
+ * Over the daily quota it returns `429` with code `daily_limit_exceeded`. Email
144
+ * broadcasts are the exception: they need the account past the unverified level,
145
+ * see `POST /v1/broadcasts/{broadcastId}/send`
146
+ * - Full reference: https://docs.zavu.dev/concepts/sending-limits
147
+ *
118
148
  * **Email recipient pre-flight:** Email messages are validated automatically
119
149
  * before dispatch. Sends that would be a guaranteed hard bounce are failed instead
120
150
  * of sent, protecting your bounce rate: the message transitions to `failed`
@@ -202,6 +232,12 @@ export interface Message {
202
232
 
203
233
  createdAt: string;
204
234
 
235
+ /**
236
+ * Who sent the message. Needed to render a thread: `status` cannot tell the two
237
+ * apart, because an inbound message is also stored as `delivered`.
238
+ */
239
+ direction: 'inbound' | 'outbound';
240
+
205
241
  /**
206
242
  * Type of message. Non-text types are supported by WhatsApp and Telegram (varies
207
243
  * by type).
@@ -115,11 +115,16 @@ export class Brands extends APIResource {
115
115
 
116
116
  /**
117
117
  * Submit a draft brand to The Campaign Registry (TCR) for vetting. The brand must
118
- * be in draft status. TCR's one-time $4 brand registration fee is charged from
119
- * your balance at submission (passed through at cost) and refunded if the carrier
120
- * rejects the registration. A team that already paid this fee through the
121
- * compliance flow is not charged again. Campaign registration is billed separately
122
- * when a campaign is submitted.
118
+ * be in draft status, and the team must have an approved Business Verification
119
+ * (KYB) — carriers register a brand against a vetted legal entity, so submitting
120
+ * without one returns `403` with code `kyb_required`.
121
+ *
122
+ * TCR's one-time $4 brand registration fee is charged from your balance at
123
+ * submission (passed through at cost) and refunded if the carrier rejects the
124
+ * registration. The fee is per BRAND: a team registering a second legal entity
125
+ * pays it again. A brand already paid for through the compliance flow is not
126
+ * charged twice. Campaign registration is billed separately when a campaign is
127
+ * submitted.
123
128
  *
124
129
  * @example
125
130
  * ```ts
@@ -116,13 +116,14 @@ export class Campaigns extends APIResource {
116
116
  }
117
117
 
118
118
  /**
119
- * Submit a draft campaign for carrier review. The campaign must be in draft status
120
- * and its brand must be verified. TCR's one-time registration fee is charged from
121
- * your balance at submission ($15 for standard use cases, $2 for LOW_VOLUME),
122
- * passed through at cost and refunded if the carrier rejects it. Once approved,
123
- * the campaign's monthly TCR fee ($10 standard, $2 LOW_VOLUME) is charged from
124
- * your balance while the campaign is active — see registrationCostCents and
125
- * monthlyFeeCents on the campaign object.
119
+ * The team must have an approved Business Verification (KYB): submitting without
120
+ * one returns `403` with code `kyb_required`. Submit a draft campaign for carrier
121
+ * review. The campaign must be in draft status and its brand must be verified.
122
+ * TCR's one-time registration fee is charged from your balance at submission ($15
123
+ * for standard use cases, $2 for LOW_VOLUME), passed through at cost and refunded
124
+ * if the carrier rejects it. Once approved, the campaign's monthly TCR fee ($10
125
+ * standard, $2 LOW_VOLUME) is charged from your balance while the campaign is
126
+ * active — see registrationCostCents and monthlyFeeCents on the campaign object.
126
127
  *
127
128
  * @example
128
129
  * ```ts
@@ -229,7 +229,12 @@ export interface PhoneNumberPricing {
229
229
 
230
230
  export type PhoneNumberStatus = 'active' | 'suspended' | 'pending';
231
231
 
232
- export type PhoneNumberType = 'local' | 'national' | 'tollFree';
232
+ /**
233
+ * Type of phone number. `mobile` is stocked in countries where no geographic
234
+ * (`local`) or non-geographic (`national`) inventory exists, and in several
235
+ * markets it is the only type that can receive SMS.
236
+ */
237
+ export type PhoneNumberType = 'local' | 'national' | 'tollFree' | 'mobile';
233
238
 
234
239
  /**
235
240
  * A group of requirements for a specific country/phone type combination.
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const VERSION = '0.56.0'; // x-release-please-version
1
+ export const VERSION = '0.57.0'; // x-release-please-version
package/version.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.56.0";
1
+ export declare const VERSION = "0.57.0";
2
2
  //# sourceMappingURL=version.d.mts.map
package/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export declare const VERSION = "0.56.0";
1
+ export declare const VERSION = "0.57.0";
2
2
  //# sourceMappingURL=version.d.ts.map
package/version.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VERSION = void 0;
4
- exports.VERSION = '0.56.0'; // x-release-please-version
4
+ exports.VERSION = '0.57.0'; // x-release-please-version
5
5
  //# sourceMappingURL=version.js.map
package/version.mjs CHANGED
@@ -1,2 +1,2 @@
1
- export const VERSION = '0.56.0'; // x-release-please-version
1
+ export const VERSION = '0.57.0'; // x-release-please-version
2
2
  //# sourceMappingURL=version.mjs.map