@proveanything/smartlinks 1.6.6 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  # Smartlinks API Summary
2
2
 
3
- Version: 1.6.6 | Generated: 2026-03-03T14:13:59.227Z
3
+ Version: 1.7.0 | Generated: 2026-03-03T14:59:10.692Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -11,6 +11,8 @@ For detailed guides on specific features:
11
11
  - **[AI & Chat Completions](ai.md)** - Chat completions, RAG (document-grounded Q&A), voice integration, streaming, tool calling, podcast generation
12
12
  - **[Widgets](widgets.md)** - Embeddable React components for parent applications
13
13
  - **[Containers](containers.md)** - Building full-app embeddable containers (lazy-loaded)
14
+ - **[App Configuration Files](app-manifest.md)** - `app.manifest.json` and `app.admin.json` reference — bundles, components, setup questions, import schemas, tunable fields, and metrics
15
+ - **[Executor Model](executor.md)** - Programmatic JS bundles for AI-driven setup, server-side SEO metadata generation, and LLM content for AI crawlers
14
16
  - **[Realtime](realtime.md)** - Real-time data updates and WebSocket connections
15
17
  - **[iframe Responder](iframe-responder.md)** - iframe integration and cross-origin communication
16
18
  - **[i18n](i18n.md)** - Internationalization and localization
@@ -68,6 +70,8 @@ The Smartlinks SDK is organized into the following namespaces:
68
70
  - **appObjects** - Functions for appObjects operations
69
71
  - **async** - Functions for async operations
70
72
  - **attestation** - Functions for attestation operations
73
+ - **attestations** - Functions for attestations operations
74
+ - **containers** - Functions for containers operations
71
75
  - **jobs** - Functions for jobs operations
72
76
  - **journeysAnalytics** - Functions for journeysAnalytics operations
73
77
  - **location** - Functions for location operations
@@ -873,6 +877,102 @@ interface AppContainerComponent {
873
877
  }
874
878
  ```
875
879
 
880
+ **DeepLinkEntry** (interface)
881
+ ```typescript
882
+ interface DeepLinkEntry {
883
+ title: string;
884
+ * Hash route path within the app (optional).
885
+ * Defaults to "/" if omitted.
886
+ * @example "/gallery"
887
+ path?: string;
888
+ * App-specific query params appended to the hash route URL.
889
+ * Do NOT include platform context params (collectionId, appId, productId, etc.) —
890
+ * those are injected by the platform automatically.
891
+ params?: Record<string, string>;
892
+ }
893
+ ```
894
+
895
+ **ExecutorContext** (interface)
896
+ ```typescript
897
+ interface ExecutorContext {
898
+ collectionId: string;
899
+ appId: string;
900
+ SL: any;
901
+ }
902
+ ```
903
+
904
+ **SEOInput** (interface)
905
+ ```typescript
906
+ interface SEOInput {
907
+ collectionId: string;
908
+ appId: string;
909
+ productId?: string;
910
+ proofId?: string;
911
+ SL: any;
912
+ collection?: Record<string, any>;
913
+ product?: Record<string, any>;
914
+ proof?: Record<string, any>;
915
+ }
916
+ ```
917
+
918
+ **SEOResult** (interface)
919
+ ```typescript
920
+ interface SEOResult {
921
+ title?: string;
922
+ description?: string;
923
+ ogImage?: string;
924
+ jsonLd?: Record<string, any> | Record<string, any>[];
925
+ contentSummary?: string;
926
+ topics?: string[];
927
+ }
928
+ ```
929
+
930
+ **LLMContentSection** (interface)
931
+ ```typescript
932
+ interface LLMContentSection {
933
+ heading: string;
934
+ content: string;
935
+ order?: number;
936
+ }
937
+ ```
938
+
939
+ **LLMContentInput** (interface)
940
+ ```typescript
941
+ interface LLMContentInput {
942
+ collectionId: string;
943
+ appId: string;
944
+ productId?: string;
945
+ proofId?: string;
946
+ SL: any;
947
+ collection?: Record<string, any>;
948
+ product?: Record<string, any>;
949
+ proof?: Record<string, any>;
950
+ pageSlug?: string;
951
+ }
952
+ ```
953
+
954
+ **LLMContentResult** (interface)
955
+ ```typescript
956
+ interface LLMContentResult {
957
+ sections: LLMContentSection[];
958
+ }
959
+ ```
960
+
961
+ **AppManifestExecutor** (interface)
962
+ ```typescript
963
+ interface AppManifestExecutor {
964
+ files: AppManifestFiles;
965
+ factory?: string;
966
+ exports?: string[];
967
+ description?: string;
968
+ llmContent?: {
969
+ function: string;
970
+ timeout?: number;
971
+ responseShape?: Record<string, any>;
972
+ };
973
+ }
974
+ ```
975
+
876
976
  **AppAdminConfig** (interface)
877
977
  ```typescript
878
978
  interface AppAdminConfig {
@@ -947,6 +1047,19 @@ interface AppManifest {
947
1047
  version: string;
948
1048
  platformRevision?: string;
949
1049
  appId: string;
1050
+ * SEO configuration for this app.
1051
+ * `priority` controls which app's singular fields (title, description, ogImage) win
1052
+ * when multiple apps appear on the same page. Default is 0; higher wins.
1053
+ seo?: {
1054
+ strategy?: 'executor' | string;
1055
+ priority?: number;
1056
+ contract?: {
1057
+ function: string;
1058
+ input?: string[];
1059
+ timeout?: number;
1060
+ responseShape?: Record<string, string>;
1061
+ };
1062
+ };
950
1063
  };
951
1064
  * Relative path to the admin configuration file (e.g. `"app.admin.json"`).
952
1065
  * When present, fetch this file to get the full {@link AppAdminConfig}
@@ -961,6 +1074,16 @@ interface AppManifest {
961
1074
  files: AppManifestFiles;
962
1075
  components: AppContainerComponent[];
963
1076
  };
1077
+ * Static deep-linkable states built into this app.
1078
+ * These are fixed routes that exist regardless of content — declared once at build time.
1079
+ * Dynamic content entries (e.g. CMS pages) are stored separately in `appConfig.linkable`.
1080
+ * Consumers should merge both sources to get the full set of navigable states.
1081
+ * @see DeepLinkEntry
1082
+ linkable?: DeepLinkEntry[];
1083
+ * Executor bundle declaration. Present when the app ships a programmatic executor
1084
+ * for AI-driven configuration, server-side SEO, and LLM content generation.
1085
+ * @see AppManifestExecutor
1086
+ executor?: AppManifestExecutor;
964
1087
  [key: string]: any;
965
1088
  }
966
1089
  ```
@@ -1454,6 +1577,230 @@ interface AttestationUpdateRequest {
1454
1577
  }
1455
1578
  ```
1456
1579
 
1580
+ ### attestations
1581
+
1582
+ **Attestation** (interface)
1583
+ ```typescript
1584
+ interface Attestation {
1585
+ id: string
1586
+ orgId: string
1587
+ collectionId: string
1588
+ subjectType: AttestationSubjectType
1589
+ subjectId: string
1590
+ attestationType: string
1591
+ recordedAt: string
1592
+ visibility: AttestationVisibility
1593
+ value?: Record<string, any>
1594
+ ownerData?: Record<string, any>
1595
+ adminData?: Record<string, any>
1596
+ unit?: string
1597
+ source?: string
1598
+ authorId?: string
1599
+ metadata?: Record<string, any>
1600
+ contentHash: string
1601
+ prevHash?: string
1602
+ createdAt: string
1603
+ }
1604
+ ```
1605
+
1606
+ **LatestAttestation** (interface)
1607
+ ```typescript
1608
+ interface LatestAttestation {
1609
+ attestationType: string
1610
+ latest: Attestation
1611
+ }
1612
+ ```
1613
+
1614
+ **AttestationSummaryBucket** (interface)
1615
+ ```typescript
1616
+ interface AttestationSummaryBucket {
1617
+ period: string
1618
+ count: number
1619
+ values?: Record<string, any>
1620
+ }
1621
+ ```
1622
+
1623
+ **ChainVerifyResult** (interface)
1624
+ ```typescript
1625
+ interface ChainVerifyResult {
1626
+ valid: boolean
1627
+ checkedCount: number
1628
+ failedAt?: string
1629
+ message: string
1630
+ }
1631
+ ```
1632
+
1633
+ **CreateAttestationInput** (interface)
1634
+ ```typescript
1635
+ interface CreateAttestationInput {
1636
+ subjectType: AttestationSubjectType
1637
+ subjectId: string
1638
+ attestationType: string
1639
+ recordedAt?: string
1640
+ visibility?: AttestationVisibility
1641
+ value?: Record<string, any>
1642
+ ownerData?: Record<string, any>
1643
+ adminData?: Record<string, any>
1644
+ unit?: string
1645
+ source?: string
1646
+ authorId?: string
1647
+ metadata?: Record<string, any>
1648
+ }
1649
+ ```
1650
+
1651
+ **ListAttestationsResponse** (interface)
1652
+ ```typescript
1653
+ interface ListAttestationsResponse {
1654
+ attestations: Attestation[]
1655
+ }
1656
+ ```
1657
+
1658
+ **PublicListAttestationsResponse** (interface)
1659
+ ```typescript
1660
+ interface PublicListAttestationsResponse {
1661
+ attestations: Attestation[]
1662
+ audience: AttestationAudience
1663
+ }
1664
+ ```
1665
+
1666
+ **AttestationSummaryResponse** (interface)
1667
+ ```typescript
1668
+ interface AttestationSummaryResponse {
1669
+ summary: AttestationSummaryBucket[]
1670
+ }
1671
+ ```
1672
+
1673
+ **PublicAttestationSummaryResponse** (interface)
1674
+ ```typescript
1675
+ interface PublicAttestationSummaryResponse {
1676
+ summary: AttestationSummaryBucket[]
1677
+ audience: 'public'
1678
+ }
1679
+ ```
1680
+
1681
+ **AttestationLatestResponse** (interface)
1682
+ ```typescript
1683
+ interface AttestationLatestResponse {
1684
+ latest: LatestAttestation[]
1685
+ }
1686
+ ```
1687
+
1688
+ **PublicAttestationLatestResponse** (interface)
1689
+ ```typescript
1690
+ interface PublicAttestationLatestResponse {
1691
+ latest: LatestAttestation[]
1692
+ audience: AttestationAudience
1693
+ }
1694
+ ```
1695
+
1696
+ **AttestationTreeSummaryResponse** (interface)
1697
+ ```typescript
1698
+ interface AttestationTreeSummaryResponse {
1699
+ summary: AttestationSummaryBucket[]
1700
+ subjectCount: number
1701
+ }
1702
+ ```
1703
+
1704
+ **PublicAttestationTreeSummaryResponse** (interface)
1705
+ ```typescript
1706
+ interface PublicAttestationTreeSummaryResponse {
1707
+ summary: AttestationSummaryBucket[]
1708
+ audience: 'public'
1709
+ subjectCount: number
1710
+ }
1711
+ ```
1712
+
1713
+ **AttestationTreeLatestResponse** (interface)
1714
+ ```typescript
1715
+ interface AttestationTreeLatestResponse {
1716
+ latest: LatestAttestation[]
1717
+ subjectCount: number
1718
+ }
1719
+ ```
1720
+
1721
+ **PublicAttestationTreeLatestResponse** (interface)
1722
+ ```typescript
1723
+ interface PublicAttestationTreeLatestResponse {
1724
+ latest: LatestAttestation[]
1725
+ audience: 'public'
1726
+ subjectCount: number
1727
+ }
1728
+ ```
1729
+
1730
+ **ListAttestationsParams** (interface)
1731
+ ```typescript
1732
+ interface ListAttestationsParams {
1733
+ subjectType: AttestationSubjectType
1734
+ subjectId: string
1735
+ attestationType?: string
1736
+ recordedAfter?: string
1737
+ recordedBefore?: string
1738
+ limit?: number
1739
+ offset?: number
1740
+ }
1741
+ ```
1742
+
1743
+ **AttestationSummaryParams** (interface)
1744
+ ```typescript
1745
+ interface AttestationSummaryParams {
1746
+ subjectType: AttestationSubjectType
1747
+ subjectId: string
1748
+ attestationType: string
1749
+ valueField?: string
1750
+ groupBy?: AttestationGroupBy
1751
+ recordedAfter?: string
1752
+ recordedBefore?: string
1753
+ limit?: number
1754
+ }
1755
+ ```
1756
+
1757
+ **AttestationLatestParams** (interface)
1758
+ ```typescript
1759
+ interface AttestationLatestParams {
1760
+ subjectType: AttestationSubjectType
1761
+ subjectId: string
1762
+ }
1763
+ ```
1764
+
1765
+ **AttestationVerifyParams** (interface)
1766
+ ```typescript
1767
+ interface AttestationVerifyParams {
1768
+ subjectType: AttestationSubjectType
1769
+ subjectId: string
1770
+ attestationType: string
1771
+ }
1772
+ ```
1773
+
1774
+ **AttestationTreeSummaryParams** (interface)
1775
+ ```typescript
1776
+ interface AttestationTreeSummaryParams {
1777
+ subjectId: string
1778
+ attestationType: string
1779
+ valueField?: string
1780
+ groupBy?: AttestationGroupBy
1781
+ recordedAfter?: string
1782
+ recordedBefore?: string
1783
+ limit?: number
1784
+ includeItems?: boolean
1785
+ }
1786
+ ```
1787
+
1788
+ **AttestationTreeLatestParams** (interface)
1789
+ ```typescript
1790
+ interface AttestationTreeLatestParams {
1791
+ subjectId: string
1792
+ includeItems?: boolean
1793
+ }
1794
+ ```
1795
+
1796
+ **AttestationSubjectType** = ``
1797
+
1798
+ **AttestationVisibility** = `'public' | 'owner' | 'admin'`
1799
+
1800
+ **AttestationAudience** = `'public' | 'owner' | 'admin'`
1801
+
1802
+ **AttestationGroupBy** = `'hour' | 'day' | 'week' | 'month'`
1803
+
1457
1804
  ### auth
1458
1805
 
1459
1806
  **UserAccountRegistrationRequest** (interface)
@@ -2956,6 +3303,184 @@ interface ContactSchemaResponse {
2956
3303
 
2957
3304
  **ContactSchema** = `ContactSchemaResponse`
2958
3305
 
3306
+ ### containers
3307
+
3308
+ **Container** (interface)
3309
+ ```typescript
3310
+ interface Container {
3311
+ id: string
3312
+ orgId: string
3313
+ collectionId: string
3314
+ * Domain label describing what kind of container this is.
3315
+ * Examples: `'pallet'`, `'fridge'`, `'cask'`, `'warehouse'`, `'shipping_container'`
3316
+ containerType: string
3317
+ ref?: string
3318
+ name?: string
3319
+ description?: string
3320
+ status: ContainerStatus
3321
+ metadata?: Record<string, any>
3322
+ parentContainerId?: string
3323
+ children?: Container[]
3324
+ items?: ContainerItem[]
3325
+ createdAt: string
3326
+ updatedAt: string
3327
+ deletedAt?: string
3328
+ }
3329
+ ```
3330
+
3331
+ **ContainerItem** (interface)
3332
+ ```typescript
3333
+ interface ContainerItem {
3334
+ id: string
3335
+ orgId: string
3336
+ containerId: string
3337
+ collectionId?: string
3338
+ itemType: ContainerItemType
3339
+ itemId: string
3340
+ productId?: string
3341
+ proofId?: string
3342
+ addedAt: string
3343
+ removedAt?: string
3344
+ metadata?: Record<string, any>
3345
+ }
3346
+ ```
3347
+
3348
+ **CreateContainerInput** (interface)
3349
+ ```typescript
3350
+ interface CreateContainerInput {
3351
+ containerType: string
3352
+ ref?: string
3353
+ name?: string
3354
+ description?: string
3355
+ status?: ContainerStatus
3356
+ metadata?: Record<string, any>
3357
+ parentContainerId?: string
3358
+ }
3359
+ ```
3360
+
3361
+ **UpdateContainerInput** (interface)
3362
+ ```typescript
3363
+ interface UpdateContainerInput {
3364
+ containerType?: string
3365
+ ref?: string
3366
+ name?: string
3367
+ description?: string
3368
+ status?: ContainerStatus
3369
+ metadata?: Record<string, any>
3370
+ parentContainerId?: string | null
3371
+ }
3372
+ ```
3373
+
3374
+ **AddContainerItemsInput** (interface)
3375
+ ```typescript
3376
+ interface AddContainerItemsInput {
3377
+ items: Array<{
3378
+ itemType: ContainerItemType
3379
+ itemId: string
3380
+ productId?: string
3381
+ proofId?: string
3382
+ metadata?: Record<string, any>
3383
+ }>
3384
+ }
3385
+ ```
3386
+
3387
+ **RemoveContainerItemsInput** (interface)
3388
+ ```typescript
3389
+ interface RemoveContainerItemsInput {
3390
+ ids: string[]
3391
+ }
3392
+ ```
3393
+
3394
+ **ListContainersResponse** (interface)
3395
+ ```typescript
3396
+ interface ListContainersResponse {
3397
+ containers: Container[]
3398
+ limit: number
3399
+ offset: number
3400
+ }
3401
+ ```
3402
+
3403
+ **PublicListContainersResponse** (interface)
3404
+ ```typescript
3405
+ interface PublicListContainersResponse {
3406
+ containers: Container[]
3407
+ }
3408
+ ```
3409
+
3410
+ **FindContainersForItemResponse** (interface)
3411
+ ```typescript
3412
+ interface FindContainersForItemResponse {
3413
+ containers: Container[]
3414
+ }
3415
+ ```
3416
+
3417
+ **ContainerItemsResponse** (interface)
3418
+ ```typescript
3419
+ interface ContainerItemsResponse {
3420
+ items: ContainerItem[]
3421
+ limit: number
3422
+ offset: number
3423
+ }
3424
+ ```
3425
+
3426
+ **AddContainerItemsResponse** (interface)
3427
+ ```typescript
3428
+ interface AddContainerItemsResponse {
3429
+ items: ContainerItem[]
3430
+ }
3431
+ ```
3432
+
3433
+ **RemoveContainerItemsResponse** (interface)
3434
+ ```typescript
3435
+ interface RemoveContainerItemsResponse {
3436
+ success: true
3437
+ removedCount: number
3438
+ }
3439
+ ```
3440
+
3441
+ **ListContainersParams** (interface)
3442
+ ```typescript
3443
+ interface ListContainersParams {
3444
+ containerType?: string
3445
+ status?: ContainerStatus
3446
+ ref?: string
3447
+ parentContainerId?: string
3448
+ topLevel?: boolean
3449
+ limit?: number
3450
+ offset?: number
3451
+ }
3452
+ ```
3453
+
3454
+ **GetContainerParams** (interface)
3455
+ ```typescript
3456
+ interface GetContainerParams {
3457
+ tree?: boolean
3458
+ treeDepth?: number
3459
+ includeContents?: boolean
3460
+ }
3461
+ ```
3462
+
3463
+ **ListContainerItemsParams** (interface)
3464
+ ```typescript
3465
+ interface ListContainerItemsParams {
3466
+ history?: boolean
3467
+ limit?: number
3468
+ offset?: number
3469
+ }
3470
+ ```
3471
+
3472
+ **FindContainersForItemParams** (interface)
3473
+ ```typescript
3474
+ interface FindContainersForItemParams {
3475
+ itemType: ContainerItemType
3476
+ itemId: string
3477
+ }
3478
+ ```
3479
+
3480
+ **ContainerStatus** = `'active' | 'archived' | string`
3481
+
3482
+ **ContainerItemType** = `'tag' | 'proof' | 'serial' | 'order_item' | 'container'`
3483
+
2959
3484
  ### crate
2960
3485
 
2961
3486
  **CrateItem** (interface)
@@ -4376,10 +4901,15 @@ interface Tag {
4376
4901
  orgId: string // Organization ID
4377
4902
  tagId: string // Unique tag identifier (globally unique)
4378
4903
  collectionId: string // Collection ID
4379
- productId: string // Product ID
4904
+ productId?: string // Product ID (optional — may be a ref-only tag)
4380
4905
  variantId?: string | null // Optional: Variant ID
4381
4906
  batchId?: string | null // Optional: Batch ID
4382
- proofId: string // Proof ID (serial number or explicit)
4907
+ proofId?: string // Proof ID (serial number or explicit)
4908
+ * Polymorphic reference type linking the tag to any app object, e.g.
4909
+ * `'app_record'`, `'app_case'`, `'container'`, etc.
4910
+ * Must always be paired with `refId`.
4911
+ refType?: string
4912
+ refId?: string
4383
4913
  metadata: Record<string, any> // Additional metadata (e.g., serialIndex)
4384
4914
  createdAt: string // ISO 8601 timestamp
4385
4915
  updatedAt: string // ISO 8601 timestamp
@@ -4390,11 +4920,15 @@ interface Tag {
4390
4920
  ```typescript
4391
4921
  interface CreateTagRequest {
4392
4922
  tagId: string // Required: Unique tag identifier
4393
- productId: string // Required: Product ID
4923
+ productId?: string // Optional: Product ID (required when proofId is set without useSerialNumber)
4394
4924
  variantId?: string // Optional: Variant ID
4395
4925
  batchId?: string // Optional: Batch ID
4396
- proofId?: string // Optional: Explicit proof ID (if omitted, auto-generates serial)
4926
+ proofId?: string // Optional: Explicit proof ID (if omitted with productId, auto-generates serial)
4397
4927
  useSerialNumber?: boolean // Optional: Explicitly request serial number generation
4928
+ * Polymorphic ref type linking this tag to any app object (e.g. `'app_record'`, `'container'`).
4929
+ * Must be paired with `refId`. A tag can simultaneously have a product/proof AND a ref.
4930
+ refType?: string
4931
+ refId?: string
4398
4932
  metadata?: Record<string, any> // Optional: Additional metadata
4399
4933
  force?: boolean // Optional: Overwrite if tag exists in same collection (default: false)
4400
4934
  }
@@ -4451,6 +4985,10 @@ interface UpdateTagRequest {
4451
4985
  variantId?: string | null // Optional: Update variant ID (null to clear)
4452
4986
  batchId?: string | null // Optional: Update batch ID (null to clear)
4453
4987
  proofId?: string // Optional: Update proof ID
4988
+ * Polymorphic ref type. Must be paired with `refId`.
4989
+ * Set both to `null` / omit to leave unchanged.
4990
+ refType?: string
4991
+ refId?: string
4454
4992
  metadata?: Record<string, any> // Optional: Merge with existing metadata
4455
4993
  }
4456
4994
  ```
@@ -4470,6 +5008,8 @@ interface ListTagsRequest {
4470
5008
  productId?: string // Optional: Filter by product ID
4471
5009
  variantId?: string // Optional: Filter by variant ID
4472
5010
  batchId?: string // Optional: Filter by batch ID
5011
+ refType?: string
5012
+ refId?: string
4473
5013
  }
4474
5014
  ```
4475
5015
 
@@ -4525,6 +5065,21 @@ interface PublicBatchLookupQueryRequest {
4525
5065
  }
4526
5066
  ```
4527
5067
 
5068
+ **ReverseTagLookupParams** (interface)
5069
+ ```typescript
5070
+ interface ReverseTagLookupParams {
5071
+ refType: string
5072
+ refId: string
5073
+ }
5074
+ ```
5075
+
5076
+ **ReverseTagLookupResponse** (interface)
5077
+ ```typescript
5078
+ interface ReverseTagLookupResponse {
5079
+ tags: Tag[]
5080
+ }
5081
+ ```
5082
+
4528
5083
  ### template
4529
5084
 
4530
5085
  **TemplateBase** (interface)
@@ -4951,13 +5506,91 @@ Create a new attestation for a proof.
4951
5506
  proofId: string,
4952
5507
  attestationId: string,
4953
5508
  data: AttestationUpdateRequest) → `Promise<AttestationResponse>`
4954
- Update an attestation.
5509
+ Update an attestation. via `attestations.create()` with a note in `metadata` instead.
4955
5510
 
4956
5511
  **remove**(collectionId: string,
4957
5512
  productId: string,
4958
5513
  proofId: string,
4959
5514
  attestationId: string) → `Promise<void>`
4960
- Delete an attestation.
5515
+ Delete an attestation. Use `attestations.create()` to append a corrective/superseding record instead.
5516
+
5517
+ ### attestations
5518
+
5519
+ **create**(collectionId: string,
5520
+ data: CreateAttestationInput) → `Promise<Attestation>`
5521
+ Create a single attestation (admin). `attestationType` are required ```typescript const a = await attestations.create('coll_123', { subjectType: 'container', subjectId: 'uuid-of-cask', attestationType: 'temperature', recordedAt: '2025-04-15T14:30:00Z', value: { celsius: 12.4 }, ownerData: { sensorId: 'TEMP-7' }, unit: '°C', visibility: 'public', }) ```
5522
+
5523
+ **createBatch**(collectionId: string,
5524
+ items: CreateAttestationInput[]) → `Promise<Attestation[]>`
5525
+ Batch-create attestations (admin). Sends an array of `CreateAttestationInput` objects in a single request. The server processes them atomically and returns the created records. ```typescript const records = await attestations.createBatch('coll_123', [ { subjectType: 'container', subjectId: 'uuid1', attestationType: 'temperature', value: { celsius: 12.4 } }, { subjectType: 'container', subjectId: 'uuid1', attestationType: 'humidity', value: { rh: 68 } }, ]) ```
5526
+
5527
+ **list**(collectionId: string,
5528
+ params: ListAttestationsParams) → `Promise<ListAttestationsResponse>`
5529
+ List attestations for a subject (admin). Returns all three data zones. Supports filtering by type and date range. ```typescript const { attestations: records } = await attestations.list('coll_123', { subjectType: 'container', subjectId: 'uuid-of-cask', attestationType: 'temperature', recordedAfter: '2025-01-01T00:00:00Z', limit: 50, }) ```
5530
+
5531
+ **summary**(collectionId: string,
5532
+ params: AttestationSummaryParams) → `Promise<AttestationSummaryResponse>`
5533
+ Time-series summary of attestations (admin). Aggregates attestation counts (and optionally a numeric `value` field) into time buckets. Useful for charting trends. `attestationType` are required ```typescript const { summary } = await attestations.summary('coll_123', { subjectType: 'container', subjectId: 'uuid-of-cask', attestationType: 'temperature', valueField: 'celsius', groupBy: 'day', recordedAfter: '2025-01-01T00:00:00Z', }) ```
5534
+
5535
+ **latest**(collectionId: string,
5536
+ params: AttestationLatestParams) → `Promise<AttestationLatestResponse>`
5537
+ Latest snapshot — one record per `attestationType` (admin). Returns the most-recent attestation for each type recorded against this subject. Ideal for dashboards that show the current state of a container. ```typescript const { latest } = await attestations.latest('coll_123', { subjectType: 'container', subjectId: 'uuid-of-fridge', }) // latest[0].attestationType === 'temperature' // latest[0].latest.value === { celsius: 4.1 } ```
5538
+
5539
+ **verify**(collectionId: string,
5540
+ params: AttestationVerifyParams) → `Promise<ChainVerifyResult>`
5541
+ Verify the hash chain for a `(subjectType, subjectId, attestationType)` tuple (admin). Re-computes each `contentHash` and confirms it matches the stored value and correctly references the previous record's hash. A `valid: false` result with `failedAt` indicates the first broken link. ```typescript const result = await attestations.verify('coll_123', { subjectType: 'container', subjectId: 'uuid-of-cask', attestationType: 'temperature', }) if (!result.valid) { console.warn('Chain broken at', result.failedAt) } ```
5542
+
5543
+ **treeSummary**(collectionId: string,
5544
+ params: AttestationTreeSummaryParams) → `Promise<AttestationTreeSummaryResponse>`
5545
+ Tree time-series summary — aggregates across an entire container subtree (admin). Performs a BFS traversal of the container hierarchy rooted at `subjectId`, collects all descendant container IDs (and optionally their items), then aggregates attestations across all of them. `subjectType` is implicitly `'container'` ```typescript const { summary, subjectCount } = await attestations.treeSummary('coll_123', { subjectId: 'root-warehouse-uuid', attestationType: 'temperature', valueField: 'celsius', groupBy: 'hour', includeItems: true, }) console.log(`Aggregated over ${subjectCount} subjects`) ```
5546
+
5547
+ **treeLatest**(collectionId: string,
5548
+ params: AttestationTreeLatestParams) → `Promise<AttestationTreeLatestResponse>`
5549
+ Tree latest snapshot — most-recent record per type across a container subtree (admin). Same BFS traversal as `treeSummary`, but returns the most-recent record per `attestationType` aggregated across the entire subtree.
5550
+
5551
+ **publicList**(collectionId: string,
5552
+ params: ListAttestationsParams) → `Promise<PublicListAttestationsResponse>`
5553
+ List attestations for a subject (public). Records with `visibility='admin'` are always excluded. Records with `visibility='owner'` are included only when the caller provides a valid Firebase ID token that resolves to the subject owner. The `audience` field in the response indicates the tier that was served. ```typescript const { attestations: records, audience } = await attestations.publicList('coll_123', { subjectType: 'proof', subjectId: 'proof-uuid', }) ```
5554
+
5555
+ **publicSummary**(collectionId: string,
5556
+ params: AttestationSummaryParams) → `Promise<PublicAttestationSummaryResponse>`
5557
+ Time-series summary (public). Always served at `audience='public'`. Same parameters as the admin version. `attestationType` are required
5558
+
5559
+ **publicLatest**(collectionId: string,
5560
+ params: AttestationLatestParams) → `Promise<PublicAttestationLatestResponse>`
5561
+ Latest snapshot per `attestationType` (public). Owner elevation applies — provide a Firebase ID token for owner-tier data.
5562
+
5563
+ **publicTreeSummary**(collectionId: string,
5564
+ params: AttestationTreeSummaryParams) → `Promise<PublicAttestationTreeSummaryResponse>`
5565
+ Tree time-series summary (public). Always served at `audience='public'`. Performs the same BFS traversal as the admin version but only includes publicly visible attestations.
5566
+
5567
+ **publicTreeLatest**(collectionId: string,
5568
+ params: AttestationTreeLatestParams) → `Promise<PublicAttestationTreeLatestResponse>`
5569
+ Tree latest snapshot (public).
5570
+
5571
+ **publicContainerList**(collectionId: string,
5572
+ containerId: string,
5573
+ params?: Omit<ListAttestationsParams, 'subjectType' | 'subjectId'>) → `Promise<PublicListAttestationsResponse>`
5574
+ List attestations for a specific container (public shortcut). Equivalent to `publicList` with `subjectType='container'` and `subjectId=containerId` pre-filled.
5575
+
5576
+ **publicContainerSummary**(collectionId: string,
5577
+ containerId: string,
5578
+ params: Omit<AttestationSummaryParams, 'subjectType' | 'subjectId'>) → `Promise<PublicAttestationSummaryResponse>`
5579
+ Time-series summary for a specific container (public shortcut).
5580
+
5581
+ **publicContainerLatest**(collectionId: string,
5582
+ containerId: string) → `Promise<PublicAttestationLatestResponse>`
5583
+ Latest snapshot for a specific container (public shortcut).
5584
+
5585
+ **publicContainerTreeSummary**(collectionId: string,
5586
+ containerId: string,
5587
+ params: Omit<AttestationTreeSummaryParams, 'subjectId'>) → `Promise<PublicAttestationTreeSummaryResponse>`
5588
+ Tree time-series summary rooted at a specific container (public shortcut).
5589
+
5590
+ **publicContainerTreeLatest**(collectionId: string,
5591
+ containerId: string,
5592
+ params?: Pick<AttestationTreeLatestParams, 'includeItems'>) → `Promise<PublicAttestationTreeLatestResponse>`
5593
+ Tree latest snapshot rooted at a specific container (public shortcut).
4961
5594
 
4962
5595
  ### auth
4963
5596
 
@@ -5378,6 +6011,63 @@ Public: Get the contact schema for a collection. GET /public/collection/:collect
5378
6011
  userId: string,) → `Promise<UserSearchResponse>`
5379
6012
  Public: Get the contact schema for a collection. GET /public/collection/:collectionId/contact/schema Returns a ContactSchemaResponse describing all publicly visible contact fields. Core fields and collection-defined custom fields are merged into a single flat schema. Fields not in `publicVisibleFields` are stripped entirely from the response. Fields visible but not in `publicEditableFields` have `ui:disabled: true` in `uiSchema`. Use `fieldOrder` to render fields in the correct sequence, and `evaluateConditions` from the types package to handle conditional field visibility. ```typescript import { contact, evaluateConditions } from '@proveanything/smartlinks' const schema = await contact.publicGetSchema(collectionId) for (const fieldId of schema.fieldOrder) { const property = schema.schema.properties[fieldId] const ui = schema.uiSchema[fieldId] || {} const visible = evaluateConditions(property.conditions, property.showWhen, formValues) const disabled = ui['ui:disabled'] === true if (visible) renderField({ fieldId, property, ui, disabled }) } ```
5380
6013
 
6014
+ ### containers
6015
+
6016
+ **create**(collectionId: string,
6017
+ data: CreateContainerInput) → `Promise<Container>`
6018
+ Create a new container (admin). ```typescript const cask = await containers.create('coll_123', { containerType: 'cask', ref: 'CASK-0042', name: 'Cask 42 — Single Malt', metadata: { distilleryYear: 2019, capacity: 200 }, }) ```
6019
+
6020
+ **list**(collectionId: string,
6021
+ params?: ListContainersParams) → `Promise<ListContainersResponse>`
6022
+ List containers (admin). Supports filtering by type, status, ref, parent, and top-level flag. ```typescript // All active pallets const { containers: pallets } = await containers.list('coll_123', { containerType: 'pallet', status: 'active', limit: 50, }) // Top-level containers only const { containers: roots } = await containers.list('coll_123', { topLevel: true }) ```
6023
+
6024
+ **findForItem**(collectionId: string,
6025
+ params: FindContainersForItemParams) → `Promise<FindContainersForItemResponse>`
6026
+ Reverse lookup — find all containers currently holding a specific item (admin). ```typescript const { containers: holding } = await containers.findForItem('coll_123', { itemType: 'proof', itemId: 'proof-uuid', }) ```
6027
+
6028
+ **get**(collectionId: string,
6029
+ containerId: string,
6030
+ params?: GetContainerParams) → `Promise<Container>`
6031
+ Get a single container by ID (admin). Pass `?tree=true` to recursively embed children, and/or `?includeContents=true` to embed the current item list. ```typescript // Flat const cask = await containers.get('coll_123', 'cask-uuid') // Full tree with contents const tree = await containers.get('coll_123', 'warehouse-uuid', { tree: true, treeDepth: 3, includeContents: true, }) ```
6032
+
6033
+ **update**(collectionId: string,
6034
+ containerId: string,
6035
+ data: UpdateContainerInput) → `Promise<Container>`
6036
+ Partially update a container (admin). Only fields present in the request body are modified. Pass `parentContainerId: null` to promote a container to top-level. ```typescript const updated = await containers.update('coll_123', 'cask-uuid', { status: 'archived', metadata: { bottledAt: '2025-04-01' }, }) ```
6037
+
6038
+ **remove**(collectionId: string,
6039
+ containerId: string) → `Promise<`
6040
+ Soft-delete a container (admin). Sets `deletedAt`; the record and its full item history remain queryable by admins. Public API responses automatically exclude deleted containers.
6041
+
6042
+ **listItems**(collectionId: string,
6043
+ containerId: string,
6044
+ params?: ListContainerItemsParams) → `Promise<ContainerItemsResponse>`
6045
+ List items currently (or historically) inside a container (admin). Pass `history: true` to include removed items and see the full membership log. ```typescript // Current contents const { items } = await containers.listItems('coll_123', 'cask-uuid') // Full history including removed items const { items: history } = await containers.listItems('coll_123', 'cask-uuid', { history: true }) ```
6046
+
6047
+ **addItems**(collectionId: string,
6048
+ containerId: string,
6049
+ data: AddContainerItemsInput) → `Promise<AddContainerItemsResponse>`
6050
+ Add one or more items to a container (admin). Each item requires `itemType` and `itemId`. Pass `productId` / `proofId` for denormalisation convenience. ```typescript const { items } = await containers.addItems('coll_123', 'pallet-uuid', { items: [ { itemType: 'tag', itemId: 'NFC-00AABBCC' }, { itemType: 'proof', itemId: 'proof-uuid', productId: 'product-id' }, ], }) ```
6051
+
6052
+ **removeItems**(collectionId: string,
6053
+ containerId: string,
6054
+ data: RemoveContainerItemsInput) → `Promise<RemoveContainerItemsResponse>`
6055
+ Soft-remove items from a container (admin). Sets `removedAt` on the specified `ContainerItem` records. The records are retained in the history log and can be queried with `history: true`. ```typescript const result = await containers.removeItems('coll_123', 'pallet-uuid', { ids: ['container-item-uuid-1', 'container-item-uuid-2'], }) console.log(`Removed ${result.removedCount} items`) ```
6056
+
6057
+ **publicList**(collectionId: string,
6058
+ params?: ListContainersParams) → `Promise<PublicListContainersResponse>`
6059
+ List containers (public). Soft-deleted containers and containers with `metadata.publicListing === false` are excluded from results.
6060
+
6061
+ **publicGet**(collectionId: string,
6062
+ containerId: string,
6063
+ params?: GetContainerParams) → `Promise<Container>`
6064
+ Get a single container (public). Soft-deleted containers return a 404. Same `?tree` and `?includeContents` options as the admin version.
6065
+
6066
+ **publicListItems**(collectionId: string,
6067
+ containerId: string,
6068
+ params?: Pick<ListContainerItemsParams, 'limit' | 'offset'>) → `Promise<ContainerItemsResponse>`
6069
+ List current contents of a container (public). Returns only items where `removedAt` is null. No `?history` option on the public side.
6070
+
5381
6071
  ### crate
5382
6072
 
5383
6073
  **list**(collectionId: string,
@@ -5866,6 +6556,10 @@ Get a single tag mapping by tagId. ```typescript const tag = await tags.get('col
5866
6556
  params?: ListTagsRequest) → `Promise<ListTagsResponse>`
5867
6557
  List all tags for a collection with optional filters and pagination. ```typescript // List all tags const all = await tags.list('coll_123') // List with filters const filtered = await tags.list('coll_123', { productId: 'prod_456', variantId: 'var_789', limit: 50, offset: 0 }) ```
5868
6558
 
6559
+ **byRef**(collectionId: string,
6560
+ params: ReverseTagLookupParams) → `Promise<ReverseTagLookupResponse>`
6561
+ Reverse lookup — find all tags linked to a given app object (admin). Uses a global cross-shard index keyed on `(orgId, refType, refId)`, so it is safe to call without knowing which collection the object belongs to. ```typescript const { tags: linked } = await tags.byRef('coll_123', { refType: 'container', refId: 'container-uuid', }) ```
6562
+
5869
6563
  **getTag**(tagId: string,
5870
6564
  params?: PublicGetTagRequest) → `Promise<PublicGetTagResponse>`
5871
6565
  Public lookup of a single tag by tagId (global). Optionally embed related collection, product, or proof data. No authentication required. ```typescript // Simple lookup const result = await tags.getTag('TAG001') // With embedded data const withData = await tags.getTag('TAG001', { embed: 'collection,product,proof' }) console.log(withData.tag, withData.collection, withData.product, withData.proof) ```