@proveanything/smartlinks 1.1.21 → 1.1.23

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/API_SUMMARY.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.1.21 | Generated: 2026-01-05T12:21:27.209Z
3
+ Version: 1.1.23 | Generated: 2026-01-07T13:11:08.113Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -46,7 +46,9 @@ The Smartlinks SDK is organized into the following namespaces:
46
46
  - **serialNumber** - Assign, lookup, and manage serial numbers across scopes.
47
47
 
48
48
  — Other —
49
+ - **async** - Functions for async operations
49
50
  - **attestation** - Functions for attestation operations
51
+ - **jobs** - Functions for jobs operations
50
52
  - **journeysAnalytics** - Functions for journeysAnalytics operations
51
53
  - **location** - Functions for location operations
52
54
  - **template** - Functions for template operations
@@ -849,6 +851,38 @@ interface UserSearchResponse {
849
851
  }
850
852
  ```
851
853
 
854
+ **ContactPublic** (interface)
855
+ ```typescript
856
+ interface ContactPublic {
857
+ contactId: string
858
+ firstName?: string | null
859
+ lastName?: string | null
860
+ displayName?: string | null
861
+ company?: string | null
862
+ avatarUrl?: string | null
863
+ locale?: string | null
864
+ timezone?: string | null
865
+ email?: string | null
866
+ phone?: string | null
867
+ externalIds?: Record<string, any>
868
+ customFields?: ContactCustomFields
869
+ }
870
+ ```
871
+
872
+ **PublicGetMyContactResponse** (interface)
873
+ ```typescript
874
+ interface PublicGetMyContactResponse {
875
+ ok: boolean; contact: ContactPublic | null
876
+ }
877
+ ```
878
+
879
+ **PublicUpdateMyContactResponse** (interface)
880
+ ```typescript
881
+ interface PublicUpdateMyContactResponse {
882
+ ok: boolean; contact: ContactPublic
883
+ }
884
+ ```
885
+
852
886
  **ContactCustomFields** = `Record<string, any>`
853
887
 
854
888
  **ContactResponse** = `Contact`
@@ -859,6 +893,8 @@ interface UserSearchResponse {
859
893
 
860
894
  **PublicContactUpsertRequest** = `Partial<`
861
895
 
896
+ **ContactPatch** = `Partial<`
897
+
862
898
  ### error
863
899
 
864
900
  **ErrorResponse** (interface)
@@ -1056,6 +1092,71 @@ interface ListInteractionTypesQuery {
1056
1092
  }
1057
1093
  ```
1058
1094
 
1095
+ ### jobs
1096
+
1097
+ **Job** (interface)
1098
+ ```typescript
1099
+ interface Job {
1100
+ id: number
1101
+ task: string
1102
+ payload: any
1103
+ priority: number
1104
+ runAt: string | null
1105
+ createdAt: string
1106
+ attempts: number
1107
+ lastError: string | null
1108
+ lockedAt: string | null
1109
+ key: string | null
1110
+ queueName: string | null
1111
+ status: JobStatus
1112
+ }
1113
+ ```
1114
+
1115
+ **ListJobsQuery** (interface)
1116
+ ```typescript
1117
+ interface ListJobsQuery {
1118
+ state?: JobStatus
1119
+ task?: string
1120
+ limit?: number
1121
+ offset?: number
1122
+ from?: string
1123
+ to?: string
1124
+ }
1125
+ ```
1126
+
1127
+ **JobsPage** (interface)
1128
+ ```typescript
1129
+ interface JobsPage {
1130
+ items: Job[]
1131
+ limit: number
1132
+ offset: number
1133
+ }
1134
+ ```
1135
+
1136
+ **EnqueueAsyncJobRequest** (interface)
1137
+ ```typescript
1138
+ interface EnqueueAsyncJobRequest {
1139
+ task: string
1140
+ payload?: Record<string, any>
1141
+ runAt?: string | Date
1142
+ priority?: number
1143
+ key?: string
1144
+ queueName?: string
1145
+ }
1146
+ ```
1147
+
1148
+ **EnqueueAsyncJobResponse** (interface)
1149
+ ```typescript
1150
+ interface EnqueueAsyncJobResponse {
1151
+ id: number
1152
+ task: string
1153
+ runAt?: string
1154
+ key?: string
1155
+ }
1156
+ ```
1157
+
1158
+ **JobStatus** = `'queued' | 'running' | 'errored'`
1159
+
1059
1160
  ### journeys
1060
1161
 
1061
1162
  **JourneyRecord** (interface)
@@ -1723,6 +1824,16 @@ Post a chat message to the AI (admin or public)
1723
1824
  onProgress?: (percent: number) → `void`
1724
1825
  Uploads an asset file to a proof, with optional extraData as JSON. Supports progress reporting via onProgress callback (browser only).
1725
1826
 
1827
+ ### async
1828
+
1829
+ **enqueueAsyncJob**(collectionId: string,
1830
+ params: EnqueueAsyncJobRequest) → `Promise<EnqueueAsyncJobResponse>`
1831
+ Enqueue a background job for a collection POST /admin/collection/:collectionId/async/jobs (202)
1832
+
1833
+ **getAsyncJobStatus**(collectionId: string,
1834
+ jobId: number) → `Promise<Job>`
1835
+ Get job status by ID (may return 404 if completed/removed) GET /admin/collection/:collectionId/async/jobs/:jobId
1836
+
1726
1837
  ### attestation
1727
1838
 
1728
1839
  **list**(collectionId: string,
@@ -1937,6 +2048,10 @@ Look up a serial number by code for a batch (admin only).
1937
2048
  id: string,
1938
2049
  body: BroadcastPreviewRequest) → `Promise<BroadcastPreviewResponse>`
1939
2050
 
2051
+ **send**(collectionId: string,
2052
+ id: string,
2053
+ body: { pageSize?: number; maxPages?: number; sharedContext?: Record<string, any>; subject?: string } = {}) → `Promise<`
2054
+
1940
2055
  **sendTest**(collectionId: string,
1941
2056
  id: string,
1942
2057
  body: BroadcastSendTestRequest) → `Promise<BroadcastSendTestResponse>`
@@ -2085,6 +2200,11 @@ Logging: Append many communication events for a list of IDs. POST /admin/collect
2085
2200
  **publicUpsert**(collectionId: string,
2086
2201
  data: PublicContactUpsertRequest) → `Promise<PublicContactUpsertResponse>`
2087
2202
 
2203
+ **publicGetMine**(collectionId: string) → `Promise<PublicGetMyContactResponse>`
2204
+
2205
+ **publicUpdateMine**(collectionId: string,
2206
+ data: ContactPatch) → `Promise<PublicUpdateMyContactResponse>`
2207
+
2088
2208
  **erase**(collectionId: string, contactId: string, body?: any) → `Promise<ContactResponse>`
2089
2209
 
2090
2210
  **getUser**(collectionId: string,
@@ -2185,6 +2305,16 @@ Appends one interaction event from a public source.
2185
2305
  id: string) → `Promise<InteractionTypeRecord>`
2186
2306
  Appends one interaction event from a public source.
2187
2307
 
2308
+ ### jobs
2309
+
2310
+ **listJobs**(collectionId: string,
2311
+ query: ListJobsQuery = {}) → `Promise<JobsPage>`
2312
+ List visible jobs for a collection GET /admin/collection/:collectionId/jobs
2313
+
2314
+ **getJob**(collectionId: string,
2315
+ jobId: number) → `Promise<Job>`
2316
+ Get a single job GET /admin/collection/:collectionId/jobs/:jobId
2317
+
2188
2318
  ### journeys
2189
2319
 
2190
2320
  **create**(collectionId: string,
package/README.md CHANGED
@@ -171,6 +171,60 @@ await broadcasts.appendBulk('collectionId', {
171
171
  })
172
172
  ```
173
173
 
174
+ ### Broadcast sending and previews
175
+
176
+ ```ts
177
+ import { broadcasts } from '@proveanything/smartlinks'
178
+
179
+ // Preview a broadcast (HTML)
180
+ const preview = await broadcasts.preview('collectionId', 'broadcastId', {
181
+ contactId: 'contact_123',
182
+ props: { firstName: 'Sam' },
183
+ })
184
+
185
+ // Send a test email
186
+ await broadcasts.sendTest('collectionId', 'broadcastId', {
187
+ to: 'test@example.com',
188
+ subject: 'Test subject',
189
+ props: { foo: 'bar' },
190
+ })
191
+
192
+ // Enqueue broadcast sending (background)
193
+ await broadcasts.send('collectionId', 'broadcastId', {
194
+ pageSize: 100,
195
+ sharedContext: { campaign: 'summer' },
196
+ })
197
+
198
+ // Manual page send (for testing/UX)
199
+ const manual = await broadcasts.sendManual('collectionId', 'broadcastId', {
200
+ limit: 50,
201
+ dryRun: true,
202
+ })
203
+ ```
204
+
205
+ ### Async jobs
206
+
207
+ ```ts
208
+ import { async as slAsync, jobs } from '@proveanything/smartlinks'
209
+
210
+ // Enqueue an async job
211
+ const queued = await slAsync.enqueueAsyncJob('collectionId', {
212
+ task: 'email:daily-digest',
213
+ payload: { segmentId: 'seg_1' },
214
+ priority: 5,
215
+ key: 'digest:seg_1',
216
+ })
217
+
218
+ // Check job status
219
+ const status = await slAsync.getAsyncJobStatus('collectionId', queued.id)
220
+
221
+ // List recent jobs
222
+ const recent = await jobs.listJobs('collectionId', { state: 'queued', limit: 20 })
223
+
224
+ // Get a single job
225
+ const job = await jobs.getJob('collectionId', queued.id)
226
+ ```
227
+
174
228
  ## Browser and React
175
229
 
176
230
  The SDK works in modern browsers. Initialize once and call public endpoints without an API key; authenticate to access protected/admin endpoints.
@@ -0,0 +1,13 @@
1
+ import type { EnqueueAsyncJobRequest, EnqueueAsyncJobResponse, Job } from "../types/jobs";
2
+ export declare namespace async {
3
+ /**
4
+ * Enqueue a background job for a collection
5
+ * POST /admin/collection/:collectionId/async/jobs (202)
6
+ */
7
+ function enqueueAsyncJob(collectionId: string, params: EnqueueAsyncJobRequest): Promise<EnqueueAsyncJobResponse>;
8
+ /**
9
+ * Get job status by ID (may return 404 if completed/removed)
10
+ * GET /admin/collection/:collectionId/async/jobs/:jobId
11
+ */
12
+ function getAsyncJobStatus(collectionId: string, jobId: number): Promise<Job>;
13
+ }
@@ -0,0 +1,24 @@
1
+ // src/api/async.ts
2
+ import { request, post } from "../http";
3
+ function enc(v) { return encodeURIComponent(v); }
4
+ export var async;
5
+ (function (async) {
6
+ /**
7
+ * Enqueue a background job for a collection
8
+ * POST /admin/collection/:collectionId/async/jobs (202)
9
+ */
10
+ async function enqueueAsyncJob(collectionId, params) {
11
+ const path = `/admin/collection/${enc(collectionId)}/async/jobs`;
12
+ return post(path, params);
13
+ }
14
+ async.enqueueAsyncJob = enqueueAsyncJob;
15
+ /**
16
+ * Get job status by ID (may return 404 if completed/removed)
17
+ * GET /admin/collection/:collectionId/async/jobs/:jobId
18
+ */
19
+ async function getAsyncJobStatus(collectionId, jobId) {
20
+ const path = `/admin/collection/${enc(collectionId)}/async/jobs/${jobId}`;
21
+ return request(path);
22
+ }
23
+ async.getAsyncJobStatus = getAsyncJobStatus;
24
+ })(async || (async = {}));
@@ -11,6 +11,16 @@ export declare namespace broadcasts {
11
11
  offset?: number;
12
12
  }): Promise<BroadcastRecipientsResponse>;
13
13
  function preview(collectionId: string, id: string, body: BroadcastPreviewRequest): Promise<BroadcastPreviewResponse>;
14
+ function send(collectionId: string, id: string, body?: {
15
+ pageSize?: number;
16
+ maxPages?: number;
17
+ sharedContext?: Record<string, any>;
18
+ subject?: string;
19
+ }): Promise<{
20
+ ok: true;
21
+ enqueued: true;
22
+ }>;
23
+ const sendBroadcast: typeof send;
14
24
  function sendTest(collectionId: string, id: string, body: BroadcastSendTestRequest): Promise<BroadcastSendTestResponse>;
15
25
  function sendManual(collectionId: string, id: string, body: BroadcastSendManualRequest): Promise<BroadcastSendManualResponse>;
16
26
  function append(collectionId: string, body: BroadcastAppendEventBody): Promise<AppendResult>;
@@ -60,6 +60,14 @@ export var broadcasts;
60
60
  return post(path, body);
61
61
  }
62
62
  broadcasts.preview = preview;
63
+ // Enqueue send for a broadcast (202 Accepted)
64
+ async function send(collectionId, id, body = {}) {
65
+ const path = `/admin/collection/${encodeURIComponent(collectionId)}/broadcasts/${encodeURIComponent(id)}/send`;
66
+ return post(path, body);
67
+ }
68
+ broadcasts.send = send;
69
+ // Alias for clarity with docs naming
70
+ broadcasts.sendBroadcast = send;
63
71
  // Send a single test email
64
72
  async function sendTest(collectionId, id, body) {
65
73
  const path = `/admin/collection/${encodeURIComponent(collectionId)}/broadcasts/${encodeURIComponent(id)}/send/test`;
@@ -1,4 +1,4 @@
1
- import { ContactResponse, ContactCreateRequest, ContactUpdateRequest, ContactListResponse, PublicContactUpsertRequest, PublicContactUpsertResponse, UserSearchResponse } from "../types";
1
+ import { ContactResponse, ContactCreateRequest, ContactUpdateRequest, ContactListResponse, PublicContactUpsertRequest, PublicContactUpsertResponse, UserSearchResponse, ContactPatch, PublicGetMyContactResponse, PublicUpdateMyContactResponse } from "../types";
2
2
  export declare namespace contact {
3
3
  function create(collectionId: string, data: ContactCreateRequest): Promise<ContactResponse>;
4
4
  function list(collectionId: string, params?: {
@@ -17,6 +17,8 @@ export declare namespace contact {
17
17
  }): Promise<ContactResponse>;
18
18
  function upsert(collectionId: string, data: ContactCreateRequest): Promise<ContactResponse>;
19
19
  function publicUpsert(collectionId: string, data: PublicContactUpsertRequest): Promise<PublicContactUpsertResponse>;
20
+ function publicGetMine(collectionId: string): Promise<PublicGetMyContactResponse>;
21
+ function publicUpdateMine(collectionId: string, data: ContactPatch): Promise<PublicUpdateMyContactResponse>;
20
22
  function erase(collectionId: string, contactId: string, body?: any): Promise<ContactResponse>;
21
23
  function getUser(collectionId: string, userId: string): Promise<UserSearchResponse>;
22
24
  }
@@ -59,6 +59,18 @@ export var contact;
59
59
  return post(path, data);
60
60
  }
61
61
  contact.publicUpsert = publicUpsert;
62
+ // Public: Get "my" contact (requires auth bearer token)
63
+ async function publicGetMine(collectionId) {
64
+ const path = `/public/collection/${encodeURIComponent(collectionId)}/contact/me`;
65
+ return request(path);
66
+ }
67
+ contact.publicGetMine = publicGetMine;
68
+ // Public: Update "my" contact (requires auth bearer token)
69
+ async function publicUpdateMine(collectionId, data) {
70
+ const path = `/public/collection/${encodeURIComponent(collectionId)}/contact/me`;
71
+ return patch(path, data);
72
+ }
73
+ contact.publicUpdateMine = publicUpdateMine;
62
74
  async function erase(collectionId, contactId, body) {
63
75
  const path = `/admin/collection/${encodeURIComponent(collectionId)}/contacts/${encodeURIComponent(contactId)}/erase`;
64
76
  return post(path, body || {});
@@ -17,6 +17,8 @@ export { comms } from "./comms";
17
17
  export { nfc } from "./nfc";
18
18
  export { contact } from "./contact";
19
19
  export { broadcasts } from "./broadcasts";
20
+ export { async } from "./async";
21
+ export { jobs } from "./jobs";
20
22
  export { segments } from "./segments";
21
23
  export { journeys } from "./journeys";
22
24
  export { journeysAnalytics } from "./journeysAnalytics";
package/dist/api/index.js CHANGED
@@ -19,6 +19,8 @@ export { comms } from "./comms";
19
19
  export { nfc } from "./nfc";
20
20
  export { contact } from "./contact";
21
21
  export { broadcasts } from "./broadcasts";
22
+ export { async } from "./async";
23
+ export { jobs } from "./jobs";
22
24
  export { segments } from "./segments";
23
25
  export { journeys } from "./journeys";
24
26
  export { journeysAnalytics } from "./journeysAnalytics";
@@ -0,0 +1,13 @@
1
+ import type { JobsPage, ListJobsQuery, Job } from "../types/jobs";
2
+ export declare namespace jobs {
3
+ /**
4
+ * List visible jobs for a collection
5
+ * GET /admin/collection/:collectionId/jobs
6
+ */
7
+ function listJobs(collectionId: string, query?: ListJobsQuery): Promise<JobsPage>;
8
+ /**
9
+ * Get a single job
10
+ * GET /admin/collection/:collectionId/jobs/:jobId
11
+ */
12
+ function getJob(collectionId: string, jobId: number): Promise<Job>;
13
+ }
@@ -0,0 +1,35 @@
1
+ // src/api/jobs.ts
2
+ import { request } from "../http";
3
+ function enc(v) { return encodeURIComponent(v); }
4
+ function encodeQuery(params = {}) {
5
+ const search = new URLSearchParams();
6
+ for (const [key, value] of Object.entries(params)) {
7
+ if (value === undefined || value === null || value === '')
8
+ continue;
9
+ search.set(key, String(value));
10
+ }
11
+ const qs = search.toString();
12
+ return qs ? `?${qs}` : '';
13
+ }
14
+ export var jobs;
15
+ (function (jobs) {
16
+ /**
17
+ * List visible jobs for a collection
18
+ * GET /admin/collection/:collectionId/jobs
19
+ */
20
+ async function listJobs(collectionId, query = {}) {
21
+ const qs = encodeQuery(query);
22
+ const path = `/admin/collection/${enc(collectionId)}/jobs${qs}`;
23
+ return request(path);
24
+ }
25
+ jobs.listJobs = listJobs;
26
+ /**
27
+ * Get a single job
28
+ * GET /admin/collection/:collectionId/jobs/:jobId
29
+ */
30
+ async function getJob(collectionId, jobId) {
31
+ const path = `/admin/collection/${enc(collectionId)}/jobs/${jobId}`;
32
+ return request(path);
33
+ }
34
+ jobs.getJob = getJob;
35
+ })(jobs || (jobs = {}));
@@ -50,3 +50,28 @@ export interface UserSearchResponse {
50
50
  contact: ContactResponse | null;
51
51
  existsAsContact: boolean;
52
52
  }
53
+ export interface ContactPublic {
54
+ contactId: string;
55
+ firstName?: string | null;
56
+ lastName?: string | null;
57
+ displayName?: string | null;
58
+ company?: string | null;
59
+ avatarUrl?: string | null;
60
+ locale?: string | null;
61
+ timezone?: string | null;
62
+ email?: string | null;
63
+ phone?: string | null;
64
+ externalIds?: Record<string, any>;
65
+ customFields?: ContactCustomFields;
66
+ }
67
+ export type ContactPatch = Partial<Pick<Contact, "firstName" | "lastName" | "displayName" | "company" | "avatarUrl" | "locale" | "timezone" | "email" | "phone" | "externalIds">> & {
68
+ customFields?: ContactCustomFields;
69
+ };
70
+ export interface PublicGetMyContactResponse {
71
+ ok: boolean;
72
+ contact: ContactPublic | null;
73
+ }
74
+ export interface PublicUpdateMyContactResponse {
75
+ ok: boolean;
76
+ contact: ContactPublic;
77
+ }
@@ -20,3 +20,4 @@ export * from "./qr";
20
20
  export * from "./template";
21
21
  export * from "./interaction";
22
22
  export * from "./location";
23
+ export * from "./jobs";
@@ -22,3 +22,4 @@ export * from "./qr";
22
22
  export * from "./template";
23
23
  export * from "./interaction";
24
24
  export * from "./location";
25
+ export * from "./jobs";
@@ -0,0 +1,42 @@
1
+ export type JobStatus = 'queued' | 'running' | 'errored';
2
+ export interface Job {
3
+ id: number;
4
+ task: string;
5
+ payload: any;
6
+ priority: number;
7
+ runAt: string | null;
8
+ createdAt: string;
9
+ attempts: number;
10
+ lastError: string | null;
11
+ lockedAt: string | null;
12
+ key: string | null;
13
+ queueName: string | null;
14
+ status: JobStatus;
15
+ }
16
+ export interface ListJobsQuery {
17
+ state?: JobStatus;
18
+ task?: string;
19
+ limit?: number;
20
+ offset?: number;
21
+ from?: string;
22
+ to?: string;
23
+ }
24
+ export interface JobsPage {
25
+ items: Job[];
26
+ limit: number;
27
+ offset: number;
28
+ }
29
+ export interface EnqueueAsyncJobRequest {
30
+ task: string;
31
+ payload?: Record<string, any>;
32
+ runAt?: string | Date;
33
+ priority?: number;
34
+ key?: string;
35
+ queueName?: string;
36
+ }
37
+ export interface EnqueueAsyncJobResponse {
38
+ id: number;
39
+ task: string;
40
+ runAt?: string;
41
+ key?: string;
42
+ }
@@ -0,0 +1,2 @@
1
+ // src/types/jobs.ts
2
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proveanything/smartlinks",
3
- "version": "1.1.21",
3
+ "version": "1.1.23",
4
4
  "description": "Official JavaScript/TypeScript SDK for the Smartlinks API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",