@serviceai/api-spec 1.2.434 → 1.6.2

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.
Files changed (4) hide show
  1. package/openapi.json +2480 -85
  2. package/openapi.yaml +1557 -7
  3. package/package.json +1 -1
  4. package/types.d.ts +963 -63
package/types.d.ts CHANGED
@@ -129,6 +129,238 @@ export interface paths {
129
129
  patch?: never;
130
130
  trace?: never;
131
131
  };
132
+ "/api/impersonate/native-read-ticket": {
133
+ parameters: {
134
+ query?: never;
135
+ header?: never;
136
+ path?: never;
137
+ cookie?: never;
138
+ };
139
+ get?: never;
140
+ put?: never;
141
+ /**
142
+ * Authorize an exact browser-native download URL for the current support session.
143
+ * @description Requires the current typed support session and X-Support-Impersonation: 1. A narrow fixed GET allowlist only; record permissions still run on every GET. Admission lasts at most 15 minutes and never outlives the original one-hour support grant. The same browser session is required; URL alone is insufficient. GET/Range retries recheck current authority. Response is no-store with no-referrer. No user bearer is issued.
144
+ */
145
+ post: {
146
+ parameters: {
147
+ query?: never;
148
+ header: {
149
+ "X-Support-Impersonation": "1";
150
+ };
151
+ path?: never;
152
+ cookie?: never;
153
+ };
154
+ requestBody: {
155
+ content: {
156
+ "application/json": {
157
+ url: string;
158
+ };
159
+ };
160
+ };
161
+ responses: {
162
+ /** @description Exact relative URL and terminal admission deadline. */
163
+ 200: {
164
+ headers: {
165
+ [name: string]: unknown;
166
+ };
167
+ content: {
168
+ "application/json": {
169
+ url: string;
170
+ expiresAt: number;
171
+ };
172
+ };
173
+ };
174
+ /** @description Unsupported destination or malformed request. */
175
+ 400: {
176
+ headers: {
177
+ [name: string]: unknown;
178
+ };
179
+ content?: never;
180
+ };
181
+ /** @description No authenticated session. */
182
+ 401: {
183
+ headers: {
184
+ [name: string]: unknown;
185
+ };
186
+ content?: never;
187
+ };
188
+ /** @description Support authority unavailable; explicit exit required. */
189
+ 403: {
190
+ headers: {
191
+ [name: string]: unknown;
192
+ };
193
+ content: {
194
+ "application/json": components["schemas"]["StreamAuthenticationError"];
195
+ };
196
+ };
197
+ /** @description Authentication lookup temporarily unavailable. */
198
+ 503: {
199
+ headers: {
200
+ [name: string]: unknown;
201
+ };
202
+ content: {
203
+ "application/json": components["schemas"]["StreamAuthenticationError"];
204
+ };
205
+ };
206
+ };
207
+ };
208
+ delete?: never;
209
+ options?: never;
210
+ head?: never;
211
+ patch?: never;
212
+ trace?: never;
213
+ };
214
+ "/api/events/ticket": {
215
+ parameters: {
216
+ query?: never;
217
+ header?: never;
218
+ path?: never;
219
+ cookie?: never;
220
+ };
221
+ get?: never;
222
+ put?: never;
223
+ /**
224
+ * Create a short-lived stream-only admission ticket from the current authenticated actor.
225
+ * @description Connect within at most 60 seconds using GET /api/events?ticket=.... The ticket preserves the real principal, effective target and original login/impersonation deadlines; it cannot authenticate ordinary API requests. It is never a target-user bearer token. Response Cache-Control is no-store. An invalid temporary context returns 403 and must be explicitly exited, without dropping the real login.
226
+ */
227
+ post: {
228
+ parameters: {
229
+ query?: never;
230
+ header?: never;
231
+ path?: never;
232
+ cookie?: never;
233
+ };
234
+ requestBody?: {
235
+ content: {
236
+ "application/json": Record<string, never>;
237
+ };
238
+ };
239
+ responses: {
240
+ /** @description Opaque ticket, usable only for short-lived stream admission. */
241
+ 200: {
242
+ headers: {
243
+ [name: string]: unknown;
244
+ };
245
+ content: {
246
+ "application/json": components["schemas"]["EventStreamTicketResponse"];
247
+ };
248
+ };
249
+ /** @description Unexpected request fields. */
250
+ 400: {
251
+ headers: {
252
+ [name: string]: unknown;
253
+ };
254
+ content: {
255
+ "application/json": {
256
+ message: string;
257
+ errors: unknown[];
258
+ };
259
+ };
260
+ };
261
+ /** @description Real principal is missing, deleted, revoked or expired. */
262
+ 401: {
263
+ headers: {
264
+ [name: string]: unknown;
265
+ };
266
+ content: {
267
+ "application/json": components["schemas"]["StreamAuthenticationError"];
268
+ };
269
+ };
270
+ /** @description Impersonation is unavailable; explicitly exit before continuing as the real principal. */
271
+ 403: {
272
+ headers: {
273
+ [name: string]: unknown;
274
+ };
275
+ content: {
276
+ "application/json": components["schemas"]["StreamAuthenticationError"];
277
+ };
278
+ };
279
+ /** @description Authentication lookup unavailable; retry without discarding credentials. */
280
+ 503: {
281
+ headers: {
282
+ [name: string]: unknown;
283
+ };
284
+ content: {
285
+ "application/json": components["schemas"]["StreamAuthenticationError"];
286
+ };
287
+ };
288
+ };
289
+ };
290
+ delete?: never;
291
+ options?: never;
292
+ head?: never;
293
+ patch?: never;
294
+ trace?: never;
295
+ };
296
+ "/api/events": {
297
+ parameters: {
298
+ query?: never;
299
+ header?: never;
300
+ path?: never;
301
+ cookie?: never;
302
+ };
303
+ /**
304
+ * Open the authenticated server-sent event stream.
305
+ * @description New clients use a stream-only ticket in the ticket query parameter. Legacy authenticated connections remain supported. A supplied invalid ticket never falls back to another credential. Current user, session and revocation state is rechecked before admission and each delivery batch/heartbeat. Original authority deadlines also close idle or blocked sockets. A stream:resync hint means refresh authorized snapshots; this stream is not a replay log.
306
+ */
307
+ get: {
308
+ parameters: {
309
+ query?: {
310
+ ticket?: string;
311
+ };
312
+ header?: never;
313
+ path?: never;
314
+ cookie?: never;
315
+ };
316
+ requestBody?: never;
317
+ responses: {
318
+ /** @description Bounded SSE hints and heartbeat comments until disconnect or authority expiry. */
319
+ 200: {
320
+ headers: {
321
+ [name: string]: unknown;
322
+ };
323
+ content: {
324
+ "text/event-stream": string;
325
+ };
326
+ };
327
+ /** @description Ticket/source authentication expired, revoked or invalid. */
328
+ 401: {
329
+ headers: {
330
+ [name: string]: unknown;
331
+ };
332
+ content: {
333
+ "application/json": components["schemas"]["StreamAuthenticationError"];
334
+ };
335
+ };
336
+ /** @description Legacy temporary context is unavailable. */
337
+ 403: {
338
+ headers: {
339
+ [name: string]: unknown;
340
+ };
341
+ content: {
342
+ "application/json": components["schemas"]["StreamAuthenticationError"];
343
+ };
344
+ };
345
+ /** @description Authorization temporarily unavailable; retry with backoff. */
346
+ 503: {
347
+ headers: {
348
+ [name: string]: unknown;
349
+ };
350
+ content: {
351
+ "application/json": components["schemas"]["StreamAuthenticationError"];
352
+ };
353
+ };
354
+ };
355
+ };
356
+ put?: never;
357
+ post?: never;
358
+ delete?: never;
359
+ options?: never;
360
+ head?: never;
361
+ patch?: never;
362
+ trace?: never;
363
+ };
132
364
  "/api/jobs/{jobId}/scans/mobile-upload": {
133
365
  parameters: {
134
366
  query?: never;
@@ -3832,70 +4064,382 @@ export interface paths {
3832
4064
  patch?: never;
3833
4065
  trace?: never;
3834
4066
  };
3835
- }
3836
- export type webhooks = Record<string, never>;
3837
- export interface components {
3838
- schemas: {
3839
- /** @description Structured error response returned by every endpoint on failure. */
3840
- ErrorEnvelope: {
3841
- /** @example validation_failed */
3842
- error: string;
3843
- /** @example roomPlanJSON is required */
3844
- message: string;
3845
- details?: unknown;
3846
- };
3847
- /** @description Returned with HTTP 426 when the X-Client-Version major is below minClientVersion. */
3848
- UpgradeRequiredEnvelope: {
3849
- /** @enum {string} */
3850
- error: "upgrade_required";
3851
- message: string;
3852
- apiVersion: string;
3853
- minClientVersion: string;
3854
- deprecatedBelow: string;
3855
- clientVersion: string;
3856
- };
3857
- /** @description Cross-platform version handshake manifest. See docs/api-versioning.md. */
3858
- VersionManifest: {
3859
- /** @example 1.2.434 */
3860
- apiVersion: string;
3861
- /** @example 1.0.0 */
3862
- minClientVersion: string;
3863
- /** @example 1.0.0 */
3864
- deprecatedBelow: string;
3865
- /** @description Legacy alias for apiVersion. */
3866
- version: string;
3867
- buildTime: string;
3868
- env?: string | null;
3869
- gitCommit: string;
4067
+ "/api/projects/{projectId}/documents/draft-from-walkthrough": {
4068
+ parameters: {
4069
+ query?: never;
4070
+ header?: never;
4071
+ path?: never;
4072
+ cookie?: never;
3870
4073
  };
3871
- InsertContact: {
3872
- userId?: string | null;
3873
- organizationId?: string | null;
3874
- customerNumber?: number | null;
3875
- name: string;
3876
- email?: string | null;
3877
- phone?: string | null;
3878
- company?: string | null;
3879
- address?: string | null;
3880
- status?: string | null;
3881
- customFields?: string | number | boolean | null | {
3882
- [key: string]: unknown;
3883
- } | unknown[];
3884
- /** Format: date-time */
3885
- lastContactDate?: string | null;
3886
- parentContactId?: number | null;
3887
- relationship?: string | null;
3888
- role?: string | null;
3889
- firstName?: string | null;
3890
- lastName?: string | null;
3891
- serviceAddress?: string | null;
3892
- billingAddress?: string | null;
3893
- isCommercial?: boolean | null;
3894
- pointOfContactName?: string | null;
3895
- pointOfContactTitle?: string | null;
3896
- pointOfContactPhone?: string | null;
3897
- primaryEmail?: string | null;
3898
- propertyAddress?: string | null;
4074
+ get?: never;
4075
+ put?: never;
4076
+ /**
4077
+ * Turn a voice walk-through (timed transcript + photos) into a checklist draft.
4078
+ * @description Returns a DRAFT only; nothing is saved to the job. The phone's review screen creates the checklist with POST /api/projects/{projectId}/documents (custom `items`, carrying `referenceMedia`). Sections come from, in order: the camera pose of a scan, the room the tech named (the item's words, the photo's room chip, a section opened), the AI Image Sort's room for the item's photo (add-on), then the last room mentioned; items with no signal go to Not sure. GPS is never used. Item types come from spoken hints only (checkbox unless "photo required", "yes or no" or a reading; "required" sets the flag). Reference photos are the shots taken from 10 s before a sentence to 20 s after it. 200 when the draft is ready at once; 202 with `runId` while the photos go through an AI vision sort (poll the runs route). Requires the job (404 otherwise) and the Create Checklists permission (403). Photos that are not the organization's assets are left out.
4079
+ */
4080
+ post: {
4081
+ parameters: {
4082
+ query?: never;
4083
+ header?: never;
4084
+ path: {
4085
+ projectId: number;
4086
+ };
4087
+ cookie?: never;
4088
+ };
4089
+ requestBody: {
4090
+ content: {
4091
+ "application/json": components["schemas"]["WalkthroughDraftRequest"];
4092
+ };
4093
+ };
4094
+ responses: {
4095
+ /** @description The draft (status completed). */
4096
+ 200: {
4097
+ headers: {
4098
+ [name: string]: unknown;
4099
+ };
4100
+ content: {
4101
+ "application/json": components["schemas"]["WalkthroughDraftResponse"];
4102
+ };
4103
+ };
4104
+ /** @description A vision sort runs first (status running); poll GET …/draft-from-walkthrough/runs/{runId}. */
4105
+ 202: {
4106
+ headers: {
4107
+ [name: string]: unknown;
4108
+ };
4109
+ content: {
4110
+ "application/json": components["schemas"]["WalkthroughDraftResponse"];
4111
+ };
4112
+ };
4113
+ /** @description No transcript, or a wrong shape. */
4114
+ 400: {
4115
+ headers: {
4116
+ [name: string]: unknown;
4117
+ };
4118
+ content: {
4119
+ "application/json": components["schemas"]["ErrorEnvelope"];
4120
+ };
4121
+ };
4122
+ /** @description Authentication required. */
4123
+ 401: {
4124
+ headers: {
4125
+ [name: string]: unknown;
4126
+ };
4127
+ content?: never;
4128
+ };
4129
+ /** @description The role cannot create checklists. */
4130
+ 403: {
4131
+ headers: {
4132
+ [name: string]: unknown;
4133
+ };
4134
+ content: {
4135
+ "application/json": components["schemas"]["ErrorEnvelope"];
4136
+ };
4137
+ };
4138
+ /** @description Job not found. */
4139
+ 404: {
4140
+ headers: {
4141
+ [name: string]: unknown;
4142
+ };
4143
+ content: {
4144
+ "application/json": components["schemas"]["ErrorEnvelope"];
4145
+ };
4146
+ };
4147
+ /** @description The AI's answer could not be used. */
4148
+ 502: {
4149
+ headers: {
4150
+ [name: string]: unknown;
4151
+ };
4152
+ content: {
4153
+ "application/json": components["schemas"]["ErrorEnvelope"];
4154
+ };
4155
+ };
4156
+ /** @description AI is not configured. */
4157
+ 503: {
4158
+ headers: {
4159
+ [name: string]: unknown;
4160
+ };
4161
+ content: {
4162
+ "application/json": components["schemas"]["ErrorEnvelope"];
4163
+ };
4164
+ };
4165
+ };
4166
+ };
4167
+ delete?: never;
4168
+ options?: never;
4169
+ head?: never;
4170
+ patch?: never;
4171
+ trace?: never;
4172
+ };
4173
+ "/api/projects/{projectId}/documents/draft-from-walkthrough/runs/{runId}": {
4174
+ parameters: {
4175
+ query?: never;
4176
+ header?: never;
4177
+ path?: never;
4178
+ cookie?: never;
4179
+ };
4180
+ /**
4181
+ * Poll a walk-through draft that waits for an AI vision sort.
4182
+ * @description Status `running` (with the sort's progress in `sortRun`) until the draft is ready, then `completed` with `draft`, or `failed` with `message`. A run that stops making progress is marked failed on the next poll and never re-run.
4183
+ */
4184
+ get: {
4185
+ parameters: {
4186
+ query?: never;
4187
+ header?: never;
4188
+ path: {
4189
+ projectId: number;
4190
+ runId: number;
4191
+ };
4192
+ cookie?: never;
4193
+ };
4194
+ requestBody?: never;
4195
+ responses: {
4196
+ /** @description The run's envelope. */
4197
+ 200: {
4198
+ headers: {
4199
+ [name: string]: unknown;
4200
+ };
4201
+ content: {
4202
+ "application/json": components["schemas"]["WalkthroughDraftResponse"];
4203
+ };
4204
+ };
4205
+ /** @description Authentication required. */
4206
+ 401: {
4207
+ headers: {
4208
+ [name: string]: unknown;
4209
+ };
4210
+ content?: never;
4211
+ };
4212
+ /** @description The role cannot create checklists. */
4213
+ 403: {
4214
+ headers: {
4215
+ [name: string]: unknown;
4216
+ };
4217
+ content: {
4218
+ "application/json": components["schemas"]["ErrorEnvelope"];
4219
+ };
4220
+ };
4221
+ /** @description Job or run not found. */
4222
+ 404: {
4223
+ headers: {
4224
+ [name: string]: unknown;
4225
+ };
4226
+ content: {
4227
+ "application/json": components["schemas"]["ErrorEnvelope"];
4228
+ };
4229
+ };
4230
+ };
4231
+ };
4232
+ put?: never;
4233
+ post?: never;
4234
+ delete?: never;
4235
+ options?: never;
4236
+ head?: never;
4237
+ patch?: never;
4238
+ trace?: never;
4239
+ };
4240
+ "/api/assets/init-upload": {
4241
+ parameters: {
4242
+ query?: never;
4243
+ header?: never;
4244
+ path?: never;
4245
+ cookie?: never;
4246
+ };
4247
+ get?: never;
4248
+ put?: never;
4249
+ /** Open a direct-to-S3 upload: presigned PUT for the original, and for a video's optional poster frame. */
4250
+ post: {
4251
+ parameters: {
4252
+ query?: never;
4253
+ header?: {
4254
+ /** @description Semver of the calling app build. Drives the 426 / soft-upgrade handshake. */
4255
+ "X-Client-Version"?: string;
4256
+ };
4257
+ path?: never;
4258
+ cookie?: never;
4259
+ };
4260
+ requestBody: {
4261
+ content: {
4262
+ "application/json": components["schemas"]["AssetInitUploadRequest"];
4263
+ };
4264
+ };
4265
+ responses: {
4266
+ /** @description Presigned URL(s) and the asset id to pass to complete-upload. */
4267
+ 200: {
4268
+ headers: {
4269
+ [name: string]: unknown;
4270
+ };
4271
+ content: {
4272
+ "application/json": components["schemas"]["AssetInitUploadResponse"];
4273
+ };
4274
+ };
4275
+ /** @description Missing filename/mimeType, or a `poster` on a non-video upload (`poster_requires_video`). */
4276
+ 400: {
4277
+ headers: {
4278
+ [name: string]: unknown;
4279
+ };
4280
+ content: {
4281
+ "application/json": components["schemas"]["ErrorEnvelope"];
4282
+ };
4283
+ };
4284
+ /** @description Authentication required. */
4285
+ 401: {
4286
+ headers: {
4287
+ [name: string]: unknown;
4288
+ };
4289
+ content?: never;
4290
+ };
4291
+ /** @description File larger than the single-PUT limit. */
4292
+ 413: {
4293
+ headers: {
4294
+ [name: string]: unknown;
4295
+ };
4296
+ content?: never;
4297
+ };
4298
+ };
4299
+ };
4300
+ delete?: never;
4301
+ options?: never;
4302
+ head?: never;
4303
+ patch?: never;
4304
+ trace?: never;
4305
+ };
4306
+ "/api/assets/complete-upload": {
4307
+ parameters: {
4308
+ query?: never;
4309
+ header?: never;
4310
+ path?: never;
4311
+ cookie?: never;
4312
+ };
4313
+ get?: never;
4314
+ put?: never;
4315
+ /** Mark a direct upload complete (idempotent); link it to a job/contact; dispatch processing. */
4316
+ post: {
4317
+ parameters: {
4318
+ query?: never;
4319
+ header?: {
4320
+ /** @description Semver of the calling app build. Drives the 426 / soft-upgrade handshake. */
4321
+ "X-Client-Version"?: string;
4322
+ };
4323
+ path?: never;
4324
+ cookie?: never;
4325
+ };
4326
+ requestBody: {
4327
+ content: {
4328
+ "application/json": components["schemas"]["AssetCompleteUploadRequest"];
4329
+ };
4330
+ };
4331
+ responses: {
4332
+ /** @description Finalized (or already was). */
4333
+ 200: {
4334
+ headers: {
4335
+ [name: string]: unknown;
4336
+ };
4337
+ content: {
4338
+ "application/json": components["schemas"]["AssetCompleteUploadResponse"];
4339
+ };
4340
+ };
4341
+ /** @description Neither assetId nor clientQueueId. */
4342
+ 400: {
4343
+ headers: {
4344
+ [name: string]: unknown;
4345
+ };
4346
+ content: {
4347
+ "application/json": components["schemas"]["ErrorEnvelope"];
4348
+ };
4349
+ };
4350
+ /** @description Authentication required. */
4351
+ 401: {
4352
+ headers: {
4353
+ [name: string]: unknown;
4354
+ };
4355
+ content?: never;
4356
+ };
4357
+ /** @description Attaching to a job/contact without the Upload Files permission. */
4358
+ 403: {
4359
+ headers: {
4360
+ [name: string]: unknown;
4361
+ };
4362
+ content?: never;
4363
+ };
4364
+ /** @description Asset, job or contact not found in the organization. */
4365
+ 404: {
4366
+ headers: {
4367
+ [name: string]: unknown;
4368
+ };
4369
+ content?: never;
4370
+ };
4371
+ };
4372
+ };
4373
+ delete?: never;
4374
+ options?: never;
4375
+ head?: never;
4376
+ patch?: never;
4377
+ trace?: never;
4378
+ };
4379
+ }
4380
+ export type webhooks = Record<string, never>;
4381
+ export interface components {
4382
+ schemas: {
4383
+ /** @description Structured error response returned by every endpoint on failure. */
4384
+ ErrorEnvelope: {
4385
+ /** @example validation_failed */
4386
+ error: string;
4387
+ /** @example roomPlanJSON is required */
4388
+ message: string;
4389
+ details?: unknown;
4390
+ };
4391
+ /** @description Returned with HTTP 426 when the X-Client-Version major is below minClientVersion. */
4392
+ UpgradeRequiredEnvelope: {
4393
+ /** @enum {string} */
4394
+ error: "upgrade_required";
4395
+ message: string;
4396
+ apiVersion: string;
4397
+ minClientVersion: string;
4398
+ deprecatedBelow: string;
4399
+ clientVersion: string;
4400
+ };
4401
+ /** @description Cross-platform version handshake manifest. See docs/api-versioning.md. */
4402
+ VersionManifest: {
4403
+ /** @example 1.6.2 */
4404
+ apiVersion: string;
4405
+ /** @example 1.0.0 */
4406
+ minClientVersion: string;
4407
+ /** @example 1.0.0 */
4408
+ deprecatedBelow: string;
4409
+ /** @description Legacy alias for apiVersion. */
4410
+ version: string;
4411
+ buildTime: string;
4412
+ env?: string | null;
4413
+ gitCommit: string;
4414
+ };
4415
+ InsertContact: {
4416
+ userId?: string | null;
4417
+ organizationId?: string | null;
4418
+ customerNumber?: number | null;
4419
+ name: string;
4420
+ email?: string | null;
4421
+ phone?: string | null;
4422
+ company?: string | null;
4423
+ address?: string | null;
4424
+ status?: string | null;
4425
+ customFields?: string | number | boolean | null | {
4426
+ [key: string]: unknown;
4427
+ } | unknown[];
4428
+ /** Format: date-time */
4429
+ lastContactDate?: string | null;
4430
+ parentContactId?: number | null;
4431
+ relationship?: string | null;
4432
+ role?: string | null;
4433
+ firstName?: string | null;
4434
+ lastName?: string | null;
4435
+ serviceAddress?: string | null;
4436
+ billingAddress?: string | null;
4437
+ isCommercial?: boolean | null;
4438
+ pointOfContactName?: string | null;
4439
+ pointOfContactTitle?: string | null;
4440
+ pointOfContactPhone?: string | null;
4441
+ primaryEmail?: string | null;
4442
+ propertyAddress?: string | null;
3899
4443
  leadSource?: string | null;
3900
4444
  leadSourceReferralId?: number | null;
3901
4445
  leadSourceReferralUserId?: string | null;
@@ -4376,6 +4920,14 @@ export interface components {
4376
4920
  scanRoomSnapshots: boolean;
4377
4921
  roomConnections: boolean;
4378
4922
  };
4923
+ EventStreamTicketResponse: {
4924
+ ticket: string;
4925
+ };
4926
+ StreamAuthenticationError: {
4927
+ message: string;
4928
+ /** @enum {string} */
4929
+ code?: "IMPERSONATION_UNAVAILABLE" | "SUPPORT_IMPERSONATION_UNAVAILABLE" | "auth_unavailable";
4930
+ };
4379
4931
  JobSummary: {
4380
4932
  id: number;
4381
4933
  name: string;
@@ -5029,6 +5581,354 @@ export interface components {
5029
5581
  token: string;
5030
5582
  roomIds: number[];
5031
5583
  };
5584
+ WalkthroughDraftRequest: {
5585
+ transcript: {
5586
+ text: string;
5587
+ /** Format: date-time */
5588
+ startedAt: string;
5589
+ /** Format: date-time */
5590
+ endedAt: string;
5591
+ }[];
5592
+ photos?: {
5593
+ assetId: string;
5594
+ /** Format: date-time */
5595
+ capturedAt: string;
5596
+ roomHint?: string | null;
5597
+ sketchRoomId?: number | null;
5598
+ capturePose?: {
5599
+ x?: number;
5600
+ y?: number;
5601
+ z?: number;
5602
+ floorId?: number | null;
5603
+ sketchId?: number | null;
5604
+ scanSessionId?: string;
5605
+ scanRoomLocalId?: string;
5606
+ scanRoomName?: string;
5607
+ } | null;
5608
+ }[];
5609
+ sections?: {
5610
+ name: string;
5611
+ /** Format: date-time */
5612
+ startedAt: string;
5613
+ sketchRoomId?: number | null;
5614
+ }[];
5615
+ /** @enum {string} */
5616
+ roomsFrom?: "speech" | "scan";
5617
+ };
5618
+ ChecklistDraft: {
5619
+ name: string;
5620
+ sections: {
5621
+ key: string;
5622
+ title: string;
5623
+ sketchRoomId: number | null;
5624
+ /** @enum {string} */
5625
+ kind: "room" | "custom" | "not_sure";
5626
+ items: {
5627
+ key: string;
5628
+ itemText: string;
5629
+ description: string | null;
5630
+ /** @enum {string} */
5631
+ itemType: "checkbox" | "yes/no" | "text" | "number" | "date" | "dropdown" | "multi-select" | "photo" | "signature";
5632
+ required: boolean;
5633
+ options: {
5634
+ [key: string]: unknown;
5635
+ } | null;
5636
+ referenceMedia: {
5637
+ assetId: string;
5638
+ caption?: string | null;
5639
+ order?: number;
5640
+ }[];
5641
+ hints: ("photo_required" | "yes_no" | "required" | "reading")[];
5642
+ /** @enum {string} */
5643
+ roomSource: "pose" | "named" | "vision" | "time" | "none";
5644
+ spokenAt: string;
5645
+ quote: string | null;
5646
+ }[];
5647
+ }[];
5648
+ photos: {
5649
+ assetId: string;
5650
+ capturedAt: string;
5651
+ sectionKey: string | null;
5652
+ /** @enum {string} */
5653
+ roomSource: "pose" | "named" | "vision" | "time" | "none";
5654
+ itemKeys: string[];
5655
+ }[];
5656
+ visionUsed: boolean;
5657
+ model: string | null;
5658
+ promptVersion: string;
5659
+ };
5660
+ WalkthroughDraftResponse: {
5661
+ /** @enum {string} */
5662
+ status: "completed" | "running" | "failed";
5663
+ runId: number | null;
5664
+ draft: {
5665
+ name: string;
5666
+ sections: {
5667
+ key: string;
5668
+ title: string;
5669
+ sketchRoomId: number | null;
5670
+ /** @enum {string} */
5671
+ kind: "room" | "custom" | "not_sure";
5672
+ items: {
5673
+ key: string;
5674
+ itemText: string;
5675
+ description: string | null;
5676
+ /** @enum {string} */
5677
+ itemType: "checkbox" | "yes/no" | "text" | "number" | "date" | "dropdown" | "multi-select" | "photo" | "signature";
5678
+ required: boolean;
5679
+ options: {
5680
+ [key: string]: unknown;
5681
+ } | null;
5682
+ referenceMedia: {
5683
+ assetId: string;
5684
+ caption?: string | null;
5685
+ order?: number;
5686
+ }[];
5687
+ hints: ("photo_required" | "yes_no" | "required" | "reading")[];
5688
+ /** @enum {string} */
5689
+ roomSource: "pose" | "named" | "vision" | "time" | "none";
5690
+ spokenAt: string;
5691
+ quote: string | null;
5692
+ }[];
5693
+ }[];
5694
+ photos: {
5695
+ assetId: string;
5696
+ capturedAt: string;
5697
+ sectionKey: string | null;
5698
+ /** @enum {string} */
5699
+ roomSource: "pose" | "named" | "vision" | "time" | "none";
5700
+ itemKeys: string[];
5701
+ }[];
5702
+ visionUsed: boolean;
5703
+ model: string | null;
5704
+ promptVersion: string;
5705
+ } | null;
5706
+ sortRun: {
5707
+ /** @enum {string} */
5708
+ status: "running" | "completed" | "failed";
5709
+ total: number;
5710
+ done: number;
5711
+ } | null;
5712
+ message: string | null;
5713
+ };
5714
+ /** @description `arguments` of the Chatty tool `list_job_checklists` (POST /api/chatty-voice/tools/execute). */
5715
+ ChattyListJobChecklistsArguments: {
5716
+ jobId?: number | string;
5717
+ };
5718
+ /** @description `data` of a successful `list_job_checklists` call (`success: true`). */
5719
+ ChattyListJobChecklistsData: {
5720
+ id: number;
5721
+ name: string;
5722
+ status: string | null;
5723
+ completionPercentage: number;
5724
+ templateId: number | null;
5725
+ }[];
5726
+ /** @description `arguments` of the Chatty tool `get_checklist` (POST /api/chatty-voice/tools/execute). */
5727
+ ChattyGetChecklistArguments: {
5728
+ checklistId?: number | string;
5729
+ checklistName?: string;
5730
+ jobId?: number | string;
5731
+ };
5732
+ /** @description `data` of a successful `get_checklist` call (`success: true`). */
5733
+ ChattyGetChecklistData: {
5734
+ id: number;
5735
+ name: string;
5736
+ status: string | null;
5737
+ completionPercentage: number;
5738
+ jobId: number | null;
5739
+ items: {
5740
+ id: number;
5741
+ itemText: string;
5742
+ itemType: string;
5743
+ required: boolean;
5744
+ done: boolean;
5745
+ value: string | null;
5746
+ section: string | null;
5747
+ referencePhotos: number;
5748
+ }[];
5749
+ };
5750
+ /** @description `arguments` of the Chatty tool `create_checklist` (POST /api/chatty-voice/tools/execute). */
5751
+ ChattyCreateChecklistArguments: {
5752
+ jobId?: number | string;
5753
+ name?: string;
5754
+ templateId?: number | string;
5755
+ templateName?: string;
5756
+ notes?: string;
5757
+ items?: string[];
5758
+ };
5759
+ /** @description `data` of a successful `create_checklist` call (`success: true`). */
5760
+ ChattyCreateChecklistData: {
5761
+ id: number;
5762
+ name: string;
5763
+ jobId: number;
5764
+ itemCount: number;
5765
+ templateId?: number;
5766
+ sections?: {
5767
+ title: string;
5768
+ items: {
5769
+ itemText: string;
5770
+ /** @enum {string} */
5771
+ itemType: "checkbox" | "yes/no" | "text" | "number" | "date" | "dropdown" | "multi-select" | "photo" | "signature";
5772
+ required: boolean;
5773
+ }[];
5774
+ }[];
5775
+ };
5776
+ /** @description `arguments` of the Chatty tool `add_checklist_item` (POST /api/chatty-voice/tools/execute). */
5777
+ ChattyAddChecklistItemArguments: {
5778
+ checklistId?: number | string;
5779
+ checklistName?: string;
5780
+ jobId?: number | string;
5781
+ itemText: string;
5782
+ /** @enum {string} */
5783
+ itemType?: "checkbox" | "yes/no" | "text" | "number" | "date" | "dropdown" | "multi-select" | "photo" | "signature";
5784
+ required?: boolean;
5785
+ description?: string;
5786
+ sectionName?: string;
5787
+ };
5788
+ /** @description `data` of a successful `add_checklist_item` call (`success: true`). */
5789
+ ChattyAddChecklistItemData: {
5790
+ id: number;
5791
+ checklistId: number;
5792
+ itemText: string;
5793
+ /** @enum {string} */
5794
+ itemType: "checkbox" | "yes/no" | "text" | "number" | "date" | "dropdown" | "multi-select" | "photo" | "signature";
5795
+ required: boolean;
5796
+ section: string | null;
5797
+ };
5798
+ /** @description `arguments` of the Chatty tool `complete_checklist_item` (POST /api/chatty-voice/tools/execute). */
5799
+ ChattyCompleteChecklistItemArguments: {
5800
+ checklistId?: number | string;
5801
+ checklistName?: string;
5802
+ jobId?: number | string;
5803
+ itemId?: number | string;
5804
+ itemText?: string;
5805
+ completed?: boolean;
5806
+ };
5807
+ /** @description `data` of a successful `complete_checklist_item` call (`success: true`). */
5808
+ ChattyCompleteChecklistItemData: {
5809
+ checklistId: number;
5810
+ itemId: number;
5811
+ completed: boolean;
5812
+ };
5813
+ /** @description `arguments` of the Chatty tool `set_checklist_item_answer` (POST /api/chatty-voice/tools/execute). */
5814
+ ChattySetChecklistItemAnswerArguments: {
5815
+ checklistId?: number | string;
5816
+ checklistName?: string;
5817
+ jobId?: number | string;
5818
+ itemId?: number | string;
5819
+ itemText?: string;
5820
+ value: string;
5821
+ };
5822
+ /** @description `data` of a successful `set_checklist_item_answer` call (`success: true`). */
5823
+ ChattySetChecklistItemAnswerData: {
5824
+ checklistId: number;
5825
+ itemId: number;
5826
+ value: string;
5827
+ };
5828
+ /** @description `arguments` of the Chatty tool `attach_reference_photo_to_item` (POST /api/chatty-voice/tools/execute). */
5829
+ ChattyAttachReferencePhotoToItemArguments: {
5830
+ checklistId?: number | string;
5831
+ checklistName?: string;
5832
+ jobId?: number | string;
5833
+ itemId?: number | string;
5834
+ itemText?: string;
5835
+ photoId: number | string;
5836
+ caption?: string;
5837
+ };
5838
+ /** @description `data` of a successful `attach_reference_photo_to_item` call (`success: true`). */
5839
+ ChattyAttachReferencePhotoToItemData: {
5840
+ checklistId: number;
5841
+ itemId: number;
5842
+ referenceMedia: {
5843
+ assetId: string;
5844
+ caption?: string | null;
5845
+ order?: number;
5846
+ }[];
5847
+ };
5848
+ /** @description `arguments` of the Chatty tool `draft_checklist_from_job_photos` (POST /api/chatty-voice/tools/execute). */
5849
+ ChattyDraftChecklistFromJobPhotosArguments: {
5850
+ jobId?: number | string;
5851
+ name?: string;
5852
+ create?: boolean;
5853
+ };
5854
+ /** @description `data` of a successful `draft_checklist_from_job_photos` call (`success: true`). */
5855
+ ChattyDraftChecklistFromJobPhotosData: {
5856
+ id?: number;
5857
+ jobId?: number;
5858
+ name: string;
5859
+ items: {
5860
+ itemText: string;
5861
+ photos: number;
5862
+ }[];
5863
+ unsortedPhotos: number;
5864
+ created: boolean;
5865
+ };
5866
+ /** @description POST /api/assets/init-upload body. `filename` and `mimeType` (alias `contentType`) are required by the handler. `poster` is accepted only when the upload's content type is `video/*`: a JPEG frame of at most 2 MiB the client renders locally and PUTs to `posterUploadUrl`; on any other content type the response is 400 `poster_requires_video`. */
5867
+ AssetInitUploadRequest: {
5868
+ filename?: string | number | null;
5869
+ byteSize?: number | string | null;
5870
+ clientQueueId?: string | number | null;
5871
+ pendingMetadata?: {
5872
+ [key: string]: unknown;
5873
+ } | null;
5874
+ mimeType?: string | number | null;
5875
+ contentType?: string | number | null;
5876
+ poster?: {
5877
+ /** @enum {string} */
5878
+ contentType: "image/jpeg";
5879
+ byteSize: number;
5880
+ } | null;
5881
+ };
5882
+ AssetInitUploadResponse: {
5883
+ assetId: string;
5884
+ /** @description Storage key of the original (`org/<orgId>/assets/<assetId>/original`). */
5885
+ key: string;
5886
+ /** @description Presigned PUT for the original. Absent when `alreadyCompleted` is true. */
5887
+ putUrl?: string;
5888
+ headersToSend?: {
5889
+ [key: string]: string;
5890
+ };
5891
+ /** @description ISO instant; also the expiry of `posterUploadUrl`. */
5892
+ putUrlExpiresAt?: string;
5893
+ reused?: boolean;
5894
+ alreadyCompleted?: boolean;
5895
+ /** @description Presigned PUT (Content-Type: image/jpeg) for the poster frame. Present only when `poster` was sent. */
5896
+ posterUploadUrl?: string;
5897
+ /** @description The poster's storage key: the asset prefix with `/original` replaced by `/thumb_320`. */
5898
+ posterKey?: string;
5899
+ };
5900
+ /** @description POST /api/assets/complete-upload body. `assetId` or `clientQueueId` is required. `posterUploaded: true` (video uploads only) asks the server to verify the poster frame PUT to `posterUploadUrl` and use it as the thumbnail at once; a missing, oversized or non-JPEG poster never fails the upload — it completes without it. */
5901
+ AssetCompleteUploadRequest: {
5902
+ assetId?: string | number | null;
5903
+ clientQueueId?: string | number | null;
5904
+ gpsLatitude?: number | string | null;
5905
+ gpsLongitude?: number | string | null;
5906
+ gpsAddress?: string | number | null;
5907
+ captureTimestamp?: string | number | null;
5908
+ deviceInfo?: string | number | null;
5909
+ overlayApplied?: boolean | string | number | null;
5910
+ hasMarkup?: boolean | string | number | null;
5911
+ tags?: unknown[] | null;
5912
+ projectId?: number | string | null;
5913
+ contactId?: number | string | null;
5914
+ folderId?: string | number | null;
5915
+ description?: string | number | null;
5916
+ serverOverlay?: {
5917
+ [key: string]: unknown;
5918
+ } | null;
5919
+ capturePose?: {
5920
+ [key: string]: unknown;
5921
+ } | null;
5922
+ posterUploaded?: boolean | string | number | null;
5923
+ };
5924
+ AssetCompleteUploadResponse: {
5925
+ /** @enum {boolean} */
5926
+ ok: true;
5927
+ assetId: string;
5928
+ alreadyCompleted: boolean;
5929
+ /** @description Human-readable log of what finalize did (status change, links, pipeline dispatch, `thumbnail: client poster accepted (thumb_320)`). */
5930
+ actions: string[];
5931
+ };
5032
5932
  };
5033
5933
  responses: never;
5034
5934
  parameters: never;