@proveanything/smartlinks 2.0.69 → 2.0.71

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: 2.0.69 | Generated: 2026-10-20T19:38:11.744Z
3
+ Version: 2.0.71 | Generated: 2026-10-24T17:23:20.711Z
4
4
 
5
5
  This is a concise summary of all available API functions and types.
6
6
 
@@ -140,6 +140,7 @@ The Smartlinks SDK is organized into the following namespaces:
140
140
  - **async** - Functions for async operations
141
141
  - **attestation** - Functions for attestation operations
142
142
  - **attestations** - Functions for attestations operations
143
+ - **bookings** - Functions for bookings operations
143
144
  - **config** - Functions for config operations
144
145
  - **containers** - Functions for containers operations
145
146
  - **facets** - Functions for facets operations
@@ -2808,7 +2809,7 @@ interface ServerFunctionSl {
2808
2809
  tags: { resolve(id: string): Promise<ResolvedTag | null> };
2809
2810
  contacts: {
2810
2811
  upsert(details: ContactUpsertDetails): Promise<{ contactId: string; created: boolean }>;
2811
- forCaller(): Promise<{ contactId: string } | null>;
2812
+ forCaller(): Promise<CallerContact | null>;
2812
2813
  };
2813
2814
  interactions: { record(event: ServerFunctionInteractionEvent): Promise<{ eventId: string }> };
2814
2815
  tools: { run<T = any>(name: string, args?: Record<string, any>): Promise<T> };
@@ -2830,6 +2831,20 @@ interface ServerFunctionCaller {
2830
2831
  }
2831
2832
  ```
2832
2833
 
2834
+ **CallerContact** (interface)
2835
+ ```typescript
2836
+ interface CallerContact {
2837
+ contactId: string;
2838
+ email: string | null;
2839
+ phone: string | null;
2840
+ firstName: string | null;
2841
+ lastName: string | null;
2842
+ displayName: string | null;
2843
+ tags: string[];
2844
+ customFields: Record<string, unknown>;
2845
+ }
2846
+ ```
2847
+
2833
2848
  **ServerFunctionContext** (interface)
2834
2849
  ```typescript
2835
2850
  interface ServerFunctionContext {
@@ -3803,6 +3818,7 @@ interface Asset {
3803
3818
  proofId: string | null
3804
3819
  appId: string | null
3805
3820
  url: string
3821
+ assetUrl: string | null
3806
3822
  thumbnail: string | null
3807
3823
  name: string
3808
3824
  cleanName: string | null
@@ -4040,6 +4056,7 @@ interface CreateResumableUploadOptions {
4040
4056
  appId?: string
4041
4057
  admin?: boolean
4042
4058
  token?: string
4059
+ replaceAssetId?: string
4043
4060
  }
4044
4061
  ```
4045
4062
 
@@ -4565,9 +4582,9 @@ interface AppleLoginOptions {
4565
4582
  ```typescript
4566
4583
  interface MfaRequiredDetails {
4567
4584
  mfaSessionToken: string
4568
- availableFactors: Array<'email' | 'sms'>
4569
- preferredFactor: 'email' | 'sms'
4570
- maskedDestinations: { email?: string; sms?: string }
4585
+ availableFactors: MfaFactor[]
4586
+ preferredFactor: MfaFactor
4587
+ maskedDestinations: { email?: string; sms?: string; totp?: string }
4571
4588
  }
4572
4589
  ```
4573
4590
 
@@ -4575,7 +4592,7 @@ interface MfaRequiredDetails {
4575
4592
  ```typescript
4576
4593
  interface MfaChallengeSendResponse {
4577
4594
  success: true
4578
- factor: 'email' | 'sms'
4595
+ factor: MfaFactor
4579
4596
  destination: string
4580
4597
  expiresAt: string
4581
4598
  }
@@ -4590,11 +4607,23 @@ interface MfaEnrollSendResponse {
4590
4607
  }
4591
4608
  ```
4592
4609
 
4610
+ **MfaTotpEnrollResponse** (interface)
4611
+ ```typescript
4612
+ interface MfaTotpEnrollResponse {
4613
+ mfaSessionToken: string
4614
+ secret: string
4615
+ otpauthUri: string
4616
+ issuer: string
4617
+ account: string
4618
+ expiresAt: string
4619
+ }
4620
+ ```
4621
+
4593
4622
  **MfaEnrolledResponse** (interface)
4594
4623
  ```typescript
4595
4624
  interface MfaEnrolledResponse {
4596
4625
  enrolled: true
4597
- factor: 'email' | 'sms'
4626
+ factor: MfaFactor
4598
4627
  }
4599
4628
  ```
4600
4629
 
@@ -4604,6 +4633,7 @@ interface MfaFactorsResponse {
4604
4633
  enrolledFactors: {
4605
4634
  email?: { enrolledAt: string; destination: string }
4606
4635
  sms?: { enrolledAt: string; destination: string }
4636
+ totp?: { enrolledAt: string; destination: string }
4607
4637
  }
4608
4638
  recoveryCodesRemaining: number
4609
4639
  mfaEnabledForClient: boolean
@@ -4866,6 +4896,30 @@ interface AuthKitConfig {
4866
4896
  security?: AuthKitSecurityConfig
4867
4897
  collectionIds?: string[]
4868
4898
  identity?: AuthKitIdentity
4899
+ signUp?: 'open' | 'invite'
4900
+ }
4901
+ ```
4902
+
4903
+ **AuthKitInviteRequest** (interface)
4904
+ ```typescript
4905
+ interface AuthKitInviteRequest {
4906
+ email: string
4907
+ firstName?: string
4908
+ lastName?: string
4909
+ displayName?: string
4910
+ customFields?: Record<string, unknown>
4911
+ redirectUrl?: string
4912
+ }
4913
+ ```
4914
+
4915
+ **AuthKitInviteResponse** (interface)
4916
+ ```typescript
4917
+ interface AuthKitInviteResponse {
4918
+ ok: true
4919
+ userId: string
4920
+ contactId: string
4921
+ created: boolean
4922
+ expiresAt: string
4869
4923
  }
4870
4924
  ```
4871
4925
 
@@ -4934,6 +4988,8 @@ interface AuthKitLockoutPolicy {
4934
4988
 
4935
4989
  **AuthKitErrorCode** = ``
4936
4990
 
4991
+ **MfaFactor** = `'email' | 'sms' | 'totp'`
4992
+
4937
4993
  **MfaErrorCode** = ``
4938
4994
 
4939
4995
  **VerifyStatus** = `'pending' | 'verified' | 'failed' | 'expired' | 'unknown'`
@@ -5012,6 +5068,329 @@ interface BatchTag {
5012
5068
  }
5013
5069
  ```
5014
5070
 
5071
+ ### bookings
5072
+
5073
+ **BookingAllocation** (interface)
5074
+ ```typescript
5075
+ interface BookingAllocation {
5076
+ id: string
5077
+ bookingId: string | null
5078
+ slotId: string | null
5079
+ resourceType: string
5080
+ resourceId: string
5081
+ startsAt: string
5082
+ endsAt: string
5083
+ quantity: number
5084
+ mode: 'exclusive' | 'capacity'
5085
+ active: boolean
5086
+ sourceSystem?: string | null
5087
+ data: Record<string, any>
5088
+ }
5089
+ ```
5090
+
5091
+ **Booking** (interface)
5092
+ ```typescript
5093
+ interface Booking {
5094
+ id: string
5095
+ collectionId: string
5096
+ appId: string
5097
+ visibility: BookingVisibility
5098
+ contactId?: string
5099
+ status: BookingStatus
5100
+ startsAt: string
5101
+ endsAt: string
5102
+ timezone?: string | null
5103
+ quantity: number
5104
+ holdExpiresAt?: string | null
5105
+ flags: string[]
5106
+ cancelReason?: string | null
5107
+ idempotencyKey?: string | null
5108
+ seriesId?: string | null
5109
+ ref?: string | null
5110
+ customId?: string | null
5111
+ sourceSystem?: string | null
5112
+ productId?: string | null
5113
+ proofId?: string
5114
+ parentType?: string | null
5115
+ parentId?: string | null
5116
+ createdAt: string
5117
+ updatedAt: string
5118
+ cancelledAt?: string | null
5119
+ data: Record<string, any>
5120
+ owner?: Record<string, any>
5121
+ admin?: Record<string, any>
5122
+ allocations: BookingAllocation[]
5123
+ editToken?: string
5124
+ }
5125
+ ```
5126
+
5127
+ **BookingSlot** (interface)
5128
+ ```typescript
5129
+ interface BookingSlot {
5130
+ id: string
5131
+ collectionId: string
5132
+ appId: string
5133
+ visibility: BookingVisibility
5134
+ resourceType?: string | null
5135
+ resourceId?: string | null
5136
+ startsAt: string
5137
+ endsAt: string
5138
+ timezone?: string | null
5139
+ capacity: number
5140
+ booked: number
5141
+ remaining: number
5142
+ perContactLimit?: number | null
5143
+ status: 'open' | 'closed' | 'cancelled'
5144
+ seriesId?: string | null
5145
+ ref?: string | null
5146
+ customId?: string | null
5147
+ sourceSystem?: string | null
5148
+ productId?: string | null
5149
+ createdAt: string
5150
+ updatedAt: string
5151
+ data: Record<string, any>
5152
+ owner?: Record<string, any>
5153
+ admin?: Record<string, any>
5154
+ }
5155
+ ```
5156
+
5157
+ **CreateBookingInput** (interface)
5158
+ ```typescript
5159
+ interface CreateBookingInput {
5160
+ slotId?: string
5161
+ quantity?: number
5162
+ resourceType?: string
5163
+ resourceId?: string
5164
+ resource?: { type: string; id: string }
5165
+ startsAt?: string | Date
5166
+ endsAt?: string | Date
5167
+ allocations?: BookingClaimInput[]
5168
+ status?: 'held' | 'pending' | 'confirmed' | 'waitlisted'
5169
+ holdMinutes?: number
5170
+ bufferBefore?: number
5171
+ bufferAfter?: number
5172
+ idempotencyKey?: string
5173
+ contactId?: string
5174
+ timezone?: string
5175
+ visibility?: BookingVisibility
5176
+ ref?: string
5177
+ customId?: string
5178
+ sourceSystem?: string
5179
+ productId?: string
5180
+ proofId?: string
5181
+ parentType?: string
5182
+ parentId?: string
5183
+ seriesId?: string
5184
+ data?: Record<string, any>
5185
+ owner?: Record<string, any>
5186
+ admin?: Record<string, any>
5187
+ }
5188
+ ```
5189
+
5190
+ **UpdateBookingInput** (interface)
5191
+ ```typescript
5192
+ interface UpdateBookingInput {
5193
+ data?: Record<string, any>
5194
+ owner?: Record<string, any>
5195
+ admin?: Record<string, any>
5196
+ visibility?: BookingVisibility
5197
+ ref?: string
5198
+ timezone?: string
5199
+ productId?: string
5200
+ proofId?: string
5201
+ contactId?: string
5202
+ sourceSystem?: string
5203
+ customId?: string
5204
+ flags?: string[]
5205
+ }
5206
+ ```
5207
+
5208
+ **MoveBookingInput** (interface)
5209
+ ```typescript
5210
+ interface MoveBookingInput {
5211
+ slotId?: string
5212
+ resourceType?: string
5213
+ resourceId?: string
5214
+ resource?: { type: string; id: string }
5215
+ startsAt?: string | Date
5216
+ endsAt?: string | Date
5217
+ allocations?: BookingClaimInput[]
5218
+ bufferBefore?: number
5219
+ bufferAfter?: number
5220
+ }
5221
+ ```
5222
+
5223
+ **BookingListQueryParams** (interface)
5224
+ ```typescript
5225
+ interface BookingListQueryParams {
5226
+ status?: string
5227
+ contactId?: string
5228
+ slotId?: string
5229
+ resourceType?: string
5230
+ resourceId?: string
5231
+ from?: string | Date
5232
+ to?: string | Date
5233
+ ref?: string
5234
+ customId?: string
5235
+ sourceSystem?: string
5236
+ productId?: string
5237
+ seriesId?: string
5238
+ sort?: string
5239
+ limit?: number
5240
+ offset?: number
5241
+ }
5242
+ ```
5243
+
5244
+ **CreateSlotInput** (interface)
5245
+ ```typescript
5246
+ interface CreateSlotInput {
5247
+ startsAt: string | Date
5248
+ endsAt: string | Date
5249
+ capacity: number
5250
+ perContactLimit?: number
5251
+ resourceType?: string
5252
+ resourceId?: string
5253
+ blockResource?: boolean
5254
+ status?: 'open' | 'closed' | 'cancelled'
5255
+ timezone?: string
5256
+ visibility?: BookingVisibility
5257
+ seriesId?: string
5258
+ ref?: string
5259
+ customId?: string
5260
+ sourceSystem?: string
5261
+ productId?: string
5262
+ data?: Record<string, any>
5263
+ owner?: Record<string, any>
5264
+ admin?: Record<string, any>
5265
+ }
5266
+ ```
5267
+
5268
+ **SlotListQueryParams** (interface)
5269
+ ```typescript
5270
+ interface SlotListQueryParams {
5271
+ status?: string
5272
+ available?: boolean
5273
+ from?: string | Date
5274
+ to?: string | Date
5275
+ resourceType?: string
5276
+ resourceId?: string
5277
+ productId?: string
5278
+ seriesId?: string
5279
+ ref?: string
5280
+ customId?: string
5281
+ sort?: string
5282
+ limit?: number
5283
+ offset?: number
5284
+ }
5285
+ ```
5286
+
5287
+ **CreateBlockInput** (interface)
5288
+ ```typescript
5289
+ interface CreateBlockInput {
5290
+ resourceType: string
5291
+ resourceId: string
5292
+ startsAt: string | Date
5293
+ endsAt: string | Date
5294
+ sourceSystem?: string
5295
+ data?: Record<string, any>
5296
+ }
5297
+ ```
5298
+
5299
+ **BlockListQueryParams** (interface)
5300
+ ```typescript
5301
+ interface BlockListQueryParams {
5302
+ resourceType?: string
5303
+ resourceId?: string
5304
+ from?: string | Date
5305
+ to?: string | Date
5306
+ limit?: number
5307
+ offset?: number
5308
+ }
5309
+ ```
5310
+
5311
+ **FreeBusyQuery** (interface)
5312
+ ```typescript
5313
+ interface FreeBusyQuery {
5314
+ resources: BookingResourceRef[]
5315
+ from: string | Date
5316
+ to: string | Date
5317
+ }
5318
+ ```
5319
+
5320
+ **FreeBusyInterval** (interface)
5321
+ ```typescript
5322
+ interface FreeBusyInterval {
5323
+ start: string
5324
+ end: string
5325
+ }
5326
+ ```
5327
+
5328
+ **FreeBusyResponse** (interface)
5329
+ ```typescript
5330
+ interface FreeBusyResponse {
5331
+ from: string
5332
+ to: string
5333
+ resources: Array<{ resourceType: string; resourceId: string; busy: FreeBusyInterval[] }>
5334
+ }
5335
+ ```
5336
+
5337
+ **BookingAccessOptions** (interface)
5338
+ ```typescript
5339
+ interface BookingAccessOptions {
5340
+ editToken?: string
5341
+ }
5342
+ ```
5343
+
5344
+ **ScheduleHours** (interface)
5345
+ ```typescript
5346
+ interface ScheduleHours {
5347
+ start: string
5348
+ end: string
5349
+ }
5350
+ ```
5351
+
5352
+ **ScheduleOverride** (interface)
5353
+ ```typescript
5354
+ interface ScheduleOverride {
5355
+ date?: string
5356
+ from?: string
5357
+ to?: string
5358
+ hours: ScheduleHours[]
5359
+ }
5360
+ ```
5361
+
5362
+ **StandardSchedule** (interface)
5363
+ ```typescript
5364
+ interface StandardSchedule {
5365
+ timezone: string
5366
+ weekly?: Partial<Record<ScheduleDay, ScheduleHours[]>>
5367
+ overrides?: ScheduleOverride[]
5368
+ }
5369
+ ```
5370
+
5371
+ **BookingStatus** = ``
5372
+
5373
+ **BookingVisibility** = `'public' | 'owner' | 'admin'`
5374
+
5375
+ **BookingClaimInput** = ``
5376
+
5377
+ **UpdateSlotInput** = `Partial<Omit<CreateSlotInput, 'blockResource' | 'seriesId' | 'resourceType' | 'resourceId'>>`
5378
+
5379
+ **BookingResourceRef** (type)
5380
+ ```typescript
5381
+ type BookingResourceRef = { type: string; id: string }
5382
+ ```
5383
+
5384
+ **BookingList** = `PaginatedResponse<Booking>`
5385
+
5386
+ **SlotList** = `PaginatedResponse<BookingSlot>`
5387
+
5388
+ **BlockList** = `PaginatedResponse<BookingAllocation>`
5389
+
5390
+ **BookingErrorCode** = ``
5391
+
5392
+ **ScheduleDay** = `'mon' | 'tue' | 'wed' | 'thu' | 'fri' | 'sat' | 'sun'`
5393
+
5015
5394
  ### broadcasts
5016
5395
 
5017
5396
  **ListBroadcastsQuery** (interface)
@@ -10515,6 +10894,41 @@ interface ConditionDebugOptions {
10515
10894
 
10516
10895
  **ConditionDebugLogger** = `(...args: any[]) => void`
10517
10896
 
10897
+ ### freeTimes (utils)
10898
+
10899
+ **TimeInterval** (interface)
10900
+ ```typescript
10901
+ interface TimeInterval {
10902
+ start: number
10903
+ end: number
10904
+ }
10905
+ ```
10906
+
10907
+ **FreeTimesOptions** (interface)
10908
+ ```typescript
10909
+ interface FreeTimesOptions {
10910
+ hours: StandardSchedule | TimeInterval[]
10911
+ busy?: Array<FreeBusyInterval | TimeInterval>
10912
+ from: string | number | Date
10913
+ to: string | number | Date
10914
+ duration: number
10915
+ step?: number
10916
+ bufferBefore?: number
10917
+ bufferAfter?: number
10918
+ minNotice?: number
10919
+ now?: number
10920
+ buffersWithinHours?: boolean
10921
+ }
10922
+ ```
10923
+
10924
+ **FreeTimeSlot** (interface)
10925
+ ```typescript
10926
+ interface FreeTimeSlot {
10927
+ start: string
10928
+ end: string
10929
+ }
10930
+ ```
10931
+
10518
10932
  ### paths (utils)
10519
10933
 
10520
10934
  **PortalPathParams** (interface)
@@ -11012,6 +11426,9 @@ Soft-delete an asset. Schedules CDN purge after `graceDays` (default 30). Recove
11012
11426
  **restoreAdmin**(collectionId: string, assetId: string) → `Promise<Asset>`
11013
11427
  Restore a soft-deleted asset (clears `deletedAt`).
11014
11428
 
11429
+ **ensureAssetUrl**(collectionId: string, assetId: string) → `Promise<Asset>`
11430
+ Give an existing asset its own address (`assetUrl`). New and replaced assets get one automatically; this is for assets made before asset addresses existed. Safe to call again. → the asset, with `assetUrl`.
11431
+
11015
11432
  **bulkDelete**(options: BulkDeleteAssetsOptions) → `Promise<`
11016
11433
  Soft-delete multiple assets in one request.
11017
11434
 
@@ -11291,8 +11708,8 @@ Update the authenticated user's profile and replace the bearer token when refres
11291
11708
  **deleteAccount**(clientId: string, password: string, confirmText: string) → `Promise<SuccessResponse>`
11292
11709
  Update the authenticated user's profile and replace the bearer token when refreshed claims are returned.
11293
11710
 
11294
- **mfaChallengeSend**(clientId: string, mfaSessionToken: string, factor: 'email' | 'sms') → `Promise<MfaChallengeSendResponse>`
11295
- Send (or resend) an MFA challenge code to the given factor (public).
11711
+ **mfaChallengeSend**(clientId: string, mfaSessionToken: string, factor: MfaFactor) → `Promise<MfaChallengeSendResponse>`
11712
+ Send (or resend) an MFA challenge code to the given factor (public). For `totp` nothing is sent — it tells the server the code will come from their authenticator app; then {@link mfaChallengeVerify}.
11296
11713
 
11297
11714
  **mfaChallengeVerify**(clientId: string, mfaSessionToken: string, code: string, trustDevice?: boolean, deviceLabel?: string) → `Promise<MfaFinalizeResponse>`
11298
11715
  Verify an MFA challenge code and finalize the login (public). On success this behaves like {@link login} — the bearer token is adopted and the cache invalidated. it and pass it to future {@link login} calls to skip the challenge on this device.
@@ -11315,10 +11732,16 @@ Begin SMS-factor enrollment; sends a code to the given phone number (authenticat
11315
11732
  **confirmSmsMfa**(clientId: string, mfaSessionToken: string, code: string) → `Promise<MfaEnrolledResponse>`
11316
11733
  Confirm SMS-factor enrollment with the code sent by {@link enrollSmsMfa} (authenticated).
11317
11734
 
11735
+ **enrollTotpMfa**(clientId: string) → `Promise<MfaTotpEnrollResponse>`
11736
+ Begin authenticator-app enrollment (authenticated): a new secret for Google Authenticator, Microsoft Authenticator, 1Password and the like. Show `otpauthUri` as a QR code (and `secret` for typing in), then {@link confirmTotpMfa} with the code the app shows. Nothing is kept until then; setting up again replaces the previous app once confirmed.
11737
+
11738
+ **confirmTotpMfa**(clientId: string, mfaSessionToken: string, code: string) → `Promise<MfaEnrolledResponse>`
11739
+ Confirm authenticator-app enrollment with the 6-digit code the app shows (authenticated).
11740
+
11318
11741
  **generateMfaRecoveryCodes**(clientId: string, password: string) → `Promise<`
11319
11742
  Generate a fresh set of recovery codes, invalidating any previous set (authenticated). Returned **in plaintext, exactly once** — nothing else in the API ever returns them again, so the caller must display/export them immediately.
11320
11743
 
11321
- **removeMfaFactor**(clientId: string, factor: 'email' | 'sms', password: string) → `Promise<SuccessResponse>`
11744
+ **removeMfaFactor**(clientId: string, factor: MfaFactor, password: string) → `Promise<SuccessResponse>`
11322
11745
  Remove an enrolled MFA factor (authenticated). Server route is DELETE with a body.
11323
11746
 
11324
11747
  **listTrustedDevices**(clientId: string) → `Promise<`
@@ -11345,8 +11768,11 @@ Update an AuthKit client config (admin). This is how the account **security poli
11345
11768
  **setIdentity**(collectionId: string, authKitId: string, body: { mode: 'own' }) → `Promise<AuthKitSetIdentityResponse>`
11346
11769
  Give this AuthKit its **own logins** (admin): its members become accounts of this site only — the same email can be a separate account, with its own password, on another site — rather than SmartLinks accounts shared across sites. One way: a site with its own members can't go back to the shared pool. Members who signed up before keep their SmartLinks account until moved across. Errors: `MEMBER_POOL_CONFLICT` (409) when another AuthKit already gives one of its collections its own logins (one per collection); `PERMISSION_DENIED` (403) unless you administer every collection it serves.
11347
11770
 
11771
+ **invite**(collectionId: string, authKitId: string, body: AuthKitInviteRequest) → `Promise<AuthKitInviteResponse>`
11772
+ Invite someone to be a member of a site with its own logins (admin). Makes their account if they have none (the only way in when the site is invitation only — `signUp: 'invite'`), finds or creates their contact in this collection with the `customFields` you pass (their level), links the two, and emails them a sign-in link to the site (`redirectUrl`, default the kit's) that works once for 7 days. The page it opens handles it like any magic link: `mode=magicLink&token=…` → {@link verifyMagicLink}. Inviting someone again sends a fresh link. Errors: `OWN_LOGINS_REQUIRED` (409), `INVALID_EMAIL` (400), `INVALID_REDIRECT_URL` (400, not one of this site's addresses), `TOO_MANY_INVITES` (429, 5 an hour per address).
11773
+
11348
11774
  **remove**(collectionId: string, authKitId: string) → `Promise<void>`
11349
- Give this AuthKit its **own logins** (admin): its members become accounts of this site only — the same email can be a separate account, with its own password, on another site — rather than SmartLinks accounts shared across sites. One way: a site with its own members can't go back to the shared pool. Members who signed up before keep their SmartLinks account until moved across. Errors: `MEMBER_POOL_CONFLICT` (409) when another AuthKit already gives one of its collections its own logins (one per collection); `PERMISSION_DENIED` (403) unless you administer every collection it serves.
11775
+ Invite someone to be a member of a site with its own logins (admin). Makes their account if they have none (the only way in when the site is invitation only — `signUp: 'invite'`), finds or creates their contact in this collection with the `customFields` you pass (their level), links the two, and emails them a sign-in link to the site (`redirectUrl`, default the kit's) that works once for 7 days. The page it opens handles it like any magic link: `mode=magicLink&token=…` → {@link verifyMagicLink}. Inviting someone again sends a fresh link. Errors: `OWN_LOGINS_REQUIRED` (409), `INVALID_EMAIL` (400), `INVALID_REDIRECT_URL` (400, not one of this site's addresses), `TOO_MANY_INVITES` (429, 5 an hour per address).
11350
11776
 
11351
11777
  ### batch
11352
11778
 
@@ -11406,6 +11832,72 @@ Find a specific batch by ID across all products in a collection. Returns the bat
11406
11832
  claimSetId?: string) → `Promise<BatchTag[]>`
11407
11833
  Get all tags/codes assigned to a specific batch. Shows which claim set codes have been assigned to this batch. ```typescript // Get all tags assigned to a batch const tags = await batch.getBatchTags('coll_123', 'BATCH-2024-001') console.log(`Batch has ${tags.length} tags assigned`) tags.forEach(tag => { console.log(`Code: ${tag.code}, ClaimSet: ${tag.claimSetId}, TagID: ${tag.tagId}`) }) // Get tags from a specific claim set const claimSetTags = await batch.getBatchTags('coll_123', 'BATCH-2024-001', '000001') ```
11408
11834
 
11835
+ ### bookings
11836
+
11837
+ **create**(collectionId: string, appId: string, input: CreateBookingInput, admin: boolean = false) → `Promise<Booking>`
11838
+ Book. All claims succeed together or nothing is written; a clash fails with 409 (`SLOT_FULL`, `RESOURCE_TAKEN`, `PER_CONTACT_LIMIT`, …). Pass `idempotencyKey` so a retry never books twice. Public (admin = false): the app's `publicCreate.bookings` rules decide the status and limits; an anonymous guest may get `editToken` back (once) to manage the booking later. POST /bookings
11839
+
11840
+ **list**(collectionId: string, appId: string, params?: BookingListQueryParams, admin: boolean = true) → `Promise<PaginatedResponse<Booking>>`
11841
+ List bookings (admin). GET /bookings
11842
+
11843
+ **mine**(collectionId: string, appId: string, params?: BookingListQueryParams) → `Promise<PaginatedResponse<Booking>>`
11844
+ The signed-in caller's own bookings (public). GET /bookings/mine
11845
+
11846
+ **get**(collectionId: string, appId: string, bookingId: string, admin: boolean = false, opts?: BookingAccessOptions) → `Promise<Booking>`
11847
+ Get one booking. Public: the signed-in booker, or a guest passing `{ editToken }`. GET /bookings/:bookingId
11848
+
11849
+ **update**(collectionId: string, appId: string, bookingId: string, input: UpdateBookingInput, admin: boolean = true) → `Promise<Booking>`
11850
+ Update zones and descriptive fields (admin). PATCH /bookings/:bookingId
11851
+
11852
+ **confirm**(collectionId: string, appId: string, bookingId: string, admin: boolean = false, opts?: BookingAccessOptions) → `Promise<Booking>`
11853
+ held / pending / waitlisted → confirmed (idempotent). A held booking whose hold has run out fails with HOLD_EXPIRED. Public: only the booker's own hold, when `ownerActions.bookings.confirm` allows. POST /bookings/:bookingId/confirm
11854
+
11855
+ **cancel**(collectionId: string, appId: string, bookingId: string, admin: boolean = false, opts?: BookingAccessOptions & { reason?: string }) → `Promise<Booking>`
11856
+ Cancel and give the places back (idempotent). Public: per `ownerActions.bookings.cancel` and its cutoff. `reason` is admin-only (public cancels record 'owner'). POST /bookings/:bookingId/cancel
11857
+
11858
+ **move**(collectionId: string, appId: string, bookingId: string, input: MoveBookingInput, admin: boolean = false, opts?: BookingAccessOptions) → `Promise<Booking>`
11859
+ Move to a new slot / time, all-or-nothing (a failed move leaves the booking as it was). Public: per `ownerActions.bookings.move`; the create rules are re-checked for the new time. POST /bookings/:bookingId/move
11860
+
11861
+ **extendHold**(collectionId: string, appId: string, bookingId: string, holdMinutes: number) → `Promise<Booking>`
11862
+ Extend a hold by `holdMinutes` from now (admin; capped at 24h after the booking was made).
11863
+
11864
+ **complete**(collectionId: string, appId: string, bookingId: string) → `Promise<Booking>`
11865
+ confirmed → completed (admin).
11866
+
11867
+ **noShow**(collectionId: string, appId: string, bookingId: string) → `Promise<Booking>`
11868
+ confirmed → no_show (admin).
11869
+
11870
+ **freebusy**(collectionId: string, appId: string, q: FreeBusyQuery, admin: boolean = false) → `Promise<FreeBusyResponse>`
11871
+ Busy intervals per resource (bookings, blocks, slots' own blocks) — never booking details. Public only when the app sets `publicRead.bookings.freebusy: true`. GET /bookings/freebusy
11872
+
11873
+ ### bookings.blocks
11874
+
11875
+ **create**(collectionId: string, appId: string, input: CreateBlockInput) → `Promise<BookingAllocation>`
11876
+
11877
+ **list**(collectionId: string, appId: string, params?: BlockListQueryParams) → `Promise<PaginatedResponse<BookingAllocation>>`
11878
+
11879
+ **remove**(collectionId: string, appId: string, blockId: string) → `Promise<`
11880
+
11881
+ ### bookings.slots
11882
+
11883
+ **create**(collectionId: string, appId: string, input: CreateSlotInput) → `Promise<BookingSlot>`
11884
+ Create a slot (admin). POST /bookings/slots
11885
+
11886
+ **createMany**(collectionId: string, appId: string, slots: CreateSlotInput[], opts?: { seriesId?: string }) → `Promise<`
11887
+ Create many slots at once — a series — all-or-nothing (admin, max 500). POST /bookings/slots/batch
11888
+
11889
+ **list**(collectionId: string, appId: string, params?: SlotListQueryParams, admin: boolean = false) → `Promise<PaginatedResponse<BookingSlot>>`
11890
+ List slots. Public: open, public slots only, each with `remaining`. GET /bookings/slots
11891
+
11892
+ **get**(collectionId: string, appId: string, slotId: string, admin: boolean = false) → `Promise<BookingSlot>`
11893
+ GET /bookings/slots/:slotId
11894
+
11895
+ **update**(collectionId: string, appId: string, slotId: string, input: UpdateSlotInput) → `Promise<BookingSlot>`
11896
+ Update a slot (admin). Capacity can't drop below what's booked (SLOT_OVERBOOKED); times can't change once anything is booked (SLOT_HAS_BOOKINGS).
11897
+
11898
+ **remove**(collectionId: string, appId: string, slotId: string) → `Promise<`
11899
+ Delete a slot (admin; refused while places are booked).
11900
+
11409
11901
  ### broadcasts
11410
11902
 
11411
11903
  **create**(collectionId: string,
@@ -12,6 +12,10 @@ SmartLinks provides three generic data models scoped to your app that can be ada
12
12
  - **Threads** — Manage discussions, comments, or any reply-based content
13
13
  - **Records** — Store structured data with flexible lifecycles
14
14
 
15
+ > **Bookings** (anything that claims time or a place — events, classes, appointments, rooms) have
16
+ > their own objects with no-double-booking and capacity guarantees: see [bookings.md](bookings.md).
17
+ > A booking app still uses records for its schedules, staff and settings.
18
+
15
19
  Each object type supports:
16
20
  - **JSONB zones** (`data`, `owner`, `admin`) for granular access control
17
21
  - **Visibility levels** (`public`, `owner`, `admin`) for content exposure