@proveanything/smartlinks 1.13.10 → 1.13.12
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/dist/api/authKit.d.ts +1 -1
- package/dist/api/authKit.js +1 -1
- package/dist/api/interactions.d.ts +13 -8
- package/dist/api/interactions.js +13 -8
- package/dist/docs/API_SUMMARY.md +36 -16
- package/dist/docs/ai-guide-template.md +2 -0
- package/dist/docs/auth-kit.md +35 -4
- package/dist/docs/interactions.md +15 -1
- package/dist/docs/loyalty.md +2 -0
- package/dist/docs/overview.md +2 -0
- package/dist/docs/realtime.md +1 -0
- package/dist/openapi.yaml +27 -3
- package/dist/types/authKit.d.ts +17 -2
- package/docs/API_SUMMARY.md +36 -16
- package/docs/ai-guide-template.md +2 -0
- package/docs/auth-kit.md +35 -4
- package/docs/interactions.md +15 -1
- package/docs/loyalty.md +2 -0
- package/docs/overview.md +2 -0
- package/docs/realtime.md +1 -0
- package/openapi.yaml +27 -3
- package/package.json +1 -1
package/dist/api/authKit.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ export declare namespace authKit {
|
|
|
28
28
|
/** Verify phone verification code (public). */
|
|
29
29
|
function verifyPhoneCode(clientId: string, phoneNumber: string, code: string): Promise<PhoneVerifyResponse>;
|
|
30
30
|
/** Send a WhatsApp verification deep-link (public). */
|
|
31
|
-
function sendWhatsApp(clientId: string, body
|
|
31
|
+
function sendWhatsApp(clientId: string, body?: SendWhatsAppRequest): Promise<SendWhatsAppResponse>;
|
|
32
32
|
/** Manually verify WhatsApp token if inbound webhook path is unavailable (public). */
|
|
33
33
|
function verifyWhatsApp(clientId: string, token: string, phoneNumber: string): Promise<VerifyWhatsAppResponse>;
|
|
34
34
|
/** Poll WhatsApp verification status for a token (public). */
|
package/dist/api/authKit.js
CHANGED
|
@@ -47,7 +47,7 @@ export var authKit;
|
|
|
47
47
|
}
|
|
48
48
|
authKit.verifyPhoneCode = verifyPhoneCode;
|
|
49
49
|
/** Send a WhatsApp verification deep-link (public). */
|
|
50
|
-
async function sendWhatsApp(clientId, body) {
|
|
50
|
+
async function sendWhatsApp(clientId, body = {}) {
|
|
51
51
|
return post(`/authkit/${encodeURIComponent(clientId)}/auth/whatsapp/send`, body);
|
|
52
52
|
}
|
|
53
53
|
authKit.sendWhatsApp = sendWhatsApp;
|
|
@@ -21,7 +21,10 @@ export declare namespace interactions {
|
|
|
21
21
|
function aggregateByOutcome(collectionId: string, body: AdminInteractionsAggregateRequest): Promise<AdminInteractionsAggregateResponse>;
|
|
22
22
|
/**
|
|
23
23
|
* POST /admin/collection/:collectionId/interactions/append
|
|
24
|
-
|
|
24
|
+
* Appends one interaction event.
|
|
25
|
+
*
|
|
26
|
+
* `interactionId` must reference an existing interaction type definition.
|
|
27
|
+
* This endpoint does not create interaction definitions.
|
|
25
28
|
*/
|
|
26
29
|
function appendEvent(collectionId: string, body: AppendInteractionBody): Promise<{
|
|
27
30
|
success: true;
|
|
@@ -30,13 +33,15 @@ export declare namespace interactions {
|
|
|
30
33
|
success: true;
|
|
31
34
|
}>;
|
|
32
35
|
/**
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
* POST /api/v1/public/collection/:collectionId/interactions/submit
|
|
37
|
+
*
|
|
38
|
+
* Submits an interaction event from a public/client-side context.
|
|
39
|
+
* `interactionId` must reference an existing interaction type definition.
|
|
40
|
+
* This endpoint does not create interaction definitions.
|
|
41
|
+
* When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor
|
|
42
|
+
* `contactId` is required. Pass `anonId` inside `metadata` to enable
|
|
43
|
+
* device-level deduplication via `uniquePerAnonId`.
|
|
44
|
+
*/
|
|
40
45
|
function submitPublicEvent(collectionId: string, body: AppendInteractionBody): Promise<SubmitInteractionResponse | SubmitInteractionError>;
|
|
41
46
|
function create(collectionId: string, body: CreateInteractionTypeBody): Promise<InteractionTypeRecord>;
|
|
42
47
|
function list(collectionId: string, query?: ListInteractionTypesQuery): Promise<InteractionTypeList>;
|
package/dist/api/interactions.js
CHANGED
|
@@ -54,7 +54,10 @@ export var interactions;
|
|
|
54
54
|
// Deprecated endpoint removed: actorIdsByInteraction
|
|
55
55
|
/**
|
|
56
56
|
* POST /admin/collection/:collectionId/interactions/append
|
|
57
|
-
|
|
57
|
+
* Appends one interaction event.
|
|
58
|
+
*
|
|
59
|
+
* `interactionId` must reference an existing interaction type definition.
|
|
60
|
+
* This endpoint does not create interaction definitions.
|
|
58
61
|
*/
|
|
59
62
|
async function appendEvent(collectionId, body) {
|
|
60
63
|
if (!body.userId && !body.contactId) {
|
|
@@ -73,13 +76,15 @@ export var interactions;
|
|
|
73
76
|
}
|
|
74
77
|
interactions.updateEvent = updateEvent;
|
|
75
78
|
/**
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
* POST /api/v1/public/collection/:collectionId/interactions/submit
|
|
80
|
+
*
|
|
81
|
+
* Submits an interaction event from a public/client-side context.
|
|
82
|
+
* `interactionId` must reference an existing interaction type definition.
|
|
83
|
+
* This endpoint does not create interaction definitions.
|
|
84
|
+
* When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor
|
|
85
|
+
* `contactId` is required. Pass `anonId` inside `metadata` to enable
|
|
86
|
+
* device-level deduplication via `uniquePerAnonId`.
|
|
87
|
+
*/
|
|
83
88
|
async function submitPublicEvent(collectionId, body) {
|
|
84
89
|
const path = `/public/collection/${encodeURIComponent(collectionId)}/interactions/submit`;
|
|
85
90
|
return post(path, body);
|
package/dist/docs/API_SUMMARY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Smartlinks API Summary
|
|
2
2
|
|
|
3
|
-
Version: 1.13.
|
|
3
|
+
Version: 1.13.12 | Generated: 2026-05-14T16:00:33.063Z
|
|
4
4
|
|
|
5
5
|
This is a concise summary of all available API functions and types.
|
|
6
6
|
|
|
@@ -3024,11 +3024,31 @@ interface EmailVerifyTokenResponse {
|
|
|
3024
3024
|
}
|
|
3025
3025
|
```
|
|
3026
3026
|
|
|
3027
|
+
**WhatsAppReplyCta** (interface)
|
|
3028
|
+
```typescript
|
|
3029
|
+
interface WhatsAppReplyCta {
|
|
3030
|
+
body: string
|
|
3031
|
+
buttonLabel: string
|
|
3032
|
+
buttonUrl: string
|
|
3033
|
+
}
|
|
3034
|
+
```
|
|
3035
|
+
|
|
3036
|
+
**WhatsAppReplyOptions** (interface)
|
|
3037
|
+
```typescript
|
|
3038
|
+
interface WhatsAppReplyOptions {
|
|
3039
|
+
contentSid?: string
|
|
3040
|
+
contentVariables?: Record<string, unknown>
|
|
3041
|
+
cta?: WhatsAppReplyCta
|
|
3042
|
+
text?: string
|
|
3043
|
+
}
|
|
3044
|
+
```
|
|
3045
|
+
|
|
3027
3046
|
**SendWhatsAppRequest** (interface)
|
|
3028
3047
|
```typescript
|
|
3029
3048
|
interface SendWhatsAppRequest {
|
|
3030
|
-
phoneNumber
|
|
3031
|
-
redirectUrl
|
|
3049
|
+
phoneNumber?: string
|
|
3050
|
+
redirectUrl?: string
|
|
3051
|
+
reply?: WhatsAppReplyOptions
|
|
3032
3052
|
}
|
|
3033
3053
|
```
|
|
3034
3054
|
|
|
@@ -8192,7 +8212,7 @@ Send phone verification code (public).
|
|
|
8192
8212
|
**verifyPhoneCode**(clientId: string, phoneNumber: string, code: string) → `Promise<PhoneVerifyResponse>`
|
|
8193
8213
|
Verify phone verification code (public).
|
|
8194
8214
|
|
|
8195
|
-
**sendWhatsApp**(clientId: string, body: SendWhatsAppRequest) → `Promise<SendWhatsAppResponse>`
|
|
8215
|
+
**sendWhatsApp**(clientId: string, body: SendWhatsAppRequest = {}) → `Promise<SendWhatsAppResponse>`
|
|
8196
8216
|
Send a WhatsApp verification deep-link (public).
|
|
8197
8217
|
|
|
8198
8218
|
**verifyWhatsApp**(clientId: string, token: string, phoneNumber: string) → `Promise<VerifyWhatsAppResponse>`
|
|
@@ -8803,54 +8823,54 @@ Legacy-friendly alias for aggregate().
|
|
|
8803
8823
|
|
|
8804
8824
|
**appendEvent**(collectionId: string,
|
|
8805
8825
|
body: AppendInteractionBody) → `Promise<`
|
|
8806
|
-
POST /admin/collection/:collectionId/interactions/append Appends one interaction event.
|
|
8826
|
+
POST /admin/collection/:collectionId/interactions/append Appends one interaction event. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions.
|
|
8807
8827
|
|
|
8808
8828
|
**updateEvent**(collectionId: string,
|
|
8809
8829
|
body: UpdateInteractionBody) → `Promise<`
|
|
8810
|
-
POST /admin/collection/:collectionId/interactions/append Appends one interaction event.
|
|
8830
|
+
POST /admin/collection/:collectionId/interactions/append Appends one interaction event. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions.
|
|
8811
8831
|
|
|
8812
8832
|
**submitPublicEvent**(collectionId: string,
|
|
8813
8833
|
body: AppendInteractionBody) → `Promise<SubmitInteractionResponse | SubmitInteractionError>`
|
|
8814
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8834
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8815
8835
|
|
|
8816
8836
|
**create**(collectionId: string,
|
|
8817
8837
|
body: CreateInteractionTypeBody) → `Promise<InteractionTypeRecord>`
|
|
8818
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8838
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8819
8839
|
|
|
8820
8840
|
**list**(collectionId: string,
|
|
8821
8841
|
query: ListInteractionTypesQuery = {}) → `Promise<InteractionTypeList>`
|
|
8822
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8842
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8823
8843
|
|
|
8824
8844
|
**get**(collectionId: string,
|
|
8825
8845
|
id: string) → `Promise<InteractionTypeRecord>`
|
|
8826
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8846
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8827
8847
|
|
|
8828
8848
|
**update**(collectionId: string,
|
|
8829
8849
|
id: string,
|
|
8830
8850
|
patchBody: UpdateInteractionTypeBody) → `Promise<InteractionTypeRecord>`
|
|
8831
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8851
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8832
8852
|
|
|
8833
8853
|
**remove**(collectionId: string,
|
|
8834
8854
|
id: string) → `Promise<void>`
|
|
8835
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8855
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8836
8856
|
|
|
8837
8857
|
**publicCountsByOutcome**(collectionId: string,
|
|
8838
8858
|
body: PublicInteractionsCountsByOutcomeRequest,
|
|
8839
8859
|
authToken?: string) → `Promise<OutcomeCount[]>`
|
|
8840
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8860
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8841
8861
|
|
|
8842
8862
|
**publicMyInteractions**(collectionId: string,
|
|
8843
8863
|
body: PublicInteractionsByUserRequest,
|
|
8844
8864
|
authToken?: string) → `Promise<InteractionEventRow[]>`
|
|
8845
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8865
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8846
8866
|
|
|
8847
8867
|
**publicList**(collectionId: string,
|
|
8848
8868
|
query: ListInteractionTypesQuery = {}) → `Promise<InteractionTypeList>`
|
|
8849
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8869
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8850
8870
|
|
|
8851
8871
|
**publicGet**(collectionId: string,
|
|
8852
8872
|
id: string) → `Promise<InteractionTypeRecord>`
|
|
8853
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8873
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8854
8874
|
|
|
8855
8875
|
### jobs
|
|
8856
8876
|
|
|
@@ -225,6 +225,8 @@ await SL.appConfiguration.setConfig({
|
|
|
225
225
|
|
|
226
226
|
### Tracked Interactions
|
|
227
227
|
|
|
228
|
+
Use interaction IDs that are defined via `SL.interactions.create(...)` for the collection. Do not invent ad-hoc IDs in app code.
|
|
229
|
+
|
|
228
230
|
| Interaction ID | Description |
|
|
229
231
|
| -------------- | --------------------------------------------- |
|
|
230
232
|
| `page-view` | Tracks each time a user views the public page |
|
package/dist/docs/auth-kit.md
CHANGED
|
@@ -86,10 +86,20 @@ Use these flows when you want low-friction verification before or without full a
|
|
|
86
86
|
import { authKit } from '@proveanything/smartlinks';
|
|
87
87
|
|
|
88
88
|
// 1) Send WhatsApp verification deep link
|
|
89
|
-
const wa = await authKit.sendWhatsApp(clientId
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
const wa = await authKit.sendWhatsApp(clientId);
|
|
90
|
+
|
|
91
|
+
// Optional: pass redirect context and/or a post-verification reply
|
|
92
|
+
// const wa = await authKit.sendWhatsApp(clientId, {
|
|
93
|
+
// redirectUrl: 'https://app.example.com/checkout/continue',
|
|
94
|
+
// reply: {
|
|
95
|
+
// cta: {
|
|
96
|
+
// body: "You're verified and ready to bid.",
|
|
97
|
+
// buttonLabel: 'Back to Auction',
|
|
98
|
+
// buttonUrl: '{{returnUrl}}',
|
|
99
|
+
// },
|
|
100
|
+
// text: "You're verified. Return to the app to continue.",
|
|
101
|
+
// },
|
|
102
|
+
// });
|
|
93
103
|
|
|
94
104
|
// wa.waLink can be opened directly by the app/browser
|
|
95
105
|
// Poll status while user switches to WhatsApp and back
|
|
@@ -133,6 +143,27 @@ Verification status values returned by `authKit.getWhatsAppStatus` are:
|
|
|
133
143
|
- `expired`
|
|
134
144
|
- `unknown`
|
|
135
145
|
|
|
146
|
+
#### Post-verification reply
|
|
147
|
+
|
|
148
|
+
Pass a `reply` object in `sendWhatsApp` to send a message back to the user after they confirm `CONFIRM <token>`. Reply resolution order:
|
|
149
|
+
|
|
150
|
+
1. `reply.contentSid` — explicit Twilio Content SID
|
|
151
|
+
2. `reply.cta` — CTA shorthand using the shared generic Twilio Content template SID (`TWILIO_WHATSAPP_GENERIC_CTA_SID`)
|
|
152
|
+
3. `reply.text` — plain-text fallback
|
|
153
|
+
4. Per-client default (`authKit/{clientId}.whatsapp` config)
|
|
154
|
+
5. Built-in default text
|
|
155
|
+
|
|
156
|
+
The following template placeholders are available in `reply.text`, `reply.cta` fields, and `reply.contentVariables` values:
|
|
157
|
+
|
|
158
|
+
| Placeholder | Description |
|
|
159
|
+
|---|---|
|
|
160
|
+
| `{{returnUrl}}` | The resolved redirect URL |
|
|
161
|
+
| `{{phoneNumber}}` | The verified phone number |
|
|
162
|
+
| `{{clientId}}` | The Auth Kit client ID |
|
|
163
|
+
| `{{token}}` | The verification token |
|
|
164
|
+
|
|
165
|
+
> **Note:** `redirectUrl` is optional. WhatsApp tokens are short hex strings (16 chars) for better UX.
|
|
166
|
+
|
|
136
167
|
### Google OAuth
|
|
137
168
|
|
|
138
169
|
```ts
|
|
@@ -15,15 +15,19 @@ Interactions have two distinct layers:
|
|
|
15
15
|
| **Interaction Types** | Definitions stored in the database — configure an interaction's ID, permissions, and display metadata once per collection |
|
|
16
16
|
| **Interaction Events** | Individual event records logged each time a user performs that interaction |
|
|
17
17
|
|
|
18
|
+
Critical rule: event `interactionId` values must reference an existing interaction type definition in that collection. Do not generate random IDs in app code and submit events against them.
|
|
19
|
+
|
|
18
20
|
```text
|
|
19
21
|
┌──────────────────────────────────────────────────────────────────┐
|
|
20
22
|
│ Your App │
|
|
21
23
|
│ │
|
|
22
24
|
│ 1. Create type once: interactions.create(collectionId, { │
|
|
23
25
|
│ id: 'vote', permissions: { uniquePerUser: true } }) │
|
|
26
|
+
│ -> definition exists in platform │
|
|
24
27
|
│ │
|
|
25
28
|
│ 2. Log events: interactions.appendEvent(collectionId, { │
|
|
26
29
|
│ interactionId: 'vote', outcome: 'option-a', userId }) │
|
|
30
|
+
│ (must match the created definition ID) │
|
|
27
31
|
│ │
|
|
28
32
|
│ 3. Read results: interactions.countsByOutcome(collectionId, │
|
|
29
33
|
│ { interactionId: 'vote' }) │
|
|
@@ -31,6 +35,14 @@ Interactions have two distinct layers:
|
|
|
31
35
|
└──────────────────────────────────────────────────────────────────┘
|
|
32
36
|
```
|
|
33
37
|
|
|
38
|
+
### Required Workflow (Do Not Invent IDs)
|
|
39
|
+
|
|
40
|
+
1. Create an interaction type definition (admin endpoint) before recording any events.
|
|
41
|
+
2. Reuse that same definition ID for every `appendEvent` / `submitPublicEvent` call.
|
|
42
|
+
3. Treat unknown IDs as configuration errors, not as values your app should auto-create.
|
|
43
|
+
|
|
44
|
+
If your app currently hardcodes strings like `"poll"` or `"entry"`, make sure those IDs are actually created as interaction types during setup.
|
|
45
|
+
|
|
34
46
|
---
|
|
35
47
|
|
|
36
48
|
## Common Use Cases
|
|
@@ -101,6 +113,8 @@ const { items } = await SL.interactions.publicList(collectionId, { appId: 'my-ap
|
|
|
101
113
|
|
|
102
114
|
## Logging Events
|
|
103
115
|
|
|
116
|
+
Before logging events, ensure the referenced interaction type already exists. Event ingestion is not intended to create new interaction definitions.
|
|
117
|
+
|
|
104
118
|
### Admin Event Append
|
|
105
119
|
|
|
106
120
|
Use on the server side or in admin flows. Requires `userId` **or** `contactId`.
|
|
@@ -166,7 +180,7 @@ await SL.interactions.updateEvent(collectionId, {
|
|
|
166
180
|
|
|
167
181
|
| Field | Type | Required | Description |
|
|
168
182
|
|-------|------|----------|-------------|
|
|
169
|
-
| `interactionId` | string | ✅ |
|
|
183
|
+
| `interactionId` | string | ✅ | Existing interaction type ID (must already be defined in this collection) |
|
|
170
184
|
| `userId` or `contactId` | string | ✅ (one of) | The actor. `appendEvent` / `updateEvent` require one of these |
|
|
171
185
|
| `appId` | string | ❌ | Scopes the event to your app |
|
|
172
186
|
| `outcome` | string | ❌ | The result or choice — what `countsByOutcome()` aggregates |
|
package/dist/docs/loyalty.md
CHANGED
|
@@ -120,6 +120,8 @@ const { items } = await SL.loyalty.publicGetMineHistory(collectionId, schemeId,
|
|
|
120
120
|
|
|
121
121
|
Earning rules are the control plane that connects interactions to point awards. The server evaluates them automatically — your app never sets a point value directly.
|
|
122
122
|
|
|
123
|
+
Every `interactionId` in a loyalty rule must reference an existing interaction type definition in the same collection.
|
|
124
|
+
|
|
123
125
|
### Create a Rule
|
|
124
126
|
|
|
125
127
|
```typescript
|
package/dist/docs/overview.md
CHANGED
|
@@ -227,6 +227,8 @@ See `docs/ai.md` for complete documentation.
|
|
|
227
227
|
|
|
228
228
|
The `SL.interactions` namespace tracks user engagement — competition entries, votes, form submissions, warranty registrations. Events can trigger automated journeys and communications.
|
|
229
229
|
|
|
230
|
+
Important: create interaction type definitions first, then submit events using those existing IDs. Do not invent `interactionId` values in client code.
|
|
231
|
+
|
|
230
232
|
Key functions: `submitPublicEvent()`, `appendEvent()` (admin), `countsByOutcome()`, `query()`.
|
|
231
233
|
|
|
232
234
|
See `docs/interactions.md` for complete documentation.
|
package/dist/docs/realtime.md
CHANGED
|
@@ -590,6 +590,7 @@ When a user votes, publish to the channel:
|
|
|
590
590
|
```typescript
|
|
591
591
|
const submitVote = async (option: string) => {
|
|
592
592
|
// Record in SmartLinks
|
|
593
|
+
// 'poll' must already exist as an interaction type definition for this collection.
|
|
593
594
|
await SL.interactions.submitPublicEvent(collectionId, {
|
|
594
595
|
appId,
|
|
595
596
|
interactionId: 'poll',
|
package/dist/openapi.yaml
CHANGED
|
@@ -17864,6 +17864,31 @@ components:
|
|
|
17864
17864
|
required:
|
|
17865
17865
|
- success
|
|
17866
17866
|
- message
|
|
17867
|
+
WhatsAppReplyCta:
|
|
17868
|
+
type: object
|
|
17869
|
+
properties:
|
|
17870
|
+
body:
|
|
17871
|
+
type: string
|
|
17872
|
+
buttonLabel:
|
|
17873
|
+
type: string
|
|
17874
|
+
buttonUrl:
|
|
17875
|
+
type: string
|
|
17876
|
+
required:
|
|
17877
|
+
- body
|
|
17878
|
+
- buttonLabel
|
|
17879
|
+
- buttonUrl
|
|
17880
|
+
WhatsAppReplyOptions:
|
|
17881
|
+
type: object
|
|
17882
|
+
properties:
|
|
17883
|
+
contentSid:
|
|
17884
|
+
type: string
|
|
17885
|
+
contentVariables:
|
|
17886
|
+
type: object
|
|
17887
|
+
additionalProperties: true
|
|
17888
|
+
cta:
|
|
17889
|
+
$ref: "#/components/schemas/WhatsAppReplyCta"
|
|
17890
|
+
text:
|
|
17891
|
+
type: string
|
|
17867
17892
|
SendWhatsAppRequest:
|
|
17868
17893
|
type: object
|
|
17869
17894
|
properties:
|
|
@@ -17871,9 +17896,8 @@ components:
|
|
|
17871
17896
|
type: string
|
|
17872
17897
|
redirectUrl:
|
|
17873
17898
|
type: string
|
|
17874
|
-
|
|
17875
|
-
|
|
17876
|
-
- redirectUrl
|
|
17899
|
+
reply:
|
|
17900
|
+
$ref: "#/components/schemas/WhatsAppReplyOptions"
|
|
17877
17901
|
SendWhatsAppResponse:
|
|
17878
17902
|
type: object
|
|
17879
17903
|
properties:
|
package/dist/types/authKit.d.ts
CHANGED
|
@@ -76,9 +76,24 @@ export interface EmailVerifyTokenResponse {
|
|
|
76
76
|
emailVerificationMode?: 'immediate' | 'verify-auto-login' | 'verify-manual-login';
|
|
77
77
|
}
|
|
78
78
|
export type VerifyStatus = 'pending' | 'verified' | 'failed' | 'expired' | 'unknown';
|
|
79
|
+
export interface WhatsAppReplyCta {
|
|
80
|
+
body: string;
|
|
81
|
+
buttonLabel: string;
|
|
82
|
+
buttonUrl: string;
|
|
83
|
+
}
|
|
84
|
+
export interface WhatsAppReplyOptions {
|
|
85
|
+
/** Option A: explicit Twilio Content SID */
|
|
86
|
+
contentSid?: string;
|
|
87
|
+
contentVariables?: Record<string, unknown>;
|
|
88
|
+
/** Option B: CTA shorthand (uses shared generic CTA content SID) */
|
|
89
|
+
cta?: WhatsAppReplyCta;
|
|
90
|
+
/** Option C: plain-text fallback */
|
|
91
|
+
text?: string;
|
|
92
|
+
}
|
|
79
93
|
export interface SendWhatsAppRequest {
|
|
80
|
-
phoneNumber
|
|
81
|
-
redirectUrl
|
|
94
|
+
phoneNumber?: string;
|
|
95
|
+
redirectUrl?: string;
|
|
96
|
+
reply?: WhatsAppReplyOptions;
|
|
82
97
|
}
|
|
83
98
|
export interface SendWhatsAppResponse {
|
|
84
99
|
waLink: string;
|
package/docs/API_SUMMARY.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Smartlinks API Summary
|
|
2
2
|
|
|
3
|
-
Version: 1.13.
|
|
3
|
+
Version: 1.13.12 | Generated: 2026-05-14T16:00:33.063Z
|
|
4
4
|
|
|
5
5
|
This is a concise summary of all available API functions and types.
|
|
6
6
|
|
|
@@ -3024,11 +3024,31 @@ interface EmailVerifyTokenResponse {
|
|
|
3024
3024
|
}
|
|
3025
3025
|
```
|
|
3026
3026
|
|
|
3027
|
+
**WhatsAppReplyCta** (interface)
|
|
3028
|
+
```typescript
|
|
3029
|
+
interface WhatsAppReplyCta {
|
|
3030
|
+
body: string
|
|
3031
|
+
buttonLabel: string
|
|
3032
|
+
buttonUrl: string
|
|
3033
|
+
}
|
|
3034
|
+
```
|
|
3035
|
+
|
|
3036
|
+
**WhatsAppReplyOptions** (interface)
|
|
3037
|
+
```typescript
|
|
3038
|
+
interface WhatsAppReplyOptions {
|
|
3039
|
+
contentSid?: string
|
|
3040
|
+
contentVariables?: Record<string, unknown>
|
|
3041
|
+
cta?: WhatsAppReplyCta
|
|
3042
|
+
text?: string
|
|
3043
|
+
}
|
|
3044
|
+
```
|
|
3045
|
+
|
|
3027
3046
|
**SendWhatsAppRequest** (interface)
|
|
3028
3047
|
```typescript
|
|
3029
3048
|
interface SendWhatsAppRequest {
|
|
3030
|
-
phoneNumber
|
|
3031
|
-
redirectUrl
|
|
3049
|
+
phoneNumber?: string
|
|
3050
|
+
redirectUrl?: string
|
|
3051
|
+
reply?: WhatsAppReplyOptions
|
|
3032
3052
|
}
|
|
3033
3053
|
```
|
|
3034
3054
|
|
|
@@ -8192,7 +8212,7 @@ Send phone verification code (public).
|
|
|
8192
8212
|
**verifyPhoneCode**(clientId: string, phoneNumber: string, code: string) → `Promise<PhoneVerifyResponse>`
|
|
8193
8213
|
Verify phone verification code (public).
|
|
8194
8214
|
|
|
8195
|
-
**sendWhatsApp**(clientId: string, body: SendWhatsAppRequest) → `Promise<SendWhatsAppResponse>`
|
|
8215
|
+
**sendWhatsApp**(clientId: string, body: SendWhatsAppRequest = {}) → `Promise<SendWhatsAppResponse>`
|
|
8196
8216
|
Send a WhatsApp verification deep-link (public).
|
|
8197
8217
|
|
|
8198
8218
|
**verifyWhatsApp**(clientId: string, token: string, phoneNumber: string) → `Promise<VerifyWhatsAppResponse>`
|
|
@@ -8803,54 +8823,54 @@ Legacy-friendly alias for aggregate().
|
|
|
8803
8823
|
|
|
8804
8824
|
**appendEvent**(collectionId: string,
|
|
8805
8825
|
body: AppendInteractionBody) → `Promise<`
|
|
8806
|
-
POST /admin/collection/:collectionId/interactions/append Appends one interaction event.
|
|
8826
|
+
POST /admin/collection/:collectionId/interactions/append Appends one interaction event. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions.
|
|
8807
8827
|
|
|
8808
8828
|
**updateEvent**(collectionId: string,
|
|
8809
8829
|
body: UpdateInteractionBody) → `Promise<`
|
|
8810
|
-
POST /admin/collection/:collectionId/interactions/append Appends one interaction event.
|
|
8830
|
+
POST /admin/collection/:collectionId/interactions/append Appends one interaction event. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions.
|
|
8811
8831
|
|
|
8812
8832
|
**submitPublicEvent**(collectionId: string,
|
|
8813
8833
|
body: AppendInteractionBody) → `Promise<SubmitInteractionResponse | SubmitInteractionError>`
|
|
8814
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8834
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8815
8835
|
|
|
8816
8836
|
**create**(collectionId: string,
|
|
8817
8837
|
body: CreateInteractionTypeBody) → `Promise<InteractionTypeRecord>`
|
|
8818
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8838
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8819
8839
|
|
|
8820
8840
|
**list**(collectionId: string,
|
|
8821
8841
|
query: ListInteractionTypesQuery = {}) → `Promise<InteractionTypeList>`
|
|
8822
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8842
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8823
8843
|
|
|
8824
8844
|
**get**(collectionId: string,
|
|
8825
8845
|
id: string) → `Promise<InteractionTypeRecord>`
|
|
8826
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8846
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8827
8847
|
|
|
8828
8848
|
**update**(collectionId: string,
|
|
8829
8849
|
id: string,
|
|
8830
8850
|
patchBody: UpdateInteractionTypeBody) → `Promise<InteractionTypeRecord>`
|
|
8831
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8851
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8832
8852
|
|
|
8833
8853
|
**remove**(collectionId: string,
|
|
8834
8854
|
id: string) → `Promise<void>`
|
|
8835
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8855
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8836
8856
|
|
|
8837
8857
|
**publicCountsByOutcome**(collectionId: string,
|
|
8838
8858
|
body: PublicInteractionsCountsByOutcomeRequest,
|
|
8839
8859
|
authToken?: string) → `Promise<OutcomeCount[]>`
|
|
8840
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8860
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8841
8861
|
|
|
8842
8862
|
**publicMyInteractions**(collectionId: string,
|
|
8843
8863
|
body: PublicInteractionsByUserRequest,
|
|
8844
8864
|
authToken?: string) → `Promise<InteractionEventRow[]>`
|
|
8845
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8865
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8846
8866
|
|
|
8847
8867
|
**publicList**(collectionId: string,
|
|
8848
8868
|
query: ListInteractionTypesQuery = {}) → `Promise<InteractionTypeList>`
|
|
8849
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8869
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8850
8870
|
|
|
8851
8871
|
**publicGet**(collectionId: string,
|
|
8852
8872
|
id: string) → `Promise<InteractionTypeRecord>`
|
|
8853
|
-
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8873
|
+
POST /api/v1/public/collection/:collectionId/interactions/submit Submits an interaction event from a public/client-side context. `interactionId` must reference an existing interaction type definition. This endpoint does not create interaction definitions. When the interaction has `allowAnonymousSubmit: true`, neither `userId` nor `contactId` is required. Pass `anonId` inside `metadata` to enable device-level deduplication via `uniquePerAnonId`.
|
|
8854
8874
|
|
|
8855
8875
|
### jobs
|
|
8856
8876
|
|
|
@@ -225,6 +225,8 @@ await SL.appConfiguration.setConfig({
|
|
|
225
225
|
|
|
226
226
|
### Tracked Interactions
|
|
227
227
|
|
|
228
|
+
Use interaction IDs that are defined via `SL.interactions.create(...)` for the collection. Do not invent ad-hoc IDs in app code.
|
|
229
|
+
|
|
228
230
|
| Interaction ID | Description |
|
|
229
231
|
| -------------- | --------------------------------------------- |
|
|
230
232
|
| `page-view` | Tracks each time a user views the public page |
|
package/docs/auth-kit.md
CHANGED
|
@@ -86,10 +86,20 @@ Use these flows when you want low-friction verification before or without full a
|
|
|
86
86
|
import { authKit } from '@proveanything/smartlinks';
|
|
87
87
|
|
|
88
88
|
// 1) Send WhatsApp verification deep link
|
|
89
|
-
const wa = await authKit.sendWhatsApp(clientId
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
89
|
+
const wa = await authKit.sendWhatsApp(clientId);
|
|
90
|
+
|
|
91
|
+
// Optional: pass redirect context and/or a post-verification reply
|
|
92
|
+
// const wa = await authKit.sendWhatsApp(clientId, {
|
|
93
|
+
// redirectUrl: 'https://app.example.com/checkout/continue',
|
|
94
|
+
// reply: {
|
|
95
|
+
// cta: {
|
|
96
|
+
// body: "You're verified and ready to bid.",
|
|
97
|
+
// buttonLabel: 'Back to Auction',
|
|
98
|
+
// buttonUrl: '{{returnUrl}}',
|
|
99
|
+
// },
|
|
100
|
+
// text: "You're verified. Return to the app to continue.",
|
|
101
|
+
// },
|
|
102
|
+
// });
|
|
93
103
|
|
|
94
104
|
// wa.waLink can be opened directly by the app/browser
|
|
95
105
|
// Poll status while user switches to WhatsApp and back
|
|
@@ -133,6 +143,27 @@ Verification status values returned by `authKit.getWhatsAppStatus` are:
|
|
|
133
143
|
- `expired`
|
|
134
144
|
- `unknown`
|
|
135
145
|
|
|
146
|
+
#### Post-verification reply
|
|
147
|
+
|
|
148
|
+
Pass a `reply` object in `sendWhatsApp` to send a message back to the user after they confirm `CONFIRM <token>`. Reply resolution order:
|
|
149
|
+
|
|
150
|
+
1. `reply.contentSid` — explicit Twilio Content SID
|
|
151
|
+
2. `reply.cta` — CTA shorthand using the shared generic Twilio Content template SID (`TWILIO_WHATSAPP_GENERIC_CTA_SID`)
|
|
152
|
+
3. `reply.text` — plain-text fallback
|
|
153
|
+
4. Per-client default (`authKit/{clientId}.whatsapp` config)
|
|
154
|
+
5. Built-in default text
|
|
155
|
+
|
|
156
|
+
The following template placeholders are available in `reply.text`, `reply.cta` fields, and `reply.contentVariables` values:
|
|
157
|
+
|
|
158
|
+
| Placeholder | Description |
|
|
159
|
+
|---|---|
|
|
160
|
+
| `{{returnUrl}}` | The resolved redirect URL |
|
|
161
|
+
| `{{phoneNumber}}` | The verified phone number |
|
|
162
|
+
| `{{clientId}}` | The Auth Kit client ID |
|
|
163
|
+
| `{{token}}` | The verification token |
|
|
164
|
+
|
|
165
|
+
> **Note:** `redirectUrl` is optional. WhatsApp tokens are short hex strings (16 chars) for better UX.
|
|
166
|
+
|
|
136
167
|
### Google OAuth
|
|
137
168
|
|
|
138
169
|
```ts
|
package/docs/interactions.md
CHANGED
|
@@ -15,15 +15,19 @@ Interactions have two distinct layers:
|
|
|
15
15
|
| **Interaction Types** | Definitions stored in the database — configure an interaction's ID, permissions, and display metadata once per collection |
|
|
16
16
|
| **Interaction Events** | Individual event records logged each time a user performs that interaction |
|
|
17
17
|
|
|
18
|
+
Critical rule: event `interactionId` values must reference an existing interaction type definition in that collection. Do not generate random IDs in app code and submit events against them.
|
|
19
|
+
|
|
18
20
|
```text
|
|
19
21
|
┌──────────────────────────────────────────────────────────────────┐
|
|
20
22
|
│ Your App │
|
|
21
23
|
│ │
|
|
22
24
|
│ 1. Create type once: interactions.create(collectionId, { │
|
|
23
25
|
│ id: 'vote', permissions: { uniquePerUser: true } }) │
|
|
26
|
+
│ -> definition exists in platform │
|
|
24
27
|
│ │
|
|
25
28
|
│ 2. Log events: interactions.appendEvent(collectionId, { │
|
|
26
29
|
│ interactionId: 'vote', outcome: 'option-a', userId }) │
|
|
30
|
+
│ (must match the created definition ID) │
|
|
27
31
|
│ │
|
|
28
32
|
│ 3. Read results: interactions.countsByOutcome(collectionId, │
|
|
29
33
|
│ { interactionId: 'vote' }) │
|
|
@@ -31,6 +35,14 @@ Interactions have two distinct layers:
|
|
|
31
35
|
└──────────────────────────────────────────────────────────────────┘
|
|
32
36
|
```
|
|
33
37
|
|
|
38
|
+
### Required Workflow (Do Not Invent IDs)
|
|
39
|
+
|
|
40
|
+
1. Create an interaction type definition (admin endpoint) before recording any events.
|
|
41
|
+
2. Reuse that same definition ID for every `appendEvent` / `submitPublicEvent` call.
|
|
42
|
+
3. Treat unknown IDs as configuration errors, not as values your app should auto-create.
|
|
43
|
+
|
|
44
|
+
If your app currently hardcodes strings like `"poll"` or `"entry"`, make sure those IDs are actually created as interaction types during setup.
|
|
45
|
+
|
|
34
46
|
---
|
|
35
47
|
|
|
36
48
|
## Common Use Cases
|
|
@@ -101,6 +113,8 @@ const { items } = await SL.interactions.publicList(collectionId, { appId: 'my-ap
|
|
|
101
113
|
|
|
102
114
|
## Logging Events
|
|
103
115
|
|
|
116
|
+
Before logging events, ensure the referenced interaction type already exists. Event ingestion is not intended to create new interaction definitions.
|
|
117
|
+
|
|
104
118
|
### Admin Event Append
|
|
105
119
|
|
|
106
120
|
Use on the server side or in admin flows. Requires `userId` **or** `contactId`.
|
|
@@ -166,7 +180,7 @@ await SL.interactions.updateEvent(collectionId, {
|
|
|
166
180
|
|
|
167
181
|
| Field | Type | Required | Description |
|
|
168
182
|
|-------|------|----------|-------------|
|
|
169
|
-
| `interactionId` | string | ✅ |
|
|
183
|
+
| `interactionId` | string | ✅ | Existing interaction type ID (must already be defined in this collection) |
|
|
170
184
|
| `userId` or `contactId` | string | ✅ (one of) | The actor. `appendEvent` / `updateEvent` require one of these |
|
|
171
185
|
| `appId` | string | ❌ | Scopes the event to your app |
|
|
172
186
|
| `outcome` | string | ❌ | The result or choice — what `countsByOutcome()` aggregates |
|
package/docs/loyalty.md
CHANGED
|
@@ -120,6 +120,8 @@ const { items } = await SL.loyalty.publicGetMineHistory(collectionId, schemeId,
|
|
|
120
120
|
|
|
121
121
|
Earning rules are the control plane that connects interactions to point awards. The server evaluates them automatically — your app never sets a point value directly.
|
|
122
122
|
|
|
123
|
+
Every `interactionId` in a loyalty rule must reference an existing interaction type definition in the same collection.
|
|
124
|
+
|
|
123
125
|
### Create a Rule
|
|
124
126
|
|
|
125
127
|
```typescript
|
package/docs/overview.md
CHANGED
|
@@ -227,6 +227,8 @@ See `docs/ai.md` for complete documentation.
|
|
|
227
227
|
|
|
228
228
|
The `SL.interactions` namespace tracks user engagement — competition entries, votes, form submissions, warranty registrations. Events can trigger automated journeys and communications.
|
|
229
229
|
|
|
230
|
+
Important: create interaction type definitions first, then submit events using those existing IDs. Do not invent `interactionId` values in client code.
|
|
231
|
+
|
|
230
232
|
Key functions: `submitPublicEvent()`, `appendEvent()` (admin), `countsByOutcome()`, `query()`.
|
|
231
233
|
|
|
232
234
|
See `docs/interactions.md` for complete documentation.
|
package/docs/realtime.md
CHANGED
|
@@ -590,6 +590,7 @@ When a user votes, publish to the channel:
|
|
|
590
590
|
```typescript
|
|
591
591
|
const submitVote = async (option: string) => {
|
|
592
592
|
// Record in SmartLinks
|
|
593
|
+
// 'poll' must already exist as an interaction type definition for this collection.
|
|
593
594
|
await SL.interactions.submitPublicEvent(collectionId, {
|
|
594
595
|
appId,
|
|
595
596
|
interactionId: 'poll',
|
package/openapi.yaml
CHANGED
|
@@ -17864,6 +17864,31 @@ components:
|
|
|
17864
17864
|
required:
|
|
17865
17865
|
- success
|
|
17866
17866
|
- message
|
|
17867
|
+
WhatsAppReplyCta:
|
|
17868
|
+
type: object
|
|
17869
|
+
properties:
|
|
17870
|
+
body:
|
|
17871
|
+
type: string
|
|
17872
|
+
buttonLabel:
|
|
17873
|
+
type: string
|
|
17874
|
+
buttonUrl:
|
|
17875
|
+
type: string
|
|
17876
|
+
required:
|
|
17877
|
+
- body
|
|
17878
|
+
- buttonLabel
|
|
17879
|
+
- buttonUrl
|
|
17880
|
+
WhatsAppReplyOptions:
|
|
17881
|
+
type: object
|
|
17882
|
+
properties:
|
|
17883
|
+
contentSid:
|
|
17884
|
+
type: string
|
|
17885
|
+
contentVariables:
|
|
17886
|
+
type: object
|
|
17887
|
+
additionalProperties: true
|
|
17888
|
+
cta:
|
|
17889
|
+
$ref: "#/components/schemas/WhatsAppReplyCta"
|
|
17890
|
+
text:
|
|
17891
|
+
type: string
|
|
17867
17892
|
SendWhatsAppRequest:
|
|
17868
17893
|
type: object
|
|
17869
17894
|
properties:
|
|
@@ -17871,9 +17896,8 @@ components:
|
|
|
17871
17896
|
type: string
|
|
17872
17897
|
redirectUrl:
|
|
17873
17898
|
type: string
|
|
17874
|
-
|
|
17875
|
-
|
|
17876
|
-
- redirectUrl
|
|
17899
|
+
reply:
|
|
17900
|
+
$ref: "#/components/schemas/WhatsAppReplyOptions"
|
|
17877
17901
|
SendWhatsAppResponse:
|
|
17878
17902
|
type: object
|
|
17879
17903
|
properties:
|