@proveanything/smartlinks 1.8.4 → 1.8.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.8.4 | Generated: 2026-03-14T10:47:38.203Z
3
+ Version: 1.8.6 | Generated: 2026-03-17T21:25:13.155Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -30,6 +30,18 @@ For detailed guides on specific features:
30
30
  - **[AI-Native App Manifests](manifests.md)** - How AI workflows discover, configure, and import apps via structured manifests and prose guides
31
31
  - **[AI Guide Template](ai-guide-template.md)** - A sample for an app on how to build an AI setup guide
32
32
 
33
+ ## Choosing App Storage
34
+
35
+ When you need flexible app-specific data, choose the storage model based on shape and lifecycle, not just on what can hold JSON.
36
+
37
+ - **`appConfiguration.getConfig` / `setConfig`** - One config blob per scope. Best for settings, feature flags, and app setup.
38
+ - **`appConfiguration.getData` / `getDataItem` / `setDataItem`** - Small keyed documents attached to a scope. Best for lookup tables, content fragments, menus, FAQs, or a handful of standalone items where you already know the ID.
39
+ - **`app.records`** - Default choice for richer app-owned entities that need status, visibility, ownership zones, querying, filtering, parent-child links, or lifecycle fields.
40
+ - **`app.cases`** - Use when the entity is a workflow item that moves toward resolution and may need assignment, priority, and history.
41
+ - **`app.threads`** - Use for conversations, comments, Q&A, or any object centered on replies.
42
+
43
+ Rule of thumb: if you are modelling a real domain object that users will browse, filter, secure, or evolve over time, start with app objects. If you just need a simple keyed payload hanging off a collection or product, scoped data items are still a good fit.
44
+
33
45
  ## API Namespaces
34
46
 
35
47
  The Smartlinks SDK is organized into the following namespaces:
@@ -43,6 +55,7 @@ The Smartlinks SDK is organized into the following namespaces:
43
55
  - **crate** - Organize products in containers/crates for logistics and grouping.
44
56
  - **form** - Build and manage dynamic forms used by apps and workflows.
45
57
  - **appConfiguration** - Read/write app configuration and scoped data (collection/product/proof); hosts the deep-link registry. → [Guide](deep-link-discovery.md)
58
+ - **app** - Flexible app-scoped objects: use records for structured entities, cases for workflows, and threads for discussions. → [Guide](app-objects.md)
46
59
 
47
60
  — Identity & Access —
48
61
  - **auth** - Admin authentication and account ops: login/logout, tokens, account info.
@@ -72,7 +85,6 @@ The Smartlinks SDK is organized into the following namespaces:
72
85
 
73
86
  — Other —
74
87
  - **analytics** - Functions for analytics operations
75
- - **appObjects** - Functions for appObjects operations
76
88
  - **async** - Functions for async operations
77
89
  - **attestation** - Functions for attestation operations
78
90
  - **attestations** - Functions for attestations operations
@@ -1283,6 +1295,39 @@ interface AppConfigurationResponse {
1283
1295
  }
1284
1296
  ```
1285
1297
 
1298
+ **GetWidgetInstanceOptions** (interface)
1299
+ ```typescript
1300
+ interface GetWidgetInstanceOptions {
1301
+ appId: string
1302
+ collectionId?: string
1303
+ productId?: string
1304
+ variantId?: string
1305
+ batchId?: string
1306
+ admin?: boolean
1307
+ widgetId: string
1308
+ }
1309
+ ```
1310
+
1311
+ **WidgetInstance<TWidget = any>** (interface)
1312
+ ```typescript
1313
+ interface WidgetInstance<TWidget = any> {
1314
+ id: string
1315
+ name?: string
1316
+ widget?: TWidget
1317
+ [key: string]: any
1318
+ }
1319
+ ```
1320
+
1321
+ **WidgetInstanceSummary** (interface)
1322
+ ```typescript
1323
+ interface WidgetInstanceSummary {
1324
+ id: string
1325
+ name: string
1326
+ type?: string
1327
+ [key: string]: any
1328
+ }
1329
+ ```
1330
+
1286
1331
  ### appManifest
1287
1332
 
1288
1333
  **AppBundle** (interface)
@@ -1324,6 +1369,16 @@ interface AppWidgetComponent {
1324
1369
  }
1325
1370
  ```
1326
1371
 
1372
+ **AppManifestWidgets** (interface)
1373
+ ```typescript
1374
+ interface AppManifestWidgets {
1375
+ files: AppManifestFiles;
1376
+ components: AppWidgetComponent[];
1377
+ instanceResolution?: boolean;
1378
+ instanceParam?: string;
1379
+ }
1380
+ ```
1381
+
1327
1382
  **AppContainerComponent** (interface)
1328
1383
  ```typescript
1329
1384
  interface AppContainerComponent {
@@ -1525,10 +1580,7 @@ interface AppManifest {
1525
1580
  * (setup questions, import schema, tunable fields, metrics definitions).
1526
1581
  * Absent when the app has no admin UI.
1527
1582
  admin?: string;
1528
- widgets?: {
1529
- files: AppManifestFiles;
1530
- components: AppWidgetComponent[];
1531
- };
1583
+ widgets?: AppManifestWidgets;
1532
1584
  containers?: {
1533
1585
  files: AppManifestFiles;
1534
1586
  components: AppContainerComponent[];
@@ -5787,7 +5839,7 @@ type AppConfigOptions = {
5787
5839
 
5788
5840
  /** Configuration object for setConfig */
5789
5841
  config?: any
5790
- /** Data object for setDataItem */
5842
+ /** Data object for setDataItem. Best for small keyed scoped documents rather than richer app domain objects. */
5791
5843
  data?: any
5792
5844
  }
5793
5845
  ```
@@ -5818,145 +5870,118 @@ type VerifyTokenResponse = {
5818
5870
 
5819
5871
  ## API Functions
5820
5872
 
5821
- ### analytics
5822
-
5823
- **track**(event: CollectionAnalyticsEvent,
5824
- options?: AnalyticsTrackOptions) → `AnalyticsTrackResult`
5825
- Fire-and-forget collection analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5826
-
5827
- **track**(event: TagAnalyticsEvent,
5828
- options?: AnalyticsTrackOptions) → `AnalyticsTrackResult`
5829
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5830
-
5831
- **configure**(config: AnalyticsBrowserConfig) → `void`
5832
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5833
-
5834
- **getSessionId**() → `AnalyticsSessionId | undefined`
5835
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5836
-
5837
- **getVisitorId**() → `string | undefined`
5838
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5839
-
5840
- **setVisitorId**(visitorId: string,
5841
- options?: AnalyticsVisitorIdOptions) → `string`
5842
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5843
-
5844
- **clearVisitorId**(options?: Pick<AnalyticsVisitorIdOptions, 'storage' | 'storageKey'>) → `void`
5845
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5846
-
5847
- **captureCampaignParams**(search?: string) → `Partial<CollectionAnalyticsEvent>`
5848
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5849
-
5850
- **setLocation**(location: TagAnalyticsEvent['location'] | null) → `void`
5851
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5852
-
5853
- **clearLocation**() → `void`
5854
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5855
-
5856
- **getLocation**() → `TagAnalyticsEvent['location'] | undefined`
5857
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5858
-
5859
- **detectDevice**() → `CollectionAnalyticsEvent['deviceType']`
5860
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5861
-
5862
- **captureLocation**(options: AnalyticsGeolocationCaptureOptions = {}) → `Promise<TagAnalyticsEvent['location'] | null>`
5863
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5864
-
5865
- **trackCollection**(event: Partial<CollectionAnalyticsEvent>,
5866
- options?: AnalyticsTrackOptions) → `AnalyticsTrackResult`
5867
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5868
-
5869
- **trackTag**(event: Partial<TagAnalyticsEvent>,
5870
- options?: AnalyticsTrackOptions) → `AnalyticsTrackResult`
5871
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5872
-
5873
- **trackPageView**(event: Partial<CollectionAnalyticsEvent>,
5874
- options?: AnalyticsTrackOptions) → `AnalyticsTrackResult`
5875
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5876
-
5877
- **trackLinkClick**(event: AnalyticsLinkClickInput,
5878
- options?: AnalyticsTrackOptions) → `AnalyticsTrackResult`
5879
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5880
-
5881
- **trackTagScan**(event: Partial<TagAnalyticsEvent>,
5882
- options?: AnalyticsTrackOptions) → `AnalyticsTrackResult`
5883
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5884
-
5885
- **bindPageViews**(binding: AnalyticsPageViewBindingOptions = {}) → `() => void`
5886
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5887
-
5888
- **bindLinkTracking**(binding: AnalyticsLinkBindingOptions = {}) → `() => void`
5889
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5873
+ ### analytics.admin
5890
5874
 
5891
5875
  **summary**(collectionId: string,
5892
5876
  body: AnalyticsSummaryRequest) → `Promise<AnalyticsSummaryResponse>`
5893
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5894
5877
 
5895
5878
  **timeseries**(collectionId: string,
5896
5879
  body: AnalyticsTimeseriesRequest) → `Promise<AnalyticsTimeseriesResponse>`
5897
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5898
5880
 
5899
5881
  **breakdown**(collectionId: string,
5900
5882
  body: AnalyticsBreakdownRequest) → `Promise<AnalyticsBreakdownResponse>`
5901
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5902
5883
 
5903
5884
  **events**(collectionId: string,
5904
5885
  body: AnalyticsEventsRequest) → `Promise<AnalyticsEventsResponse>`
5905
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5906
5886
 
5907
5887
  **web**(collectionId: string,
5908
5888
  body: LegacyAnalyticsRequest = {}) → `Promise<AnalyticsDashboardResponse>`
5909
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5910
5889
 
5911
5890
  **clicks**(collectionId: string,
5912
5891
  body: LegacyAnalyticsRequest = {}) → `Promise<AnalyticsDashboardResponse>`
5913
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5914
5892
 
5915
5893
  **tagScans**(collectionId: string,
5916
5894
  body: LegacyAnalyticsRequest = {}) → `Promise<AnalyticsDashboardResponse>`
5917
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5918
5895
 
5919
5896
  **products**(collectionId: string,
5920
5897
  body: LegacyAnalyticsRequest = {}) → `Promise<AnalyticsProductsResponse>`
5921
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5922
5898
 
5923
5899
  **qrCodes**(collectionId: string,
5924
5900
  body: LegacyAnalyticsRequest = {}) → `Promise<AnalyticsQrCodesResponse>`
5925
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5926
5901
 
5927
5902
  **tags**(collectionId: string,
5928
5903
  body: LegacyAnalyticsRequest = {}) → `Promise<AnalyticsTagsResponse>`
5929
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5930
5904
 
5931
5905
  **weekly**(collectionId: string,
5932
5906
  body: AnalyticsWeeklyRequest = {}) → `Promise<AnalyticsTimeseriesResponse>`
5933
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5934
5907
 
5935
5908
  **country**(collectionId: string,
5936
5909
  body: AnalyticsCountryRequest = {}) → `Promise<AnalyticsBreakdownResponse>`
5937
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5938
5910
 
5939
5911
  **topPages**(collectionId: string,
5940
5912
  body: AnalyticsClassicReportRequest = {}) → `Promise<AnalyticsBreakdownResponse>`
5941
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5942
5913
 
5943
5914
  **topReferrers**(collectionId: string,
5944
5915
  body: AnalyticsClassicReportRequest = {}) → `Promise<AnalyticsBreakdownResponse>`
5945
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5946
5916
 
5947
5917
  **topCampaigns**(collectionId: string,
5948
5918
  body: AnalyticsClassicReportRequest = {}) → `Promise<AnalyticsBreakdownResponse>`
5949
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5950
5919
 
5951
5920
  **topSources**(collectionId: string,
5952
5921
  body: AnalyticsClassicReportRequest = {}) → `Promise<AnalyticsBreakdownResponse>`
5953
- Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5954
5922
 
5955
5923
  **topDestinations**(collectionId: string,
5956
5924
  body: AnalyticsClassicReportRequest = {}) → `Promise<AnalyticsBreakdownResponse>`
5925
+
5926
+ ### analytics.browser
5927
+
5928
+ **configure**(config: AnalyticsBrowserConfig) → `void`
5929
+
5930
+ **getSessionId**() → `AnalyticsSessionId | undefined`
5931
+
5932
+ **getVisitorId**() → `string | undefined`
5933
+
5934
+ **setVisitorId**(visitorId: string,
5935
+ options?: AnalyticsVisitorIdOptions) → `string`
5936
+
5937
+ **clearVisitorId**(options?: Pick<AnalyticsVisitorIdOptions, 'storage' | 'storageKey'>) → `void`
5938
+
5939
+ **captureCampaignParams**(search?: string) → `Partial<CollectionAnalyticsEvent>`
5940
+
5941
+ **setLocation**(location: TagAnalyticsEvent['location'] | null) → `void`
5942
+
5943
+ **clearLocation**() → `void`
5944
+
5945
+ **getLocation**() → `TagAnalyticsEvent['location'] | undefined`
5946
+
5947
+ **detectDevice**() → `CollectionAnalyticsEvent['deviceType']`
5948
+
5949
+ **captureLocation**(options: AnalyticsGeolocationCaptureOptions = {}) → `Promise<TagAnalyticsEvent['location'] | null>`
5950
+
5951
+ **trackCollection**(event: Partial<CollectionAnalyticsEvent>,
5952
+ options?: AnalyticsTrackOptions) → `AnalyticsTrackResult`
5953
+
5954
+ **trackTag**(event: Partial<TagAnalyticsEvent>,
5955
+ options?: AnalyticsTrackOptions) → `AnalyticsTrackResult`
5956
+
5957
+ **trackPageView**(event: Partial<CollectionAnalyticsEvent>,
5958
+ options?: AnalyticsTrackOptions) → `AnalyticsTrackResult`
5959
+
5960
+ **trackLinkClick**(event: AnalyticsLinkClickInput,
5961
+ options?: AnalyticsTrackOptions) → `AnalyticsTrackResult`
5962
+
5963
+ **trackTagScan**(event: Partial<TagAnalyticsEvent>,
5964
+ options?: AnalyticsTrackOptions) → `AnalyticsTrackResult`
5965
+
5966
+ **bindPageViews**(binding: AnalyticsPageViewBindingOptions = {}) → `() => void`
5967
+
5968
+ **bindLinkTracking**(binding: AnalyticsLinkBindingOptions = {}) → `() => void`
5969
+
5970
+ ### analytics.collection
5971
+
5972
+ **track**(event: CollectionAnalyticsEvent,
5973
+ options?: AnalyticsTrackOptions) → `AnalyticsTrackResult`
5974
+ Fire-and-forget collection analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5975
+
5976
+ ### analytics.tag
5977
+
5978
+ **track**(event: TagAnalyticsEvent,
5979
+ options?: AnalyticsTrackOptions) → `AnalyticsTrackResult`
5957
5980
  Fire-and-forget tag analytics event. Uses `navigator.sendBeacon()` when available, falling back to `fetch(..., { keepalive: true })`.
5958
5981
 
5959
- ### app
5982
+ ### app.cases
5983
+
5984
+ Workflow-oriented app objects for issues, requests, claims, and tasks that move through statuses and often need assignment or history.
5960
5985
 
5961
5986
  **create**(collectionId: string,
5962
5987
  appId: string,
@@ -6011,11 +6036,108 @@ Append an entry to case history (admin only) POST /cases/:caseId/history
6011
6036
  caseId: string) → `Promise<RelatedResponse>`
6012
6037
  Get related threads and records for a case (admin only) GET /cases/:caseId/related
6013
6038
 
6039
+ ### app.records
6040
+
6041
+ General-purpose structured app objects. Use these when a simple scoped data item grows into something queryable, lifecycle-aware, or access-controlled.
6042
+
6043
+ **create**(collectionId: string,
6044
+ appId: string,
6045
+ input: CreateRecordInput,
6046
+ admin: boolean = false) → `Promise<AppRecord>`
6047
+ Create a new record POST /records
6048
+
6049
+ **list**(collectionId: string,
6050
+ appId: string,
6051
+ params?: RecordListQueryParams,
6052
+ admin: boolean = false) → `Promise<PaginatedResponse<AppRecord>>`
6053
+ List records with optional query parameters GET /records
6054
+
6055
+ **get**(collectionId: string,
6056
+ appId: string,
6057
+ recordId: string,
6058
+ admin: boolean = false) → `Promise<AppRecord>`
6059
+ Get a single record by ID GET /records/:recordId
6060
+
6061
+ **update**(collectionId: string,
6062
+ appId: string,
6063
+ recordId: string,
6064
+ input: UpdateRecordInput,
6065
+ admin: boolean = false) → `Promise<AppRecord>`
6066
+ Update a record PATCH /records/:recordId Admin can update any field, public (owner) can only update data and owner
6067
+
6068
+ **remove**(collectionId: string,
6069
+ appId: string,
6070
+ recordId: string,
6071
+ admin: boolean = false) → `Promise<`
6072
+ Soft delete a record DELETE /records/:recordId
6073
+
6074
+ **aggregate**(collectionId: string,
6075
+ appId: string,
6076
+ request: AggregateRequest,
6077
+ admin: boolean = false) → `Promise<AggregateResponse>`
6078
+ Get aggregate statistics for records POST /records/aggregate
6079
+
6080
+ ### app.threads
6081
+
6082
+ Conversation-oriented app objects for comments, discussions, Q&A, and reply-driven experiences.
6083
+
6084
+ **create**(collectionId: string,
6085
+ appId: string,
6086
+ input: CreateThreadInput,
6087
+ admin: boolean = false) → `Promise<AppThread>`
6088
+ Create a new thread POST /threads
6089
+
6090
+ **list**(collectionId: string,
6091
+ appId: string,
6092
+ params?: ThreadListQueryParams,
6093
+ admin: boolean = false) → `Promise<PaginatedResponse<AppThread>>`
6094
+ List threads with optional query parameters GET /threads
6095
+
6096
+ **get**(collectionId: string,
6097
+ appId: string,
6098
+ threadId: string,
6099
+ admin: boolean = false) → `Promise<AppThread>`
6100
+ Get a single thread by ID GET /threads/:threadId
6101
+
6102
+ **update**(collectionId: string,
6103
+ appId: string,
6104
+ threadId: string,
6105
+ input: UpdateThreadInput,
6106
+ admin: boolean = false) → `Promise<AppThread>`
6107
+ Update a thread PATCH /threads/:threadId Admin can update any field, public (owner) can only update body, tags, data, owner
6108
+
6109
+ **remove**(collectionId: string,
6110
+ appId: string,
6111
+ threadId: string,
6112
+ admin: boolean = false) → `Promise<`
6113
+ Soft delete a thread DELETE /threads/:threadId
6114
+
6115
+ **reply**(collectionId: string,
6116
+ appId: string,
6117
+ threadId: string,
6118
+ input: ReplyInput,
6119
+ admin: boolean = false) → `Promise<AppThread>`
6120
+ Add a reply to a thread POST /threads/:threadId/reply Atomically appends to replies array, increments replyCount, updates lastReplyAt
6121
+
6122
+ **aggregate**(collectionId: string,
6123
+ appId: string,
6124
+ request: AggregateRequest,
6125
+ admin: boolean = false) → `Promise<AggregateResponse>`
6126
+ Get aggregate statistics for threads POST /threads/aggregate
6127
+
6014
6128
  ### appConfiguration
6015
6129
 
6130
+ Scoped config and keyed data items for collections, products, variants, or batches. Best for settings and small standalone documents, not as the default answer for every app-owned entity.
6131
+
6016
6132
  **getConfig**(opts: AppConfigOptions) → `Promise<any>`
6017
6133
  Get app configuration for a collection/product scope. ```typescript const config = await appConfiguration.getConfig({ appId: 'warranty-portal', collectionId: 'my-collection' }); ```
6018
6134
 
6135
+ **getWidgetInstance**(opts: GetWidgetInstanceOptions) → `Promise<WidgetInstance<TWidget>>`
6136
+ Resolve a configured widget instance by ID from an app's stored config. This is a thin convenience wrapper over `getConfig()` that reads `config.widgets[widgetId]`. ```typescript const widget = await appConfiguration.getWidgetInstance({ collectionId: 'my-collection', appId: 'widget-toolkit', widgetId: 'launch-countdown' }) ```
6137
+
6138
+ **listWidgetInstances**(opts: Omit<GetWidgetInstanceOptions, 'widgetId'>) → `Promise<WidgetInstanceSummary[]>`
6139
+ List configured widget instances for an app. Useful for picker UIs, setup schemas, and widget-to-widget references. ```typescript const widgets = await appConfiguration.listWidgetInstances({ collectionId: 'my-collection', appId: 'widget-toolkit' }) ```
6140
+
6019
6141
  **setConfig**(opts: AppConfigOptions) → `Promise<any>`
6020
6142
  Set app configuration for a collection/product scope. Requires admin authentication. ```typescript await appConfiguration.setConfig({ appId: 'warranty-portal', collectionId: 'my-collection', admin: true, config: { warrantyPeriod: 24, supportEmail: 'support@example.com' } }); ```
6021
6143
 
@@ -6023,16 +6145,16 @@ Set app configuration for a collection/product scope. Requires admin authenticat
6023
6145
  Delete app configuration for a collection/product scope. Requires admin authentication. ```typescript await appConfiguration.deleteConfig({ appId: 'warranty-portal', collectionId: 'my-collection', admin: true }); ```
6024
6146
 
6025
6147
  **getData**(opts: AppConfigOptions) → `Promise<any[]>`
6026
- Get all data items for an app within a scope. ```typescript const items = await appConfiguration.getData({ appId: 'product-docs', collectionId: 'my-collection', productId: 'product-123' }); ```
6148
+ Get all keyed data items for an app within a scope. Best for a small set of standalone documents such as FAQs, menus, lookup tables, or content fragments where the caller typically knows the item IDs. If you are modelling richer app entities that need filtering, lifecycle fields, visibility, ownership, or relationships, prefer `app.records`, `app.cases`, or `app.threads` instead. ```typescript const items = await appConfiguration.getData({ appId: 'product-docs', collectionId: 'my-collection', productId: 'product-123' }); ```
6027
6149
 
6028
6150
  **getDataItem**(opts: AppConfigOptions) → `Promise<any>`
6029
- Get a single data item by ID within a scope. ```typescript const item = await appConfiguration.getDataItem({ appId: 'product-docs', collectionId: 'my-collection', productId: 'product-123', itemId: 'manual-1' }); ```
6151
+ Get a single keyed data item by ID within a scope. This is ideal when you already know the exact ID of a simple scoped document. For richer domain objects that users browse or query, prefer `app.records`, `app.cases`, or `app.threads`. ```typescript const item = await appConfiguration.getDataItem({ appId: 'product-docs', collectionId: 'my-collection', productId: 'product-123', itemId: 'manual-1' }); ```
6030
6152
 
6031
6153
  **setDataItem**(opts: AppConfigOptions) → `Promise<any>`
6032
- Set/create a data item within a scope. Requires admin authentication. ```typescript await appConfiguration.setDataItem({ appId: 'product-docs', collectionId: 'my-collection', productId: 'product-123', admin: true, data: { id: 'manual-1', title: 'User Manual', url: 'https://...' } }); ```
6154
+ Set/create a keyed data item within a scope. Requires admin authentication. Use this for simple scoped documents attached to a collection/product/variant/batch, especially when you want a small number of items with stable IDs. Do not treat this as the default write path for every app-owned entity. If the data starts behaving like a real object with lifecycle, filtering, visibility, ownership, history, or relationships, prefer `app.records`, `app.cases`, or `app.threads`. ```typescript await appConfiguration.setDataItem({ appId: 'product-docs', collectionId: 'my-collection', productId: 'product-123', admin: true, data: { id: 'manual-1', title: 'User Manual', url: 'https://...' } }); ```
6033
6155
 
6034
6156
  **deleteDataItem**(opts: AppConfigOptions) → `Promise<void>`
6035
- Delete a data item by ID within a scope. Requires admin authentication. ```typescript await appConfiguration.deleteDataItem({ appId: 'product-docs', collectionId: 'my-collection', productId: 'product-123', admin: true, itemId: 'manual-1' }); ```
6157
+ Delete a keyed data item by ID within a scope. Requires admin authentication. ```typescript await appConfiguration.deleteDataItem({ appId: 'product-docs', collectionId: 'my-collection', productId: 'product-123', admin: true, itemId: 'manual-1' }); ```
6036
6158
 
6037
6159
  **getWidgets**(collectionId: string,
6038
6160
  options?: GetCollectionWidgetsOptions) → `Promise<CollectionWidgetsResponse>`
@@ -6430,93 +6552,17 @@ Get all tags/codes assigned to a specific batch. Shows which claim set codes hav
6430
6552
  **appendBulk**(collectionId: string,
6431
6553
  body: BroadcastAppendBulkBody) → `Promise<AppendBulkResult>`
6432
6554
 
6433
- ### chat
6434
-
6435
- **create**(collectionId: string,
6436
- request: ResponsesRequest) → `Promise<ResponsesResult | AsyncIterable<ResponsesStreamEvent>>`
6437
- Create a Responses API request (streaming or non-streaming)
6555
+ ### chat.completions
6438
6556
 
6439
6557
  **create**(collectionId: string,
6440
6558
  request: ChatCompletionRequest) → `Promise<ChatCompletionResponse | AsyncIterable<ChatCompletionChunk>>`
6441
6559
  Create a chat completion (streaming or non-streaming)
6442
6560
 
6443
- **list**(collectionId: string, params?: AIModelListParams) → `Promise<AIModelListResponse>`
6444
- List available AI models
6445
-
6446
- **get**(collectionId: string, modelId: string) → `Promise<AIModel>`
6447
- Get specific model information
6448
-
6449
- **indexDocument**(collectionId: string,
6450
- request: IndexDocumentRequest) → `Promise<IndexDocumentResponse>`
6451
- Index a document for RAG
6452
-
6453
- **configureAssistant**(collectionId: string,
6454
- request: ConfigureAssistantRequest) → `Promise<ConfigureAssistantResponse>`
6455
- Configure AI assistant behavior
6456
-
6457
- **stats**(collectionId: string) → `Promise<SessionStatistics>`
6458
- Get session statistics
6459
-
6460
- **reset**(collectionId: string, userId: string) → `Promise<`
6461
- Reset rate limit for a user
6462
-
6463
- **generate**(collectionId: string,
6464
- request: GeneratePodcastRequest) → `Promise<GeneratePodcastResponse>`
6465
- Generate a NotebookLM-style conversational podcast from product documents
6561
+ ### chat.responses
6466
6562
 
6467
- **getStatus**(collectionId: string, podcastId: string) → `Promise<PodcastStatus>`
6468
- Get podcast generation status
6469
-
6470
- **generate**(collectionId: string,
6471
- request: TTSRequest) → `Promise<Blob>`
6472
- Generate text-to-speech audio
6473
-
6474
- **chat**(collectionId: string,
6475
- request: PublicChatRequest) → `Promise<PublicChatResponse>`
6476
- Chat with product assistant (RAG)
6477
-
6478
- **getSession**(collectionId: string, sessionId: string) → `Promise<Session>`
6479
- Get session history
6480
-
6481
- **clearSession**(collectionId: string, sessionId: string) → `Promise<`
6482
- Clear session history
6483
-
6484
- **getRateLimit**(collectionId: string, userId: string) → `Promise<RateLimitStatus>`
6485
- Check rate limit status
6486
-
6487
- **getToken**(collectionId: string,
6488
- request: EphemeralTokenRequest) → `Promise<EphemeralTokenResponse>`
6489
- Generate ephemeral token for Gemini Live
6490
-
6491
- **isSupported**() → `boolean`
6492
- Check if voice is supported in browser
6493
-
6494
- **listen**(language = 'en-US') → `Promise<string>`
6495
- Listen for voice input
6496
-
6497
- **speak**(text: string, options?: { voice?: string; rate?: number }) → `Promise<void>`
6498
- Speak text
6499
-
6500
- **generateContent**(collectionId: string,
6501
- params: AIGenerateContentRequest,
6502
- admin: boolean = true) → `Promise<any>`
6503
- Generate text/content via AI (admin)
6504
-
6505
- **generateImage**(collectionId: string, params: AIGenerateImageRequest) → `Promise<any>`
6506
- Generate an image via AI (admin)
6507
-
6508
- **searchPhotos**(collectionId: string,
6509
- params: AISearchPhotosRequest) → `Promise<AISearchPhotosPhoto[]>`
6510
- Search stock photos or similar via AI (admin)
6511
-
6512
- **uploadFile**(collectionId: string, params: any) → `Promise<any>`
6513
- Upload a file for AI usage (admin). Pass FormData for binary uploads.
6514
-
6515
- **createCache**(collectionId: string, params: any) → `Promise<any>`
6516
- Create or warm a cache for AI (admin)
6517
-
6518
- **postChat**(collectionId: string, params: any, admin: boolean = true) → `Promise<any>`
6519
- Post a chat message to the AI (admin or public)
6563
+ **create**(collectionId: string,
6564
+ request: ResponsesRequest) `Promise<ResponsesResult | AsyncIterable<ResponsesStreamEvent>>`
6565
+ Create a Responses API request (streaming or non-streaming)
6520
6566
 
6521
6567
  ### claimSet
6522
6568
 
@@ -6947,6 +6993,14 @@ Public: Fetch a global location by ID GET /public/location/:locationId
6947
6993
  locationId: string) → `Promise<Location>`
6948
6994
  Public: Fetch a location for a collection; returns either a collection-owned or global fallback GET /public/collection/:collectionId/location/:locationId
6949
6995
 
6996
+ ### models
6997
+
6998
+ **list**(collectionId: string, params?: AIModelListParams) → `Promise<AIModelListResponse>`
6999
+ List available AI models
7000
+
7001
+ **get**(collectionId: string, modelId: string) → `Promise<AIModel>`
7002
+ Get specific model information
7003
+
6950
7004
  ### nfc
6951
7005
 
6952
7006
  **claimTag**(data: NfcClaimTagRequest) → `Promise<NfcTagInfo>`
@@ -7052,6 +7106,15 @@ Get individual order items for a specific product. Returns all matching items wi
7052
7106
  params?: GetOrderIdsParams) → `Promise<GetOrderIdsResponse>`
7053
7107
  Get unique order IDs containing items for a specific product. Lightweight query that only returns order IDs, not full order objects. ```typescript // Get order IDs for a product const productOrders = await order.getOrderIdsByAttribute( 'coll_123', 'productId', 'prod_789', { limit: 500 } ) ```
7054
7108
 
7109
+ ### podcast
7110
+
7111
+ **generate**(collectionId: string,
7112
+ request: GeneratePodcastRequest) → `Promise<GeneratePodcastResponse>`
7113
+ Generate a NotebookLM-style conversational podcast from product documents
7114
+
7115
+ **getStatus**(collectionId: string, podcastId: string) → `Promise<PodcastStatus>`
7116
+ Get podcast generation status
7117
+
7055
7118
  ### product
7056
7119
 
7057
7120
  **get**(collectionId: string,
@@ -7152,57 +7215,52 @@ Get proofs for a batch (admin only). GET /admin/collection/:collectionId/product
7152
7215
  data: { targetProductId: string }) → `Promise<ProofResponse>`
7153
7216
  Migrate a proof to a different product within the same collection (admin only). Because the Firestore ledger document ID is `{productId}-{proofId}`, a proof cannot simply be re-assigned to another product by updating a field — the document must be re-keyed. This endpoint handles that atomically: 1. Reads the source ledger document (`{sourceProductId}-{proofId}`). 2. Writes a new document (`{targetProductId}-{proofId}`) with `productId` and `proofGroup` updated. The short `proofId` (nanoid) is unchanged. 3. Writes a migration history entry to the new document's `history` subcollection (snapshot of the original proof + migration metadata). 4. Copies all subcollections — `assets`, `attestations`, `history` — from the old document to the new one. 5. Deletes the old subcollections and then the old document. Repeated migrations are safe — each one appends a history record; no migration metadata is stored on the proof document itself. ```typescript const migrated = await proof.migrate('coll_123', 'prod_old', 'proof_abc', { targetProductId: 'prod_new', }) console.log(migrated.productId) // 'prod_new' ```
7154
7217
 
7218
+ ### publicClient
7219
+
7220
+ **chat**(collectionId: string,
7221
+ request: PublicChatRequest) → `Promise<PublicChatResponse>`
7222
+ Chat with product assistant (RAG)
7223
+
7224
+ **getSession**(collectionId: string, sessionId: string) → `Promise<Session>`
7225
+ Get session history
7226
+
7227
+ **clearSession**(collectionId: string, sessionId: string) → `Promise<`
7228
+ Clear session history
7229
+
7230
+ **getRateLimit**(collectionId: string, userId: string) → `Promise<RateLimitStatus>`
7231
+ Check rate limit status
7232
+
7233
+ **getToken**(collectionId: string,
7234
+ request: EphemeralTokenRequest) → `Promise<EphemeralTokenResponse>`
7235
+ Generate ephemeral token for Gemini Live
7236
+
7155
7237
  ### qr
7156
7238
 
7157
7239
  **lookupShortCode**(shortId: string, code: string) → `Promise<QrShortCodeLookupResponse>`
7158
7240
  Resolve a short code to related resource identifiers.
7159
7241
 
7160
- ### realtime
7242
+ ### rag
7161
7243
 
7162
- **getPublicToken**(params: RealtimeTokenRequest) → `Promise<AblyTokenRequest>`
7163
- Get an Ably token for public (user-scoped) real-time communication. This endpoint returns an Ably TokenRequest that can be used to initialize an Ably client with appropriate permissions for the specified collection and optional app. Requires user authentication (Bearer token). ```ts const tokenRequest = await realtime.getPublicToken({ collectionId: 'my-collection-id', appId: 'my-app-id' }) // Use with Ably const ably = new Ably.Realtime.Promise({ authCallback: async (data, callback) => { callback(null, tokenRequest) } }) // Subscribe to channels matching the pattern const channel = ably.channels.get('collection:my-collection-id:app:my-app-id:chat:general') await channel.subscribe('message', (msg) => console.log(msg.data)) ```
7164
-
7165
- **getAdminToken**() → `Promise<AblyTokenRequest>`
7166
- Get an Ably token for admin real-time communication. This endpoint returns an Ably TokenRequest that can be used to initialize an Ably client with admin permissions to receive system notifications and alerts. Admin users get subscribe-only (read-only) access to the interaction:{userId} channel pattern. Requires admin authentication (Bearer token). ```ts const tokenRequest = await realtime.getAdminToken() // Use with Ably const ably = new Ably.Realtime.Promise({ authCallback: async (data, callback) => { callback(null, tokenRequest) } }) // Subscribe to admin interaction channel const userId = 'my-user-id' const channel = ably.channels.get(`interaction:${userId}`) await channel.subscribe((message) => { console.log('Admin notification:', message.data) }) ```
7167
-
7168
- ### records
7244
+ **indexDocument**(collectionId: string,
7245
+ request: IndexDocumentRequest) `Promise<IndexDocumentResponse>`
7246
+ Index a document for RAG
7169
7247
 
7170
- **create**(collectionId: string,
7171
- appId: string,
7172
- input: CreateRecordInput,
7173
- admin: boolean = false) → `Promise<AppRecord>`
7174
- Create a new record POST /records
7248
+ **configureAssistant**(collectionId: string,
7249
+ request: ConfigureAssistantRequest) → `Promise<ConfigureAssistantResponse>`
7250
+ Configure AI assistant behavior
7175
7251
 
7176
- **list**(collectionId: string,
7177
- appId: string,
7178
- params?: RecordListQueryParams,
7179
- admin: boolean = false) → `Promise<PaginatedResponse<AppRecord>>`
7180
- List records with optional query parameters GET /records
7252
+ ### rateLimit
7181
7253
 
7182
- **get**(collectionId: string,
7183
- appId: string,
7184
- recordId: string,
7185
- admin: boolean = false) → `Promise<AppRecord>`
7186
- Get a single record by ID GET /records/:recordId
7254
+ **reset**(collectionId: string, userId: string) → `Promise<`
7255
+ Reset rate limit for a user
7187
7256
 
7188
- **update**(collectionId: string,
7189
- appId: string,
7190
- recordId: string,
7191
- input: UpdateRecordInput,
7192
- admin: boolean = false) → `Promise<AppRecord>`
7193
- Update a record PATCH /records/:recordId Admin can update any field, public (owner) can only update data and owner
7257
+ ### realtime
7194
7258
 
7195
- **remove**(collectionId: string,
7196
- appId: string,
7197
- recordId: string,
7198
- admin: boolean = false) → `Promise<`
7199
- Soft delete a record DELETE /records/:recordId
7259
+ **getPublicToken**(params: RealtimeTokenRequest) → `Promise<AblyTokenRequest>`
7260
+ Get an Ably token for public (user-scoped) real-time communication. This endpoint returns an Ably TokenRequest that can be used to initialize an Ably client with appropriate permissions for the specified collection and optional app. Requires user authentication (Bearer token). ```ts const tokenRequest = await realtime.getPublicToken({ collectionId: 'my-collection-id', appId: 'my-app-id' }) // Use with Ably const ably = new Ably.Realtime.Promise({ authCallback: async (data, callback) => { callback(null, tokenRequest) } }) // Subscribe to channels matching the pattern const channel = ably.channels.get('collection:my-collection-id:app:my-app-id:chat:general') await channel.subscribe('message', (msg) => console.log(msg.data)) ```
7200
7261
 
7201
- **aggregate**(collectionId: string,
7202
- appId: string,
7203
- request: AggregateRequest,
7204
- admin: boolean = false) → `Promise<AggregateResponse>`
7205
- Get aggregate statistics for records POST /records/aggregate
7262
+ **getAdminToken**() → `Promise<AblyTokenRequest>`
7263
+ Get an Ably token for admin real-time communication. This endpoint returns an Ably TokenRequest that can be used to initialize an Ably client with admin permissions to receive system notifications and alerts. Admin users get subscribe-only (read-only) access to the interaction:{userId} channel pattern. Requires admin authentication (Bearer token). ```ts const tokenRequest = await realtime.getAdminToken() // Use with Ably const ably = new Ably.Realtime.Promise({ authCallback: async (data, callback) => { callback(null, tokenRequest) } }) // Subscribe to admin interaction channel const userId = 'my-user-id' const channel = ably.channels.get(`interaction:${userId}`) await channel.subscribe((message) => { console.log('Admin notification:', message.data) }) ```
7206
7264
 
7207
7265
  ### segments
7208
7266
 
@@ -7229,6 +7287,11 @@ Get aggregate statistics for records POST /records/aggregate
7229
7287
  id: string,
7230
7288
  query: { limit?: number; offset?: number } = {}) → `Promise<SegmentRecipientsResponse>`
7231
7289
 
7290
+ ### sessions
7291
+
7292
+ **stats**(collectionId: string) → `Promise<SessionStatistics>`
7293
+ Get session statistics
7294
+
7232
7295
  ### tags
7233
7296
 
7234
7297
  **create**(collectionId: string,
@@ -7317,54 +7380,16 @@ Reverse lookup by ref via POST (public). `POST /public/collection/:collectionId/
7317
7380
  **renderSource**(collectionId: string,
7318
7381
  body: TemplateRenderSourceRequest) → `Promise<TemplateRenderSourceResponse>`
7319
7382
 
7320
- ### threads
7321
-
7322
- **create**(collectionId: string,
7323
- appId: string,
7324
- input: CreateThreadInput,
7325
- admin: boolean = false) → `Promise<AppThread>`
7326
- Create a new thread POST /threads
7327
-
7328
- **list**(collectionId: string,
7329
- appId: string,
7330
- params?: ThreadListQueryParams,
7331
- admin: boolean = false) → `Promise<PaginatedResponse<AppThread>>`
7332
- List threads with optional query parameters GET /threads
7333
-
7334
- **get**(collectionId: string,
7335
- appId: string,
7336
- threadId: string,
7337
- admin: boolean = false) → `Promise<AppThread>`
7338
- Get a single thread by ID GET /threads/:threadId
7383
+ ### tts
7339
7384
 
7340
- **update**(collectionId: string,
7341
- appId: string,
7342
- threadId: string,
7343
- input: UpdateThreadInput,
7344
- admin: boolean = false) → `Promise<AppThread>`
7345
- Update a thread PATCH /threads/:threadId Admin can update any field, public (owner) can only update body, tags, data, owner
7346
-
7347
- **remove**(collectionId: string,
7348
- appId: string,
7349
- threadId: string,
7350
- admin: boolean = false) → `Promise<`
7351
- Soft delete a thread DELETE /threads/:threadId
7352
-
7353
- **reply**(collectionId: string,
7354
- appId: string,
7355
- threadId: string,
7356
- input: ReplyInput,
7357
- admin: boolean = false) → `Promise<AppThread>`
7358
- Add a reply to a thread POST /threads/:threadId/reply Atomically appends to replies array, increments replyCount, updates lastReplyAt
7359
-
7360
- **aggregate**(collectionId: string,
7361
- appId: string,
7362
- request: AggregateRequest,
7363
- admin: boolean = false) → `Promise<AggregateResponse>`
7364
- Get aggregate statistics for threads POST /threads/aggregate
7385
+ **generate**(collectionId: string,
7386
+ request: TTSRequest) → `Promise<Blob>`
7387
+ Generate text-to-speech audio
7365
7388
 
7366
7389
  ### userAppData
7367
7390
 
7391
+ User-owned app data stored per user and app, shared across collections.
7392
+
7368
7393
  **getConfig**(appId: string) → `Promise<any>`
7369
7394
  Get user's config blob for an app. This is a single JSON object stored per user+app. ```typescript const config = await userAppData.getConfig('allergy-tracker'); // Returns: { allergies: ['peanuts'], notifications: true } ```
7370
7395
 
@@ -7431,3 +7456,14 @@ Get serial numbers for a variant (admin only).
7431
7456
  codeId: string) → `Promise<any>`
7432
7457
  Look up a serial number by code for a variant (admin only).
7433
7458
 
7459
+ ### voice
7460
+
7461
+ **isSupported**() → `boolean`
7462
+ Check if voice is supported in browser
7463
+
7464
+ **listen**(language = 'en-US') → `Promise<string>`
7465
+ Listen for voice input
7466
+
7467
+ **speak**(text: string, options?: { voice?: string; rate?: number }) → `Promise<void>`
7468
+ Speak text
7469
+