@proveanything/smartlinks 1.13.6 → 1.13.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -75,13 +75,13 @@ initializeApi({
75
75
  List public collections and fetch products:
76
76
 
77
77
  ```ts
78
- import { collection, product } from '@proveanything/smartlinks'
78
+ import { collection, products } from '@proveanything/smartlinks'
79
79
 
80
80
  const collections = await collection.list(false) // public endpoint
81
81
  const first = collections[0]
82
82
  if (first) {
83
- const products = await product.list(first.id, false) // public endpoint
84
- console.log('First product:', products[0])
83
+ const items = await products.list(first.id, false) // public endpoint
84
+ console.log('First product:', items[0])
85
85
  }
86
86
  ```
87
87
 
@@ -90,28 +90,51 @@ if (first) {
90
90
  **Public storefront or portal experience**
91
91
 
92
92
  ```ts
93
- import { initializeApi, collection, product } from '@proveanything/smartlinks'
93
+ import { initializeApi, collection, products } from '@proveanything/smartlinks'
94
94
 
95
95
  initializeApi({ baseURL: 'https://smartlinks.app/api/v1' })
96
96
 
97
97
  const collections = await collection.list(false)
98
- const products = await product.list('collectionId', false)
98
+ const items = await products.list('collectionId', false)
99
99
  ```
100
100
 
101
101
  **Server-side admin scripts or back office tools**
102
102
 
103
103
  ```ts
104
- import { initializeApi, product } from '@proveanything/smartlinks'
104
+ import { initializeApi, products } from '@proveanything/smartlinks'
105
105
 
106
106
  initializeApi({
107
107
  baseURL: 'https://smartlinks.app/api/v1',
108
108
  apiKey: process.env.SMARTLINKS_API_KEY,
109
109
  })
110
110
 
111
- const created = await product.create('collectionId', { name: 'New product' })
111
+ const created = await products.create('collectionId', { name: 'New product' })
112
112
  console.log(created.id)
113
113
  ```
114
114
 
115
+ ### Product API migration: use products (plural)
116
+
117
+ The SDK keeps `product` (singular) for backward compatibility, but it is deprecated.
118
+ For all new integrations, use `products` (plural).
119
+
120
+ ```ts
121
+ // Preferred
122
+ import { products } from '@proveanything/smartlinks'
123
+
124
+ await products.get(collectionId, productId, false)
125
+ await products.list(collectionId, false)
126
+ await products.query(collectionId, { query: { search: 'cabernet' } })
127
+ ```
128
+
129
+ Quick mapping:
130
+
131
+ - `product.get` -> `products.get`
132
+ - `product.list` -> `products.list`
133
+ - `product.create` -> `products.create`
134
+ - `product.update` -> `products.update`
135
+ - `product.remove` -> `products.remove`
136
+ - `product.find` / `product.publicFind` -> `products.query` / `products.get`
137
+
115
138
  **AI-powered assistant or setup flow**
116
139
 
117
140
  ```ts
@@ -181,10 +204,10 @@ The SDK automatically normalizes various server error response formats into a co
181
204
  // { error: "..." }
182
205
 
183
206
  // All are normalized to SmartlinksApiError with consistent access:
184
- import { SmartlinksApiError, product } from '@proveanything/smartlinks'
207
+ import { SmartlinksApiError, products } from '@proveanything/smartlinks'
185
208
 
186
209
  try {
187
- const item = await product.get('collectionId', 'productId', false)
210
+ const item = await products.get('collectionId', 'productId', false)
188
211
  } catch (error) {
189
212
  if (error instanceof SmartlinksApiError) {
190
213
  console.error({
@@ -286,15 +309,15 @@ For complete documentation, see [docs/utils.md](docs/utils.md).
286
309
  ### Products
287
310
 
288
311
  ```ts
289
- import { product } from '@proveanything/smartlinks'
312
+ import { products } from '@proveanything/smartlinks'
290
313
 
291
314
  // Public fetch
292
- const item = await product.get('collectionId', 'productId', false)
315
+ const item = await products.get('collectionId', 'productId', false)
293
316
 
294
317
  // Admin create/update/delete (requires auth)
295
- await product.create('collectionId', { name: 'New product' })
296
- await product.update('collectionId', 'productId', { description: 'Updated' })
297
- await product.remove('collectionId', 'productId')
318
+ await products.create('collectionId', { name: 'New product' })
319
+ await products.update('collectionId', 'productId', { description: 'Updated' })
320
+ await products.remove('collectionId', 'productId')
298
321
  ```
299
322
 
300
323
  ### Assets
package/dist/README.md CHANGED
@@ -38,16 +38,21 @@ initializeApi({
38
38
  List public collections and fetch products:
39
39
 
40
40
  ```ts
41
- import { collection, product } from '@proveanything/smartlinks'
41
+ import { collection, products } from '@proveanything/smartlinks'
42
42
 
43
43
  const collections = await collection.list(false) // public endpoint
44
44
  const first = collections[0]
45
45
  if (first) {
46
- const products = await product.list(first.id, false) // public endpoint
47
- console.log('First product:', products[0])
46
+ const items = await products.list(first.id, false) // public endpoint
47
+ console.log('First product:', items[0])
48
48
  }
49
49
  ```
50
50
 
51
+ ### Product API migration: use products (plural)
52
+
53
+ The SDK keeps `product` (singular) for backward compatibility, but it is deprecated.
54
+ For all new integrations, use `products` (plural).
55
+
51
56
  ## Authentication
52
57
 
53
58
  Use the built-in helpers to log in and verify tokens. After a successful login, the SDK stores the bearer token for subsequent calls.
@@ -100,10 +105,10 @@ The SDK automatically normalizes various server error response formats into a co
100
105
  // { error: "..." }
101
106
 
102
107
  // All are normalized to SmartlinksApiError with consistent access:
103
- import { SmartlinksApiError, product } from '@proveanything/smartlinks'
108
+ import { SmartlinksApiError, products } from '@proveanything/smartlinks'
104
109
 
105
110
  try {
106
- const item = await product.get('collectionId', 'productId', false)
111
+ const item = await products.get('collectionId', 'productId', false)
107
112
  } catch (error) {
108
113
  if (error instanceof SmartlinksApiError) {
109
114
  console.error({
@@ -160,15 +165,15 @@ For comprehensive error handling examples and migration guidance, see:
160
165
  ### Products
161
166
 
162
167
  ```ts
163
- import { product } from '@proveanything/smartlinks'
168
+ import { products } from '@proveanything/smartlinks'
164
169
 
165
170
  // Public fetch
166
- const item = await product.get('collectionId', 'productId', false)
171
+ const item = await products.get('collectionId', 'productId', false)
167
172
 
168
173
  // Admin create/update/delete (requires auth)
169
- await product.create('collectionId', { name: 'New product' })
170
- await product.update('collectionId', 'productId', { description: 'Updated' })
171
- await product.remove('collectionId', 'productId')
174
+ await products.create('collectionId', { name: 'New product' })
175
+ await products.update('collectionId', 'productId', { description: 'Updated' })
176
+ await products.remove('collectionId', 'productId')
172
177
  ```
173
178
 
174
179
  ### Assets
@@ -276,7 +276,7 @@ function queueAnalytics(path, body, options) {
276
276
  const preferBeacon = (options === null || options === void 0 ? void 0 : options.preferBeacon) !== false;
277
277
  if (typeof navigator !== 'undefined' && typeof navigator.sendBeacon === 'function' && preferBeacon) {
278
278
  try {
279
- const blob = new Blob([payload], { type: 'application/json' });
279
+ const blob = new Blob([payload], { type: 'text/plain;charset=UTF-8' });
280
280
  const queued = navigator.sendBeacon(url, blob);
281
281
  if (queued)
282
282
  return { queued: true, transport: 'beacon' };
@@ -287,9 +287,12 @@ function queueAnalytics(path, body, options) {
287
287
  if (typeof fetch === 'function') {
288
288
  void fetch(url, {
289
289
  method: 'POST',
290
- headers: Object.assign({ 'Content-Type': 'application/json' }, headers),
291
- body: payload,
290
+ mode: 'cors',
292
291
  keepalive: true,
292
+ headers: {
293
+ 'Content-Type': 'text/plain;charset=UTF-8',
294
+ },
295
+ body: payload,
293
296
  }).catch(() => { });
294
297
  return { queued: true, transport: 'fetch' };
295
298
  }
@@ -107,6 +107,9 @@ export declare namespace app {
107
107
  /**
108
108
  * List records with optional query parameters
109
109
  * GET /records
110
+ *
111
+ * Public/owner callers only receive records with `status: "active"`.
112
+ * Admin callers can query all statuses (for example `draft`/`archived`).
110
113
  */
111
114
  function list(collectionId: string, appId: string, params?: RecordListQueryParams, admin?: boolean): Promise<PaginatedResponse<AppRecord>>;
112
115
  /**
@@ -196,7 +199,7 @@ export declare namespace app {
196
199
  * ordered by specificity descending (most specific first).
197
200
  * POST /records/match
198
201
  *
199
- * @param admin - false for public endpoint (visibility-filtered), true for admin
202
+ * @param admin - false for public endpoint (visibility-filtered, active-only), true for admin
200
203
  *
201
204
  * @example
202
205
  * ```ts
@@ -245,7 +248,7 @@ export declare namespace app {
245
248
  * deduplicated and sorted by specificity descending.
246
249
  * POST /records/resolve-all
247
250
  *
248
- * @param admin - false for public (visibility-filtered), true for admin (all records)
251
+ * @param admin - false for public (visibility-filtered, active-only), true for admin (all statuses)
249
252
  */
250
253
  function resolveAll(collectionId: string, appId: string, input: ResolveAllParams, admin?: boolean): Promise<ResolveAllResult>;
251
254
  /**
@@ -203,6 +203,9 @@ export var app;
203
203
  /**
204
204
  * List records with optional query parameters
205
205
  * GET /records
206
+ *
207
+ * Public/owner callers only receive records with `status: "active"`.
208
+ * Admin callers can query all statuses (for example `draft`/`archived`).
206
209
  */
207
210
  async function list(collectionId, appId, params, admin = false) {
208
211
  const path = basePath(collectionId, appId, admin);
@@ -323,7 +326,7 @@ export var app;
323
326
  * ordered by specificity descending (most specific first).
324
327
  * POST /records/match
325
328
  *
326
- * @param admin - false for public endpoint (visibility-filtered), true for admin
329
+ * @param admin - false for public endpoint (visibility-filtered, active-only), true for admin
327
330
  *
328
331
  * @example
329
332
  * ```ts
@@ -384,7 +387,7 @@ export var app;
384
387
  * deduplicated and sorted by specificity descending.
385
388
  * POST /records/resolve-all
386
389
  *
387
- * @param admin - false for public (visibility-filtered), true for admin (all records)
390
+ * @param admin - false for public (visibility-filtered, active-only), true for admin (all statuses)
388
391
  */
389
392
  async function resolveAll(collectionId, appId, input, admin = false) {
390
393
  const path = `${basePath(collectionId, appId, admin)}/resolve-all`;
@@ -1,4 +1,4 @@
1
- import type { AuthLoginResponse, PhoneSendCodeResponse, PhoneVerifyResponse, PasswordResetRequestResponse, VerifyResetTokenResponse, PasswordResetCompleteResponse, EmailVerificationActionResponse, EmailVerifyTokenResponse, AuthKitConfig, MagicLinkSendResponse, MagicLinkVerifyResponse, UserProfile, ProfileUpdateData, SuccessResponse } from "../types/authKit";
1
+ import type { AuthLoginResponse, PhoneSendCodeResponse, PhoneVerifyResponse, PasswordResetRequestResponse, VerifyResetTokenResponse, PasswordResetCompleteResponse, EmailVerificationActionResponse, EmailVerifyTokenResponse, AuthKitConfig, MagicLinkSendResponse, MagicLinkVerifyResponse, UserProfile, ProfileUpdateData, SuccessResponse, SendWhatsAppRequest, SendWhatsAppResponse, VerifyWhatsAppResponse, WhatsAppStatusResponse, SendSmsVerifyRequest, SendSmsVerifyResponse, VerifySmsResponse, UpsertContactRequest, UpsertContactResponse } from "../types/authKit";
2
2
  /**
3
3
  * Namespace containing helper functions for the new AuthKit API.
4
4
  * Legacy collection-based authKit helpers retained (marked as *Legacy*).
@@ -27,6 +27,18 @@ export declare namespace authKit {
27
27
  function sendPhoneCode(clientId: string, phoneNumber: string): Promise<PhoneSendCodeResponse>;
28
28
  /** Verify phone verification code (public). */
29
29
  function verifyPhoneCode(clientId: string, phoneNumber: string, code: string): Promise<PhoneVerifyResponse>;
30
+ /** Send a WhatsApp verification deep-link (public). */
31
+ function sendWhatsApp(clientId: string, body: SendWhatsAppRequest): Promise<SendWhatsAppResponse>;
32
+ /** Manually verify WhatsApp token if inbound webhook path is unavailable (public). */
33
+ function verifyWhatsApp(clientId: string, token: string, phoneNumber: string): Promise<VerifyWhatsAppResponse>;
34
+ /** Poll WhatsApp verification status for a token (public). */
35
+ function getWhatsAppStatus(clientId: string, token: string): Promise<WhatsAppStatusResponse>;
36
+ /** Send an SMS click-to-verify link (public). */
37
+ function sendSmsVerify(clientId: string, body: SendSmsVerifyRequest): Promise<SendSmsVerifyResponse>;
38
+ /** Verify an SMS click-to-verify token via API (public). */
39
+ function verifySms(clientId: string, token: string, phoneNumber?: string): Promise<VerifySmsResponse>;
40
+ /** Upsert contact identity after lightweight verification (public). */
41
+ function upsertContact(clientId: string, body: UpsertContactRequest): Promise<UpsertContactResponse>;
30
42
  function requestPasswordReset(clientId: string, data: {
31
43
  email: string;
32
44
  redirectUrl?: string;
@@ -46,6 +46,40 @@ export var authKit;
46
46
  return post(`/authkit/${encodeURIComponent(clientId)}/auth/phone/verify`, { phoneNumber, code });
47
47
  }
48
48
  authKit.verifyPhoneCode = verifyPhoneCode;
49
+ /** Send a WhatsApp verification deep-link (public). */
50
+ async function sendWhatsApp(clientId, body) {
51
+ return post(`/authkit/${encodeURIComponent(clientId)}/auth/whatsapp/send`, body);
52
+ }
53
+ authKit.sendWhatsApp = sendWhatsApp;
54
+ /** Manually verify WhatsApp token if inbound webhook path is unavailable (public). */
55
+ async function verifyWhatsApp(clientId, token, phoneNumber) {
56
+ return post(`/authkit/${encodeURIComponent(clientId)}/auth/whatsapp/verify`, { token, phoneNumber });
57
+ }
58
+ authKit.verifyWhatsApp = verifyWhatsApp;
59
+ /** Poll WhatsApp verification status for a token (public). */
60
+ async function getWhatsAppStatus(clientId, token) {
61
+ const encodedToken = encodeURIComponent(token);
62
+ return request(`/authkit/${encodeURIComponent(clientId)}/auth/whatsapp/status?token=${encodedToken}`);
63
+ }
64
+ authKit.getWhatsAppStatus = getWhatsAppStatus;
65
+ /** Send an SMS click-to-verify link (public). */
66
+ async function sendSmsVerify(clientId, body) {
67
+ return post(`/authkit/${encodeURIComponent(clientId)}/auth/sms/send`, body);
68
+ }
69
+ authKit.sendSmsVerify = sendSmsVerify;
70
+ /** Verify an SMS click-to-verify token via API (public). */
71
+ async function verifySms(clientId, token, phoneNumber) {
72
+ const payload = { token };
73
+ if (phoneNumber)
74
+ payload.phoneNumber = phoneNumber;
75
+ return post(`/authkit/${encodeURIComponent(clientId)}/auth/sms/verify`, payload);
76
+ }
77
+ authKit.verifySms = verifySms;
78
+ /** Upsert contact identity after lightweight verification (public). */
79
+ async function upsertContact(clientId, body) {
80
+ return post(`/authkit/${encodeURIComponent(clientId)}/contact/upsert`, body);
81
+ }
82
+ authKit.upsertContact = upsertContact;
49
83
  /* ===================================
50
84
  * Password Reset (Public flows)
51
85
  * =================================== */
@@ -106,7 +106,7 @@ export declare namespace comms {
106
106
  * No broadcast record is created. The send is logged to the contact's
107
107
  * communication history with sourceType: 'transactional'.
108
108
  *
109
- * POST /admin/collection/:collectionId/comm.send
109
+ * POST /admin/collection/:collectionId/comm/send
110
110
  *
111
111
  * @example
112
112
  * ```typescript
package/dist/api/comms.js CHANGED
@@ -201,7 +201,7 @@ export var comms;
201
201
  * No broadcast record is created. The send is logged to the contact's
202
202
  * communication history with sourceType: 'transactional'.
203
203
  *
204
- * POST /admin/collection/:collectionId/comm.send
204
+ * POST /admin/collection/:collectionId/comm/send
205
205
  *
206
206
  * @example
207
207
  * ```typescript
@@ -222,8 +222,19 @@ export var comms;
222
222
  * ```
223
223
  */
224
224
  async function sendTransactional(collectionId, body) {
225
- const path = `/admin/collection/${encodeURIComponent(collectionId)}/comm.send`;
226
- return post(path, body);
225
+ const encodedCollectionId = encodeURIComponent(collectionId);
226
+ const path = `/admin/collection/${encodedCollectionId}/comm/send`;
227
+ try {
228
+ return await post(path, body);
229
+ }
230
+ catch (error) {
231
+ // Backward compatibility for deployments still serving the legacy route.
232
+ if ((error === null || error === void 0 ? void 0 : error.statusCode) === 404 || (error === null || error === void 0 ? void 0 : error.code) === 404) {
233
+ const legacyPath = `/admin/collection/${encodedCollectionId}/comm.send`;
234
+ return post(legacyPath, body);
235
+ }
236
+ throw error;
237
+ }
227
238
  }
228
239
  comms.sendTransactional = sendTransactional;
229
240
  /**
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.13.6 | Generated: 2026-05-09T13:35:50.729Z
3
+ Version: 1.13.8 | Generated: 2026-05-11T12:03:30.435Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -1725,7 +1725,7 @@ interface ListQueryParams {
1725
1725
  offset?: number // default 0
1726
1726
  sort?: string // field:asc or field:desc
1727
1727
  includeDeleted?: boolean // admin only
1728
- status?: string // exact or in:a,b,c
1728
+ status?: string // exact or in:a,b,c. For app.records on public/owner endpoints, only active records are returned.
1729
1729
  productId?: string
1730
1730
  createdAt?: string // gte:2024-01-01, lte:2024-12-31, or ISO date string
1731
1731
  updatedAt?: string // same format
@@ -3024,6 +3024,98 @@ interface EmailVerifyTokenResponse {
3024
3024
  }
3025
3025
  ```
3026
3026
 
3027
+ **SendWhatsAppRequest** (interface)
3028
+ ```typescript
3029
+ interface SendWhatsAppRequest {
3030
+ phoneNumber: string
3031
+ redirectUrl: string
3032
+ }
3033
+ ```
3034
+
3035
+ **SendWhatsAppResponse** (interface)
3036
+ ```typescript
3037
+ interface SendWhatsAppResponse {
3038
+ waLink: string
3039
+ code: string
3040
+ token: string
3041
+ expiresAt: string
3042
+ }
3043
+ ```
3044
+
3045
+ **VerifyWhatsAppResponse** (interface)
3046
+ ```typescript
3047
+ interface VerifyWhatsAppResponse {
3048
+ success: boolean
3049
+ verified: boolean
3050
+ redirectUrl?: string | null
3051
+ }
3052
+ ```
3053
+
3054
+ **WhatsAppStatusResponse** (interface)
3055
+ ```typescript
3056
+ interface WhatsAppStatusResponse {
3057
+ ok: boolean
3058
+ status: VerifyStatus
3059
+ verified: boolean
3060
+ redirectUrl?: string | null
3061
+ phoneNumber?: string | null
3062
+ updatedAt?: unknown
3063
+ }
3064
+ ```
3065
+
3066
+ **SendSmsVerifyRequest** (interface)
3067
+ ```typescript
3068
+ interface SendSmsVerifyRequest {
3069
+ phoneNumber: string
3070
+ redirectUrl: string
3071
+ ctaText?: string
3072
+ }
3073
+ ```
3074
+
3075
+ **SendSmsVerifyResponse** (interface)
3076
+ ```typescript
3077
+ interface SendSmsVerifyResponse {
3078
+ success: boolean
3079
+ expiresAt: string
3080
+ }
3081
+ ```
3082
+
3083
+ **VerifySmsResponse** (interface)
3084
+ ```typescript
3085
+ interface VerifySmsResponse {
3086
+ verified: boolean
3087
+ redirectUrl?: string | null
3088
+ phoneNumber?: string | null
3089
+ }
3090
+ ```
3091
+
3092
+ **UpsertContactRequest** (interface)
3093
+ ```typescript
3094
+ interface UpsertContactRequest {
3095
+ collectionId?: string
3096
+ phone?: string
3097
+ email?: string
3098
+ name?: string
3099
+ firstName?: string
3100
+ lastName?: string
3101
+ displayName?: string
3102
+ source?: string
3103
+ customFields?: Record<string, unknown>
3104
+ externalIds?: Record<string, unknown>
3105
+ }
3106
+ ```
3107
+
3108
+ **UpsertContactResponse** (interface)
3109
+ ```typescript
3110
+ interface UpsertContactResponse {
3111
+ ok: boolean
3112
+ collectionId: string
3113
+ contactId: string
3114
+ userId: string | null
3115
+ created: boolean
3116
+ }
3117
+ ```
3118
+
3027
3119
  **AuthKitBrandingConfig** (interface)
3028
3120
  ```typescript
3029
3121
  interface AuthKitBrandingConfig {
@@ -3053,6 +3145,8 @@ interface AuthKitConfig {
3053
3145
  }
3054
3146
  ```
3055
3147
 
3148
+ **VerifyStatus** = `'pending' | 'verified' | 'failed' | 'expired' | 'unknown'`
3149
+
3056
3150
  ### batch
3057
3151
 
3058
3152
  **FirebaseTimestamp** (interface)
@@ -3820,8 +3914,8 @@ interface TransactionalSendRequest {
3820
3914
  templateId: string
3821
3915
  * Channel to send on. Defaults to 'preferred', which auto-selects the
3822
3916
  * contact's best available channel respecting consent, suppression, and
3823
- * template availability (priority: email → push → sms → wallet).
3824
- channel?: 'email' | 'sms' | 'push' | 'wallet' | 'preferred'
3917
+ * template availability.
3918
+ channel?: 'email' | 'sms' | 'whatsapp' | 'push' | 'wallet' | 'preferred'
3825
3919
  props?: Record<string, unknown>
3826
3920
  include?: {
3827
3921
  collection?: boolean
@@ -3841,7 +3935,7 @@ interface TransactionalSendRequest {
3841
3935
  ```typescript
3842
3936
  interface TransactionalSendResponse {
3843
3937
  ok: true
3844
- channel: 'email' | 'sms' | 'push' | 'wallet'
3938
+ channel: 'email' | 'sms' | 'whatsapp' | 'push' | 'wallet'
3845
3939
  messageId?: string
3846
3940
  }
3847
3941
  ```
@@ -3856,6 +3950,7 @@ interface TransactionalSendError {
3856
3950
  * - `transactional.no_channel_available`
3857
3951
  * - `transactional.email_missing`
3858
3952
  * - `transactional.phone_missing`
3953
+ * - `transactional.whatsapp_missing`
3859
3954
  * - `transactional.no_push_methods`
3860
3955
  * - `transactional.no_wallet_methods`
3861
3956
  error: string
@@ -4129,7 +4224,7 @@ export interface SubscriptionsResolveResponse {
4129
4224
  * No broadcast record is created; the send is logged directly to the
4130
4225
  * contact's communication history with sourceType: 'transactional'.
4131
4226
  *
4132
- * POST /admin/collection/:collectionId/comm.send
4227
+ * POST /admin/collection/:collectionId/comm/send
4133
4228
  */
4134
4229
  export interface TransactionalSendRequest {
4135
4230
  /** CRM contact UUID */
@@ -4139,9 +4234,9 @@ export interface TransactionalSendRequest {
4139
4234
  /**
4140
4235
  * Channel to send on. Defaults to 'preferred', which auto-selects the
4141
4236
  * contact's best available channel respecting consent, suppression, and
4142
- * template availability (priority: email → push → sms → wallet).
4237
+ * template availability.
4143
4238
  */
4144
- channel?: 'email' | 'sms' | 'push' | 'wallet' | 'preferred'
4239
+ channel?: 'email' | 'sms' | 'whatsapp' | 'push' | 'wallet' | 'preferred'
4145
4240
  /** Extra Liquid variables merged into the top-level render context */
4146
4241
  props?: Record<string, unknown>
4147
4242
  /** Context objects to hydrate into the Liquid template */
@@ -4170,8 +4265,8 @@ export interface TransactionalSendRequest {
4170
4265
  export interface TransactionalSendResponse {
4171
4266
  ok: true
4172
4267
  /** The channel the message was actually sent on */
4173
- channel: 'email' | 'sms' | 'push' | 'wallet'
4174
- /** Provider message ID (email/SMS); absent for push/wallet */
4268
+ channel: 'email' | 'sms' | 'whatsapp' | 'push' | 'wallet'
4269
+ /** Provider message ID (email/SMS/WhatsApp); absent for push/wallet */
4175
4270
  messageId?: string
4176
4271
  }
4177
4272
 
@@ -4184,6 +4279,7 @@ export interface TransactionalSendError {
4184
4279
  * - `transactional.no_channel_available`
4185
4280
  * - `transactional.email_missing`
4186
4281
  * - `transactional.phone_missing`
4282
+ * - `transactional.whatsapp_missing`
4187
4283
  * - `transactional.no_push_methods`
4188
4284
  * - `transactional.no_wallet_methods`
4189
4285
  */
@@ -7583,7 +7679,7 @@ Create a new record POST /records When called on the public endpoint (admin = fa
7583
7679
  appId: string,
7584
7680
  params?: RecordListQueryParams,
7585
7681
  admin: boolean = false) → `Promise<PaginatedResponse<AppRecord>>`
7586
- List records with optional query parameters GET /records
7682
+ List records with optional query parameters GET /records Public/owner callers only receive records with `status: "active"`. Admin callers can query all statuses (for example `draft`/`archived`).
7587
7683
 
7588
7684
  **get**(collectionId: string,
7589
7685
  appId: string,
@@ -7997,62 +8093,80 @@ Send phone verification code (public).
7997
8093
  **verifyPhoneCode**(clientId: string, phoneNumber: string, code: string) → `Promise<PhoneVerifyResponse>`
7998
8094
  Verify phone verification code (public).
7999
8095
 
8096
+ **sendWhatsApp**(clientId: string, body: SendWhatsAppRequest) → `Promise<SendWhatsAppResponse>`
8097
+ Send a WhatsApp verification deep-link (public).
8098
+
8099
+ **verifyWhatsApp**(clientId: string, token: string, phoneNumber: string) → `Promise<VerifyWhatsAppResponse>`
8100
+ Manually verify WhatsApp token if inbound webhook path is unavailable (public).
8101
+
8102
+ **getWhatsAppStatus**(clientId: string, token: string) → `Promise<WhatsAppStatusResponse>`
8103
+ Poll WhatsApp verification status for a token (public).
8104
+
8105
+ **sendSmsVerify**(clientId: string, body: SendSmsVerifyRequest) → `Promise<SendSmsVerifyResponse>`
8106
+ Send an SMS click-to-verify link (public).
8107
+
8108
+ **verifySms**(clientId: string, token: string, phoneNumber?: string) → `Promise<VerifySmsResponse>`
8109
+ Verify an SMS click-to-verify token via API (public).
8110
+
8111
+ **upsertContact**(clientId: string, body: UpsertContactRequest) → `Promise<UpsertContactResponse>`
8112
+ Upsert contact identity after lightweight verification (public).
8113
+
8000
8114
  **requestPasswordReset**(clientId: string, data: { email: string; redirectUrl?: string; clientName?: string }) → `Promise<PasswordResetRequestResponse>`
8001
- Verify phone verification code (public).
8115
+ Upsert contact identity after lightweight verification (public).
8002
8116
 
8003
8117
  **verifyResetToken**(clientId: string, token: string) → `Promise<VerifyResetTokenResponse>`
8004
- Verify phone verification code (public).
8118
+ Upsert contact identity after lightweight verification (public).
8005
8119
 
8006
8120
  **completePasswordReset**(clientId: string, token: string, newPassword: string) → `Promise<PasswordResetCompleteResponse>`
8007
- Verify phone verification code (public).
8121
+ Upsert contact identity after lightweight verification (public).
8008
8122
 
8009
8123
  **sendEmailVerification**(clientId: string, data: { userId: string; email: string; redirectUrl?: string; clientName?: string }) → `Promise<EmailVerificationActionResponse>`
8010
- Verify phone verification code (public).
8124
+ Upsert contact identity after lightweight verification (public).
8011
8125
 
8012
8126
  **verifyEmail**(clientId: string, token: string) → `Promise<EmailVerifyTokenResponse>`
8013
- Verify phone verification code (public).
8127
+ Upsert contact identity after lightweight verification (public).
8014
8128
 
8015
8129
  **resendEmailVerification**(clientId: string, data: { userId: string; email: string; redirectUrl?: string; clientName?: string }) → `Promise<EmailVerificationActionResponse>`
8016
- Verify phone verification code (public).
8130
+ Upsert contact identity after lightweight verification (public).
8017
8131
 
8018
8132
  **getProfile**(clientId: string) → `Promise<UserProfile>`
8019
- Verify phone verification code (public).
8133
+ Upsert contact identity after lightweight verification (public).
8020
8134
 
8021
8135
  **updateProfile**(clientId: string, data: ProfileUpdateData) → `Promise<UserProfile>`
8022
- Verify phone verification code (public).
8136
+ Upsert contact identity after lightweight verification (public).
8023
8137
 
8024
8138
  **changePassword**(clientId: string, currentPassword: string, newPassword: string) → `Promise<SuccessResponse>`
8025
- Verify phone verification code (public).
8139
+ Upsert contact identity after lightweight verification (public).
8026
8140
 
8027
8141
  **changeEmail**(clientId: string, newEmail: string, password: string, redirectUrl: string) → `Promise<SuccessResponse>`
8028
- Verify phone verification code (public).
8142
+ Upsert contact identity after lightweight verification (public).
8029
8143
 
8030
8144
  **verifyEmailChange**(clientId: string, token: string) → `Promise<SuccessResponse>`
8031
- Verify phone verification code (public).
8145
+ Upsert contact identity after lightweight verification (public).
8032
8146
 
8033
8147
  **updatePhone**(clientId: string, phoneNumber: string, verificationCode: string) → `Promise<SuccessResponse>`
8034
- Verify phone verification code (public).
8148
+ Upsert contact identity after lightweight verification (public).
8035
8149
 
8036
8150
  **deleteAccount**(clientId: string, password: string, confirmText: string) → `Promise<SuccessResponse>`
8037
- Verify phone verification code (public).
8151
+ Upsert contact identity after lightweight verification (public).
8038
8152
 
8039
8153
  **load**(authKitId: string) → `Promise<AuthKitConfig>`
8040
- Verify phone verification code (public).
8154
+ Upsert contact identity after lightweight verification (public).
8041
8155
 
8042
8156
  **get**(collectionId: string, authKitId: string) → `Promise<AuthKitConfig>`
8043
- Verify phone verification code (public).
8157
+ Upsert contact identity after lightweight verification (public).
8044
8158
 
8045
8159
  **list**(collectionId: string, admin?: boolean) → `Promise<AuthKitConfig[]>`
8046
- Verify phone verification code (public).
8160
+ Upsert contact identity after lightweight verification (public).
8047
8161
 
8048
8162
  **create**(collectionId: string, data: any) → `Promise<AuthKitConfig>`
8049
- Verify phone verification code (public).
8163
+ Upsert contact identity after lightweight verification (public).
8050
8164
 
8051
8165
  **update**(collectionId: string, authKitId: string, data: any) → `Promise<AuthKitConfig>`
8052
- Verify phone verification code (public).
8166
+ Upsert contact identity after lightweight verification (public).
8053
8167
 
8054
8168
  **remove**(collectionId: string, authKitId: string) → `Promise<void>`
8055
- Verify phone verification code (public).
8169
+ Upsert contact identity after lightweight verification (public).
8056
8170
 
8057
8171
  ### batch
8058
8172
 
@@ -8336,7 +8450,7 @@ Analytics: Recipients who performed an action, optionally with outcome. POST /ad
8336
8450
 
8337
8451
  **sendTransactional**(collectionId: string,
8338
8452
  body: TransactionalSendRequest) → `Promise<TransactionalSendResult>`
8339
- Send a single transactional message to one contact using a template. No broadcast record is created. The send is logged to the contact's communication history with sourceType: 'transactional'. POST /admin/collection/:collectionId/comm.send ```typescript const result = await comms.sendTransactional(collectionId, { contactId: 'e4f2a1b0-...', templateId: 'warranty-update', channel: 'preferred', props: { claimRef: 'CLM-0042', decision: 'approved' }, include: { productId: 'prod-abc123', appCase: 'c9d1e2f3-...' }, ref: 'warranty-decision-notification', appId: 'warrantyApp', }) if (result.ok) { console.log(`Sent via ${result.channel}`, result.messageId) } else { console.error('Send failed:', result.error) } ```
8453
+ Send a single transactional message to one contact using a template. No broadcast record is created. The send is logged to the contact's communication history with sourceType: 'transactional'. POST /admin/collection/:collectionId/comm/send ```typescript const result = await comms.sendTransactional(collectionId, { contactId: 'e4f2a1b0-...', templateId: 'warranty-update', channel: 'preferred', props: { claimRef: 'CLM-0042', decision: 'approved' }, include: { productId: 'prod-abc123', appCase: 'c9d1e2f3-...' }, ref: 'warranty-decision-notification', appId: 'warrantyApp', }) if (result.ok) { console.log(`Sent via ${result.channel}`, result.messageId) } else { console.error('Send failed:', result.error) } ```
8340
8454
 
8341
8455
  **logCommunicationEvent**(collectionId: string,
8342
8456
  body: LogCommunicationEventBody) → `Promise<AppendResult>`