@serviceai/api-spec 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/types.d.ts ADDED
@@ -0,0 +1,1505 @@
1
+ /**
2
+ * This file was auto-generated by openapi-typescript.
3
+ * Do not make direct changes to the file.
4
+ */
5
+
6
+ export interface paths {
7
+ "/api/version": {
8
+ parameters: {
9
+ query?: never;
10
+ header?: never;
11
+ path?: never;
12
+ cookie?: never;
13
+ };
14
+ /** Cross-platform version handshake manifest. */
15
+ get: {
16
+ parameters: {
17
+ query?: never;
18
+ header?: never;
19
+ path?: never;
20
+ cookie?: never;
21
+ };
22
+ requestBody?: never;
23
+ responses: {
24
+ /** @description Always returned. Body is the canonical handshake manifest. */
25
+ 200: {
26
+ headers: {
27
+ [name: string]: unknown;
28
+ };
29
+ content: {
30
+ "application/json": components["schemas"]["VersionManifest"];
31
+ };
32
+ };
33
+ };
34
+ };
35
+ put?: never;
36
+ post?: never;
37
+ delete?: never;
38
+ options?: never;
39
+ head?: never;
40
+ patch?: never;
41
+ trace?: never;
42
+ };
43
+ "/api/ping": {
44
+ parameters: {
45
+ query?: never;
46
+ header?: never;
47
+ path?: never;
48
+ cookie?: never;
49
+ };
50
+ /** Liveness probe. Bypasses the version handshake. */
51
+ get: {
52
+ parameters: {
53
+ query?: never;
54
+ header?: never;
55
+ path?: never;
56
+ cookie?: never;
57
+ };
58
+ requestBody?: never;
59
+ responses: {
60
+ /** @description Static OK envelope. */
61
+ 200: {
62
+ headers: {
63
+ [name: string]: unknown;
64
+ };
65
+ content: {
66
+ "application/json": {
67
+ /** @enum {string} */
68
+ status: "ok";
69
+ timestamp: string;
70
+ env: string | null;
71
+ };
72
+ };
73
+ };
74
+ };
75
+ };
76
+ put?: never;
77
+ post?: never;
78
+ delete?: never;
79
+ options?: never;
80
+ head?: never;
81
+ patch?: never;
82
+ trace?: never;
83
+ };
84
+ "/api/me/features": {
85
+ parameters: {
86
+ query?: never;
87
+ header?: never;
88
+ path?: never;
89
+ cookie?: never;
90
+ };
91
+ /** Capability discovery — iOS calls on launch to gate UI affordances. */
92
+ get: {
93
+ parameters: {
94
+ query?: never;
95
+ header?: {
96
+ /** @description Semver of the calling app build. Drives the 426 / soft-upgrade handshake. */
97
+ "X-Client-Version"?: string;
98
+ };
99
+ path?: never;
100
+ cookie?: never;
101
+ };
102
+ requestBody?: never;
103
+ responses: {
104
+ /** @description Flat feature map. Unknown / missing flags must be treated as false by the client. */
105
+ 200: {
106
+ headers: {
107
+ [name: string]: unknown;
108
+ };
109
+ content: {
110
+ "application/json": components["schemas"]["FeatureFlags"];
111
+ };
112
+ };
113
+ /** @description Client major below minClientVersion. */
114
+ 426: {
115
+ headers: {
116
+ [name: string]: unknown;
117
+ };
118
+ content: {
119
+ "application/json": components["schemas"]["UpgradeRequiredEnvelope"];
120
+ };
121
+ };
122
+ };
123
+ };
124
+ put?: never;
125
+ post?: never;
126
+ delete?: never;
127
+ options?: never;
128
+ head?: never;
129
+ patch?: never;
130
+ trace?: never;
131
+ };
132
+ "/api/jobs/{jobId}/scans/mobile-upload": {
133
+ parameters: {
134
+ query?: never;
135
+ header?: never;
136
+ path?: never;
137
+ cookie?: never;
138
+ };
139
+ get?: never;
140
+ put?: never;
141
+ /** iOS LiDAR scan upload. v2 fields are additive — v1 payloads remain byte-identical. */
142
+ post: {
143
+ parameters: {
144
+ query?: never;
145
+ header?: {
146
+ /** @description Semver of the calling app build. Drives the 426 / soft-upgrade handshake. */
147
+ "X-Client-Version"?: string;
148
+ };
149
+ path: {
150
+ jobId: number;
151
+ };
152
+ cookie?: never;
153
+ };
154
+ requestBody?: {
155
+ content: {
156
+ "application/json": components["schemas"]["MobileUploadRequest"];
157
+ };
158
+ };
159
+ responses: {
160
+ /** @description Idempotent replay of a session-mode upload (same sessionId). */
161
+ 200: {
162
+ headers: {
163
+ [name: string]: unknown;
164
+ };
165
+ content: {
166
+ "application/json": components["schemas"]["MobileUploadResponse"];
167
+ };
168
+ };
169
+ /** @description Scan created (or composite child appended via parentScanId+entryDoorwayId). */
170
+ 201: {
171
+ headers: {
172
+ [name: string]: unknown;
173
+ };
174
+ content: {
175
+ "application/json": components["schemas"]["MobileUploadResponse"];
176
+ };
177
+ };
178
+ /** @description Validation failure. */
179
+ 400: {
180
+ headers: {
181
+ [name: string]: unknown;
182
+ };
183
+ content: {
184
+ "application/json": components["schemas"]["ErrorEnvelope"];
185
+ };
186
+ };
187
+ /** @description Caller not assigned to this job. */
188
+ 403: {
189
+ headers: {
190
+ [name: string]: unknown;
191
+ };
192
+ content: {
193
+ "application/json": components["schemas"]["ErrorEnvelope"];
194
+ };
195
+ };
196
+ /** @description Job not found. */
197
+ 404: {
198
+ headers: {
199
+ [name: string]: unknown;
200
+ };
201
+ content: {
202
+ "application/json": components["schemas"]["ErrorEnvelope"];
203
+ };
204
+ };
205
+ /** @description Client major below minClientVersion. */
206
+ 426: {
207
+ headers: {
208
+ [name: string]: unknown;
209
+ };
210
+ content: {
211
+ "application/json": components["schemas"]["UpgradeRequiredEnvelope"];
212
+ };
213
+ };
214
+ };
215
+ };
216
+ delete?: never;
217
+ options?: never;
218
+ head?: never;
219
+ patch?: never;
220
+ trace?: never;
221
+ };
222
+ "/api/jobs/{jobId}/floors": {
223
+ parameters: {
224
+ query?: never;
225
+ header?: never;
226
+ path?: never;
227
+ cookie?: never;
228
+ };
229
+ get?: never;
230
+ put?: never;
231
+ /** Idempotent floor mint. Lookup is case-/whitespace-insensitive on name. */
232
+ post: {
233
+ parameters: {
234
+ query?: never;
235
+ header?: {
236
+ /** @description Semver of the calling app build. Drives the 426 / soft-upgrade handshake. */
237
+ "X-Client-Version"?: string;
238
+ };
239
+ path: {
240
+ jobId: number;
241
+ };
242
+ cookie?: never;
243
+ };
244
+ requestBody?: {
245
+ content: {
246
+ "application/json": {
247
+ name: string;
248
+ level?: number;
249
+ sortOrder?: number;
250
+ notes?: string;
251
+ propertyId?: number;
252
+ };
253
+ };
254
+ };
255
+ responses: {
256
+ /** @description Existing floor matched by normalized name. */
257
+ 200: {
258
+ headers: {
259
+ [name: string]: unknown;
260
+ };
261
+ content: {
262
+ "application/json": {
263
+ /** @enum {boolean} */
264
+ created: false;
265
+ floor: {
266
+ propertyId: number;
267
+ organizationId: string;
268
+ name?: string;
269
+ level?: number;
270
+ sortOrder?: number;
271
+ notes?: string | null;
272
+ id: number;
273
+ };
274
+ };
275
+ };
276
+ };
277
+ /** @description Fresh floor inserted. */
278
+ 201: {
279
+ headers: {
280
+ [name: string]: unknown;
281
+ };
282
+ content: {
283
+ "application/json": {
284
+ /** @enum {boolean} */
285
+ created: true;
286
+ floor: {
287
+ propertyId: number;
288
+ organizationId: string;
289
+ name?: string;
290
+ level?: number;
291
+ sortOrder?: number;
292
+ notes?: string | null;
293
+ id: number;
294
+ };
295
+ };
296
+ };
297
+ };
298
+ /** @description Validation failure. */
299
+ 400: {
300
+ headers: {
301
+ [name: string]: unknown;
302
+ };
303
+ content: {
304
+ "application/json": components["schemas"]["ErrorEnvelope"];
305
+ };
306
+ };
307
+ /** @description Caller cannot reach this job. */
308
+ 403: {
309
+ headers: {
310
+ [name: string]: unknown;
311
+ };
312
+ content: {
313
+ "application/json": components["schemas"]["ErrorEnvelope"];
314
+ };
315
+ };
316
+ };
317
+ };
318
+ delete?: never;
319
+ options?: never;
320
+ head?: never;
321
+ patch?: never;
322
+ trace?: never;
323
+ };
324
+ "/api/jobs": {
325
+ parameters: {
326
+ query?: never;
327
+ header?: never;
328
+ path?: never;
329
+ cookie?: never;
330
+ };
331
+ /** List jobs (projects) visible to the caller. */
332
+ get: {
333
+ parameters: {
334
+ query?: never;
335
+ header?: {
336
+ /** @description Semver of the calling app build. Drives the 426 / soft-upgrade handshake. */
337
+ "X-Client-Version"?: string;
338
+ };
339
+ path?: never;
340
+ cookie?: never;
341
+ };
342
+ requestBody?: never;
343
+ responses: {
344
+ /** @description Array of jobs. */
345
+ 200: {
346
+ headers: {
347
+ [name: string]: unknown;
348
+ };
349
+ content: {
350
+ "application/json": components["schemas"]["JobSummary"][];
351
+ };
352
+ };
353
+ /** @description Unauthenticated. */
354
+ 401: {
355
+ headers: {
356
+ [name: string]: unknown;
357
+ };
358
+ content: {
359
+ "application/json": components["schemas"]["ErrorEnvelope"];
360
+ };
361
+ };
362
+ };
363
+ };
364
+ put?: never;
365
+ /** Create a job. */
366
+ post: {
367
+ parameters: {
368
+ query?: never;
369
+ header?: {
370
+ /** @description Semver of the calling app build. Drives the 426 / soft-upgrade handshake. */
371
+ "X-Client-Version"?: string;
372
+ };
373
+ path?: never;
374
+ cookie?: never;
375
+ };
376
+ requestBody?: {
377
+ content: {
378
+ "application/json": components["schemas"]["JobCreateRequest"];
379
+ };
380
+ };
381
+ responses: {
382
+ /** @description Job created. */
383
+ 201: {
384
+ headers: {
385
+ [name: string]: unknown;
386
+ };
387
+ content: {
388
+ "application/json": components["schemas"]["JobSummary"];
389
+ };
390
+ };
391
+ /** @description Validation failure. */
392
+ 400: {
393
+ headers: {
394
+ [name: string]: unknown;
395
+ };
396
+ content: {
397
+ "application/json": components["schemas"]["ErrorEnvelope"];
398
+ };
399
+ };
400
+ };
401
+ };
402
+ delete?: never;
403
+ options?: never;
404
+ head?: never;
405
+ patch?: never;
406
+ trace?: never;
407
+ };
408
+ "/api/jobs/{jobId}": {
409
+ parameters: {
410
+ query?: never;
411
+ header?: never;
412
+ path?: never;
413
+ cookie?: never;
414
+ };
415
+ /** Fetch a single job by id. */
416
+ get: {
417
+ parameters: {
418
+ query?: never;
419
+ header?: {
420
+ /** @description Semver of the calling app build. Drives the 426 / soft-upgrade handshake. */
421
+ "X-Client-Version"?: string;
422
+ };
423
+ path: {
424
+ jobId: number;
425
+ };
426
+ cookie?: never;
427
+ };
428
+ requestBody?: never;
429
+ responses: {
430
+ /** @description Job detail. */
431
+ 200: {
432
+ headers: {
433
+ [name: string]: unknown;
434
+ };
435
+ content: {
436
+ "application/json": components["schemas"]["JobSummary"];
437
+ };
438
+ };
439
+ /** @description Caller cannot reach this job. */
440
+ 403: {
441
+ headers: {
442
+ [name: string]: unknown;
443
+ };
444
+ content: {
445
+ "application/json": components["schemas"]["ErrorEnvelope"];
446
+ };
447
+ };
448
+ /** @description Job not found. */
449
+ 404: {
450
+ headers: {
451
+ [name: string]: unknown;
452
+ };
453
+ content: {
454
+ "application/json": components["schemas"]["ErrorEnvelope"];
455
+ };
456
+ };
457
+ };
458
+ };
459
+ put?: never;
460
+ post?: never;
461
+ delete?: never;
462
+ options?: never;
463
+ head?: never;
464
+ patch?: never;
465
+ trace?: never;
466
+ };
467
+ "/api/chatty/sessions": {
468
+ parameters: {
469
+ query?: never;
470
+ header?: never;
471
+ path?: never;
472
+ cookie?: never;
473
+ };
474
+ get?: never;
475
+ put?: never;
476
+ /** Mint an ephemeral realtime voice session token. */
477
+ post: {
478
+ parameters: {
479
+ query?: never;
480
+ header?: {
481
+ /** @description Semver of the calling app build. Drives the 426 / soft-upgrade handshake. */
482
+ "X-Client-Version"?: string;
483
+ };
484
+ path?: never;
485
+ cookie?: never;
486
+ };
487
+ requestBody?: {
488
+ content: {
489
+ "application/json": components["schemas"]["ChattySessionStartRequest"];
490
+ };
491
+ };
492
+ responses: {
493
+ /** @description Session created. Connect to websocketUrl with ephemeralToken in the Authorization header. */
494
+ 201: {
495
+ headers: {
496
+ [name: string]: unknown;
497
+ };
498
+ content: {
499
+ "application/json": components["schemas"]["ChattySessionToken"];
500
+ };
501
+ };
502
+ /** @description Validation failure. */
503
+ 400: {
504
+ headers: {
505
+ [name: string]: unknown;
506
+ };
507
+ content: {
508
+ "application/json": components["schemas"]["ErrorEnvelope"];
509
+ };
510
+ };
511
+ /** @description Unauthenticated. */
512
+ 401: {
513
+ headers: {
514
+ [name: string]: unknown;
515
+ };
516
+ content: {
517
+ "application/json": components["schemas"]["ErrorEnvelope"];
518
+ };
519
+ };
520
+ /** @description Client major below minClientVersion. */
521
+ 426: {
522
+ headers: {
523
+ [name: string]: unknown;
524
+ };
525
+ content: {
526
+ "application/json": components["schemas"]["UpgradeRequiredEnvelope"];
527
+ };
528
+ };
529
+ };
530
+ };
531
+ delete?: never;
532
+ options?: never;
533
+ head?: never;
534
+ patch?: never;
535
+ trace?: never;
536
+ };
537
+ "/api/chatty/sessions/{sessionId}/messages": {
538
+ parameters: {
539
+ query?: never;
540
+ header?: never;
541
+ path?: never;
542
+ cookie?: never;
543
+ };
544
+ /** List transcript messages for a Chatty session. */
545
+ get: {
546
+ parameters: {
547
+ query?: never;
548
+ header?: {
549
+ /** @description Semver of the calling app build. Drives the 426 / soft-upgrade handshake. */
550
+ "X-Client-Version"?: string;
551
+ };
552
+ path: {
553
+ sessionId: string;
554
+ };
555
+ cookie?: never;
556
+ };
557
+ requestBody?: never;
558
+ responses: {
559
+ /** @description Ordered transcript. */
560
+ 200: {
561
+ headers: {
562
+ [name: string]: unknown;
563
+ };
564
+ content: {
565
+ "application/json": components["schemas"]["ChattyMessage"][];
566
+ };
567
+ };
568
+ /** @description Session does not belong to caller. */
569
+ 403: {
570
+ headers: {
571
+ [name: string]: unknown;
572
+ };
573
+ content: {
574
+ "application/json": components["schemas"]["ErrorEnvelope"];
575
+ };
576
+ };
577
+ /** @description Session not found. */
578
+ 404: {
579
+ headers: {
580
+ [name: string]: unknown;
581
+ };
582
+ content: {
583
+ "application/json": components["schemas"]["ErrorEnvelope"];
584
+ };
585
+ };
586
+ };
587
+ };
588
+ put?: never;
589
+ post?: never;
590
+ delete?: never;
591
+ options?: never;
592
+ head?: never;
593
+ patch?: never;
594
+ trace?: never;
595
+ };
596
+ "/api/chatty/sessions/{sessionId}": {
597
+ parameters: {
598
+ query?: never;
599
+ header?: never;
600
+ path?: never;
601
+ cookie?: never;
602
+ };
603
+ get?: never;
604
+ put?: never;
605
+ post?: never;
606
+ /** End a Chatty session and revoke its ephemeral token. */
607
+ delete: {
608
+ parameters: {
609
+ query?: never;
610
+ header?: {
611
+ /** @description Semver of the calling app build. Drives the 426 / soft-upgrade handshake. */
612
+ "X-Client-Version"?: string;
613
+ };
614
+ path: {
615
+ sessionId: string;
616
+ };
617
+ cookie?: never;
618
+ };
619
+ requestBody?: never;
620
+ responses: {
621
+ /** @description Session terminated. */
622
+ 204: {
623
+ headers: {
624
+ [name: string]: unknown;
625
+ };
626
+ content?: never;
627
+ };
628
+ /** @description Session does not belong to caller. */
629
+ 403: {
630
+ headers: {
631
+ [name: string]: unknown;
632
+ };
633
+ content: {
634
+ "application/json": components["schemas"]["ErrorEnvelope"];
635
+ };
636
+ };
637
+ /** @description Session not found. */
638
+ 404: {
639
+ headers: {
640
+ [name: string]: unknown;
641
+ };
642
+ content: {
643
+ "application/json": components["schemas"]["ErrorEnvelope"];
644
+ };
645
+ };
646
+ };
647
+ };
648
+ options?: never;
649
+ head?: never;
650
+ patch?: never;
651
+ trace?: never;
652
+ };
653
+ "/api/me": {
654
+ parameters: {
655
+ query?: never;
656
+ header?: never;
657
+ path?: never;
658
+ cookie?: never;
659
+ };
660
+ /** Current session principal. iOS calls this immediately after /api/version on launch. */
661
+ get: {
662
+ parameters: {
663
+ query?: never;
664
+ header?: {
665
+ /** @description Semver of the calling app build. Drives the 426 / soft-upgrade handshake. */
666
+ "X-Client-Version"?: string;
667
+ };
668
+ path?: never;
669
+ cookie?: never;
670
+ };
671
+ requestBody?: never;
672
+ responses: {
673
+ /** @description Authenticated user. */
674
+ 200: {
675
+ headers: {
676
+ [name: string]: unknown;
677
+ };
678
+ content: {
679
+ "application/json": components["schemas"]["MeResponse"];
680
+ };
681
+ };
682
+ /** @description No active session. */
683
+ 401: {
684
+ headers: {
685
+ [name: string]: unknown;
686
+ };
687
+ content: {
688
+ "application/json": components["schemas"]["ErrorEnvelope"];
689
+ };
690
+ };
691
+ /** @description Client major below minClientVersion. */
692
+ 426: {
693
+ headers: {
694
+ [name: string]: unknown;
695
+ };
696
+ content: {
697
+ "application/json": components["schemas"]["UpgradeRequiredEnvelope"];
698
+ };
699
+ };
700
+ };
701
+ };
702
+ put?: never;
703
+ post?: never;
704
+ delete?: never;
705
+ options?: never;
706
+ head?: never;
707
+ patch?: never;
708
+ trace?: never;
709
+ };
710
+ "/api/contacts": {
711
+ parameters: {
712
+ query?: never;
713
+ header?: never;
714
+ path?: never;
715
+ cookie?: never;
716
+ };
717
+ /** List contacts in the caller's org. */
718
+ get: {
719
+ parameters: {
720
+ query?: never;
721
+ header?: {
722
+ /** @description Semver of the calling app build. Drives the 426 / soft-upgrade handshake. */
723
+ "X-Client-Version"?: string;
724
+ };
725
+ path?: never;
726
+ cookie?: never;
727
+ };
728
+ requestBody?: never;
729
+ responses: {
730
+ /** @description Array of contacts. */
731
+ 200: {
732
+ headers: {
733
+ [name: string]: unknown;
734
+ };
735
+ content: {
736
+ "application/json": ({
737
+ userId?: string | null;
738
+ organizationId?: string | null;
739
+ customerNumber?: number | null;
740
+ name: string;
741
+ email?: string | null;
742
+ phone?: string | null;
743
+ company?: string | null;
744
+ address?: string | null;
745
+ status?: string | null;
746
+ customFields?: string | number | boolean | null | {
747
+ [key: string]: unknown;
748
+ } | unknown[];
749
+ lastContactDate?: string | null;
750
+ parentContactId?: number | null;
751
+ relationship?: string | null;
752
+ role?: string | null;
753
+ firstName?: string | null;
754
+ lastName?: string | null;
755
+ serviceAddress?: string | null;
756
+ billingAddress?: string | null;
757
+ isCommercial?: boolean | null;
758
+ pointOfContactName?: string | null;
759
+ pointOfContactTitle?: string | null;
760
+ pointOfContactPhone?: string | null;
761
+ primaryEmail?: string | null;
762
+ propertyAddress?: string | null;
763
+ leadSource?: string | null;
764
+ leadSourceReferralId?: number | null;
765
+ leadSourceReferralUserId?: string | null;
766
+ leadSourceOther?: string | null;
767
+ googleDriveCustomerFolderId?: string | null;
768
+ cachedLat?: number | null;
769
+ cachedLng?: number | null;
770
+ qboId?: string | null;
771
+ qboSyncToken?: string | null;
772
+ qboLastPushedAt?: string | null;
773
+ qboLastPushedHash?: string | null;
774
+ qboLastError?: string | null;
775
+ deletedAt?: string | null;
776
+ deletedBy?: string | null;
777
+ } & {
778
+ id: number;
779
+ })[];
780
+ };
781
+ };
782
+ /** @description Unauthenticated. */
783
+ 401: {
784
+ headers: {
785
+ [name: string]: unknown;
786
+ };
787
+ content: {
788
+ "application/json": components["schemas"]["ErrorEnvelope"];
789
+ };
790
+ };
791
+ };
792
+ };
793
+ put?: never;
794
+ /** Create a contact. */
795
+ post: {
796
+ parameters: {
797
+ query?: never;
798
+ header?: {
799
+ /** @description Semver of the calling app build. Drives the 426 / soft-upgrade handshake. */
800
+ "X-Client-Version"?: string;
801
+ };
802
+ path?: never;
803
+ cookie?: never;
804
+ };
805
+ requestBody?: {
806
+ content: {
807
+ "application/json": {
808
+ userId?: string | null;
809
+ organizationId?: string | null;
810
+ customerNumber?: number | null;
811
+ name: string;
812
+ email?: string | null;
813
+ phone?: string | null;
814
+ company?: string | null;
815
+ address?: string | null;
816
+ status?: string | null;
817
+ customFields?: string | number | boolean | null | {
818
+ [key: string]: unknown;
819
+ } | unknown[];
820
+ lastContactDate?: string | null;
821
+ parentContactId?: number | null;
822
+ relationship?: string | null;
823
+ role?: string | null;
824
+ firstName?: string | null;
825
+ lastName?: string | null;
826
+ serviceAddress?: string | null;
827
+ billingAddress?: string | null;
828
+ isCommercial?: boolean | null;
829
+ pointOfContactName?: string | null;
830
+ pointOfContactTitle?: string | null;
831
+ pointOfContactPhone?: string | null;
832
+ primaryEmail?: string | null;
833
+ propertyAddress?: string | null;
834
+ leadSource?: string | null;
835
+ leadSourceReferralId?: number | null;
836
+ leadSourceReferralUserId?: string | null;
837
+ leadSourceOther?: string | null;
838
+ googleDriveCustomerFolderId?: string | null;
839
+ cachedLat?: number | null;
840
+ cachedLng?: number | null;
841
+ qboId?: string | null;
842
+ qboSyncToken?: string | null;
843
+ qboLastPushedAt?: string | null;
844
+ qboLastPushedHash?: string | null;
845
+ qboLastError?: string | null;
846
+ deletedAt?: string | null;
847
+ deletedBy?: string | null;
848
+ };
849
+ };
850
+ };
851
+ responses: {
852
+ /** @description Created. */
853
+ 201: {
854
+ headers: {
855
+ [name: string]: unknown;
856
+ };
857
+ content: {
858
+ "application/json": {
859
+ userId?: string | null;
860
+ organizationId?: string | null;
861
+ customerNumber?: number | null;
862
+ name: string;
863
+ email?: string | null;
864
+ phone?: string | null;
865
+ company?: string | null;
866
+ address?: string | null;
867
+ status?: string | null;
868
+ customFields?: string | number | boolean | null | {
869
+ [key: string]: unknown;
870
+ } | unknown[];
871
+ lastContactDate?: string | null;
872
+ parentContactId?: number | null;
873
+ relationship?: string | null;
874
+ role?: string | null;
875
+ firstName?: string | null;
876
+ lastName?: string | null;
877
+ serviceAddress?: string | null;
878
+ billingAddress?: string | null;
879
+ isCommercial?: boolean | null;
880
+ pointOfContactName?: string | null;
881
+ pointOfContactTitle?: string | null;
882
+ pointOfContactPhone?: string | null;
883
+ primaryEmail?: string | null;
884
+ propertyAddress?: string | null;
885
+ leadSource?: string | null;
886
+ leadSourceReferralId?: number | null;
887
+ leadSourceReferralUserId?: string | null;
888
+ leadSourceOther?: string | null;
889
+ googleDriveCustomerFolderId?: string | null;
890
+ cachedLat?: number | null;
891
+ cachedLng?: number | null;
892
+ qboId?: string | null;
893
+ qboSyncToken?: string | null;
894
+ qboLastPushedAt?: string | null;
895
+ qboLastPushedHash?: string | null;
896
+ qboLastError?: string | null;
897
+ deletedAt?: string | null;
898
+ deletedBy?: string | null;
899
+ } & {
900
+ id: number;
901
+ };
902
+ };
903
+ };
904
+ /** @description Validation failure. */
905
+ 400: {
906
+ headers: {
907
+ [name: string]: unknown;
908
+ };
909
+ content: {
910
+ "application/json": components["schemas"]["ErrorEnvelope"];
911
+ };
912
+ };
913
+ };
914
+ };
915
+ delete?: never;
916
+ options?: never;
917
+ head?: never;
918
+ patch?: never;
919
+ trace?: never;
920
+ };
921
+ "/api/jobs/{jobId}/photos": {
922
+ parameters: {
923
+ query?: never;
924
+ header?: never;
925
+ path?: never;
926
+ cookie?: never;
927
+ };
928
+ get?: never;
929
+ put?: never;
930
+ /** Upload a project photo (raw-first; server watermarks). */
931
+ post: {
932
+ parameters: {
933
+ query?: never;
934
+ header?: {
935
+ /** @description Semver of the calling app build. Drives the 426 / soft-upgrade handshake. */
936
+ "X-Client-Version"?: string;
937
+ };
938
+ path: {
939
+ jobId: number;
940
+ };
941
+ cookie?: never;
942
+ };
943
+ requestBody?: {
944
+ content: {
945
+ "multipart/form-data": {
946
+ /** Format: binary */
947
+ file: string;
948
+ };
949
+ };
950
+ };
951
+ responses: {
952
+ /** @description Photo created. */
953
+ 201: {
954
+ headers: {
955
+ [name: string]: unknown;
956
+ };
957
+ content: {
958
+ "application/json": components["schemas"]["PhotoUploadResponse"];
959
+ };
960
+ };
961
+ /** @description Validation failure. */
962
+ 400: {
963
+ headers: {
964
+ [name: string]: unknown;
965
+ };
966
+ content: {
967
+ "application/json": components["schemas"]["ErrorEnvelope"];
968
+ };
969
+ };
970
+ /** @description Caller not assigned to this job. */
971
+ 403: {
972
+ headers: {
973
+ [name: string]: unknown;
974
+ };
975
+ content: {
976
+ "application/json": components["schemas"]["ErrorEnvelope"];
977
+ };
978
+ };
979
+ };
980
+ };
981
+ delete?: never;
982
+ options?: never;
983
+ head?: never;
984
+ patch?: never;
985
+ trace?: never;
986
+ };
987
+ "/api/jobs/{jobId}/scans": {
988
+ parameters: {
989
+ query?: never;
990
+ header?: never;
991
+ path?: never;
992
+ cookie?: never;
993
+ };
994
+ /** List every scan on a job. Augments each row with floor placement echo. */
995
+ get: {
996
+ parameters: {
997
+ query?: never;
998
+ header?: {
999
+ /** @description Semver of the calling app build. Drives the 426 / soft-upgrade handshake. */
1000
+ "X-Client-Version"?: string;
1001
+ };
1002
+ path: {
1003
+ jobId: number;
1004
+ };
1005
+ cookie?: never;
1006
+ };
1007
+ requestBody?: never;
1008
+ responses: {
1009
+ /** @description Sorted by COALESCE(captureTimestamp, createdAt) DESC. */
1010
+ 200: {
1011
+ headers: {
1012
+ [name: string]: unknown;
1013
+ };
1014
+ content: {
1015
+ "application/json": {
1016
+ [key: string]: unknown;
1017
+ }[];
1018
+ };
1019
+ };
1020
+ };
1021
+ };
1022
+ put?: never;
1023
+ post?: never;
1024
+ delete?: never;
1025
+ options?: never;
1026
+ head?: never;
1027
+ patch?: never;
1028
+ trace?: never;
1029
+ };
1030
+ }
1031
+ export type webhooks = Record<string, never>;
1032
+ export interface components {
1033
+ schemas: {
1034
+ /** @description Structured error response returned by every endpoint on failure. */
1035
+ ErrorEnvelope: {
1036
+ /** @example validation_failed */
1037
+ error: string;
1038
+ /** @example roomPlanJSON is required */
1039
+ message: string;
1040
+ details?: unknown;
1041
+ };
1042
+ /** @description Returned with HTTP 426 when the X-Client-Version major is below minClientVersion. */
1043
+ UpgradeRequiredEnvelope: {
1044
+ /** @enum {string} */
1045
+ error: "upgrade_required";
1046
+ message: string;
1047
+ apiVersion: string;
1048
+ minClientVersion: string;
1049
+ deprecatedBelow: string;
1050
+ clientVersion: string;
1051
+ };
1052
+ /** @description Cross-platform version handshake manifest. See docs/api-versioning.md. */
1053
+ VersionManifest: {
1054
+ /** @example 1.0.7 */
1055
+ apiVersion: string;
1056
+ /** @example 1.0.0 */
1057
+ minClientVersion: string;
1058
+ /** @example 1.0.0 */
1059
+ deprecatedBelow: string;
1060
+ /** @description Legacy alias for apiVersion. */
1061
+ version: string;
1062
+ buildTime: string;
1063
+ env?: string | null;
1064
+ gitCommit: string;
1065
+ };
1066
+ InsertContact: {
1067
+ userId?: string | null;
1068
+ organizationId?: string | null;
1069
+ customerNumber?: number | null;
1070
+ name: string;
1071
+ email?: string | null;
1072
+ phone?: string | null;
1073
+ company?: string | null;
1074
+ address?: string | null;
1075
+ status?: string | null;
1076
+ customFields?: string | number | boolean | null | {
1077
+ [key: string]: unknown;
1078
+ } | unknown[];
1079
+ lastContactDate?: string | null;
1080
+ parentContactId?: number | null;
1081
+ relationship?: string | null;
1082
+ role?: string | null;
1083
+ firstName?: string | null;
1084
+ lastName?: string | null;
1085
+ serviceAddress?: string | null;
1086
+ billingAddress?: string | null;
1087
+ isCommercial?: boolean | null;
1088
+ pointOfContactName?: string | null;
1089
+ pointOfContactTitle?: string | null;
1090
+ pointOfContactPhone?: string | null;
1091
+ primaryEmail?: string | null;
1092
+ propertyAddress?: string | null;
1093
+ leadSource?: string | null;
1094
+ leadSourceReferralId?: number | null;
1095
+ leadSourceReferralUserId?: string | null;
1096
+ leadSourceOther?: string | null;
1097
+ googleDriveCustomerFolderId?: string | null;
1098
+ cachedLat?: number | null;
1099
+ cachedLng?: number | null;
1100
+ qboId?: string | null;
1101
+ qboSyncToken?: string | null;
1102
+ qboLastPushedAt?: string | null;
1103
+ qboLastPushedHash?: string | null;
1104
+ qboLastError?: string | null;
1105
+ deletedAt?: string | null;
1106
+ deletedBy?: string | null;
1107
+ };
1108
+ InsertProperty: {
1109
+ organizationId: string;
1110
+ jobId?: number | null;
1111
+ name: string;
1112
+ address1?: string | null;
1113
+ address2?: string | null;
1114
+ city?: string | null;
1115
+ state?: string | null;
1116
+ postalCode?: string | null;
1117
+ country?: string | null;
1118
+ notes?: string | null;
1119
+ createdBy?: string | null;
1120
+ };
1121
+ InsertFloor: {
1122
+ propertyId: number;
1123
+ organizationId: string;
1124
+ name?: string;
1125
+ level?: number;
1126
+ sortOrder?: number;
1127
+ notes?: string | null;
1128
+ };
1129
+ InsertScan: {
1130
+ jobId: number;
1131
+ organizationId: string;
1132
+ assetId?: string | null;
1133
+ name: string;
1134
+ description?: string | null;
1135
+ fileType?: string;
1136
+ scaleFactor?: number | null;
1137
+ scaleCalibrated?: boolean | null;
1138
+ pageNumber?: number | null;
1139
+ totalPages?: number | null;
1140
+ processingStatus?: string;
1141
+ aiAnalysis?: string | number | boolean | null | {
1142
+ [key: string]: unknown;
1143
+ } | unknown[];
1144
+ featureTier?: string | null;
1145
+ xactimateMetadata?: string | number | boolean | null | {
1146
+ [key: string]: unknown;
1147
+ } | unknown[];
1148
+ parentScanId?: number | null;
1149
+ doorwayLinks?: string | number | boolean | null | {
1150
+ [key: string]: unknown;
1151
+ } | unknown[];
1152
+ rawRoomPlanData?: string | number | boolean | null | {
1153
+ [key: string]: unknown;
1154
+ } | unknown[];
1155
+ cleanupPipelineVersion?: string | null;
1156
+ clientCleanupPipelineVersion?: string | null;
1157
+ userOrientationHint?: string | null;
1158
+ wallConfidences?: string | number | boolean | null | {
1159
+ [key: string]: unknown;
1160
+ } | unknown[];
1161
+ deviceTrack?: string | number | boolean | null | {
1162
+ [key: string]: unknown;
1163
+ } | unknown[];
1164
+ referencePhotoKeys?: (string | null)[] | null;
1165
+ metricCorrection?: number | null;
1166
+ squareUpAngleRad?: number | null;
1167
+ clientMirrorApplied?: boolean | null;
1168
+ deviceModel?: string | null;
1169
+ appVersion?: string | null;
1170
+ captureTimestamp?: string | null;
1171
+ captureMode?: string | null;
1172
+ sessionId?: string | null;
1173
+ sessionCapturedAt?: string | null;
1174
+ floorPlanAssetId?: string | null;
1175
+ floorPlanPixelsPerMeter?: number | null;
1176
+ floorPlanOffsetX?: number | null;
1177
+ floorPlanOffsetY?: number | null;
1178
+ floorPlanWidthPx?: number | null;
1179
+ floorPlanHeightPx?: number | null;
1180
+ floorId?: number | null;
1181
+ createdBy?: string | null;
1182
+ deletedAt?: string | null;
1183
+ deletedBy?: string | null;
1184
+ };
1185
+ InsertTask: {
1186
+ userId?: string | null;
1187
+ organizationId?: string | null;
1188
+ contactId?: number | null;
1189
+ projectId?: number | null;
1190
+ agentId?: number | null;
1191
+ title: string;
1192
+ description?: string | null;
1193
+ taskType?: string | null;
1194
+ location?: string | null;
1195
+ startDate?: string | null;
1196
+ dueDate?: string | null;
1197
+ allDay?: boolean | null;
1198
+ status?: string | null;
1199
+ priority?: string | null;
1200
+ assignedTo?: string | number | boolean | null | {
1201
+ [key: string]: unknown;
1202
+ } | unknown[];
1203
+ assignedContactIds?: string | number | boolean | null | {
1204
+ [key: string]: unknown;
1205
+ } | unknown[];
1206
+ progress?: number | null;
1207
+ checklist?: string | number | boolean | null | {
1208
+ [key: string]: unknown;
1209
+ } | unknown[];
1210
+ relatedFiles?: string | number | boolean | null | {
1211
+ [key: string]: unknown;
1212
+ } | unknown[];
1213
+ /** @enum {string|null} */
1214
+ reminder?: "none" | "when_due" | "15_min" | "30_min" | "1_hour" | "1_day" | null;
1215
+ reminderNotificationId?: number | null;
1216
+ isRecurring?: boolean | null;
1217
+ recurrencePattern?: string | null;
1218
+ recurrenceInterval?: number | null;
1219
+ recurrenceEndDate?: string | null;
1220
+ parentTaskId?: number | null;
1221
+ recurrenceDate?: string | null;
1222
+ isRecurrenceException?: boolean | null;
1223
+ excludedDates?: string | number | boolean | null | {
1224
+ [key: string]: unknown;
1225
+ } | unknown[];
1226
+ displayIndex?: number | null;
1227
+ deletedAt?: string | null;
1228
+ deletedBy?: string | null;
1229
+ };
1230
+ InsertNote: {
1231
+ userId?: string | null;
1232
+ organizationId?: string | null;
1233
+ contactId?: number | null;
1234
+ content: string;
1235
+ userName?: string | null;
1236
+ userEmail?: string | null;
1237
+ deletedAt?: string | null;
1238
+ deletedBy?: string | null;
1239
+ };
1240
+ InsertFile: {
1241
+ organizationId: string;
1242
+ folderId: number;
1243
+ name: string;
1244
+ originalName: string;
1245
+ mimeType?: string | null;
1246
+ size?: number | null;
1247
+ storageUrl?: string | null;
1248
+ assetId?: string | null;
1249
+ thumbnailUrl?: string | null;
1250
+ metadata?: string | number | boolean | null | {
1251
+ [key: string]: unknown;
1252
+ } | unknown[];
1253
+ uploadedBy?: string | null;
1254
+ deletedAt?: string | null;
1255
+ deletedBy?: string | null;
1256
+ };
1257
+ InsertFolder: {
1258
+ organizationId: string;
1259
+ name: string;
1260
+ parentId?: number | null;
1261
+ isSystemFolder?: boolean | null;
1262
+ folderType?: string | null;
1263
+ createdBy?: string | null;
1264
+ deletedAt?: string | null;
1265
+ deletedBy?: string | null;
1266
+ };
1267
+ InsertEstimate: {
1268
+ jobId: number;
1269
+ estimateNumber: string;
1270
+ name?: string | null;
1271
+ version?: number | null;
1272
+ templateId?: number | null;
1273
+ pricelistId?: number | null;
1274
+ status?: string | null;
1275
+ subtotal?: string | null;
1276
+ taxAmount?: string | null;
1277
+ discountAmount?: string | null;
1278
+ discountPercent?: string | null;
1279
+ overheadEnabled?: boolean | null;
1280
+ overheadPercent?: string | null;
1281
+ profitEnabled?: boolean | null;
1282
+ profitPercent?: string | null;
1283
+ totalAmount?: string | null;
1284
+ description?: string | null;
1285
+ sections?: string | number | boolean | null | {
1286
+ [key: string]: unknown;
1287
+ } | unknown[];
1288
+ terms?: string | null;
1289
+ notes?: string | null;
1290
+ internalNotes?: string | null;
1291
+ validUntil?: string | null;
1292
+ sentAt?: string | null;
1293
+ approvedAt?: string | null;
1294
+ approvedBy?: string | null;
1295
+ rejectedAt?: string | null;
1296
+ rejectionReason?: string | null;
1297
+ signedAt?: string | null;
1298
+ signatureMeta?: string | number | boolean | null | {
1299
+ [key: string]: unknown;
1300
+ } | unknown[];
1301
+ signatureProvider?: string | null;
1302
+ signatureId?: string | null;
1303
+ signerName?: string | null;
1304
+ signerEmail?: string | null;
1305
+ signerIp?: string | null;
1306
+ revisionRequestedAt?: string | null;
1307
+ revisionNotes?: string | null;
1308
+ customerResponseAt?: string | null;
1309
+ convertedToInvoiceId?: number | null;
1310
+ voidedAt?: string | null;
1311
+ voidedBy?: string | null;
1312
+ voidedReason?: string | null;
1313
+ signatureLocked?: boolean | null;
1314
+ signNowStatus?: string | null;
1315
+ signNowRoleId?: string | null;
1316
+ signNowRoleName?: string | null;
1317
+ portalVisible?: boolean | null;
1318
+ signedCompletionEmailSentAt?: string | null;
1319
+ qboId?: string | null;
1320
+ qboSyncToken?: string | null;
1321
+ qboLastPushedAt?: string | null;
1322
+ qboLastPushedHash?: string | null;
1323
+ qboLastError?: string | null;
1324
+ createdBy?: string | null;
1325
+ deletedAt?: string | null;
1326
+ deletedBy?: string | null;
1327
+ };
1328
+ PhotoUploadResponse: {
1329
+ id: number;
1330
+ url: string;
1331
+ s3Key: string;
1332
+ contentType: string;
1333
+ width?: number | null;
1334
+ height?: number | null;
1335
+ watermarked: boolean;
1336
+ };
1337
+ MeResponse: {
1338
+ id: number;
1339
+ /** Format: email */
1340
+ email: string;
1341
+ name?: string | null;
1342
+ orgId: number;
1343
+ role: string;
1344
+ };
1345
+ /** @description POST /api/jobs/:jobId/scans/mobile-upload body. Required: `roomPlanJSON` (object with nested `rooms` array) + `name`. All other fields are additive / optional per the v2 contract. */
1346
+ MobileUploadRequest: {
1347
+ roomPlanJSON: {
1348
+ rooms: {
1349
+ label?: string;
1350
+ name?: string;
1351
+ category?: string;
1352
+ walls?: unknown[];
1353
+ doors?: {
1354
+ position: {
1355
+ x: number;
1356
+ y: number;
1357
+ z: number;
1358
+ };
1359
+ width: number;
1360
+ height: number;
1361
+ hostWallIndex?: number | null;
1362
+ wallIndex?: number;
1363
+ /** @enum {string} */
1364
+ swingHand?: "left" | "right" | "none";
1365
+ }[];
1366
+ windows?: {
1367
+ position: {
1368
+ x: number;
1369
+ y: number;
1370
+ z: number;
1371
+ };
1372
+ width: number;
1373
+ height: number;
1374
+ hostWallIndex?: number | null;
1375
+ wallIndex?: number;
1376
+ /** @enum {string} */
1377
+ swingHand?: "left" | "right" | "none";
1378
+ }[];
1379
+ openings?: {
1380
+ position: {
1381
+ x: number;
1382
+ y: number;
1383
+ z: number;
1384
+ };
1385
+ width: number;
1386
+ height: number;
1387
+ hostWallIndex?: number | null;
1388
+ wallIndex?: number;
1389
+ /** @enum {string} */
1390
+ swingHand?: "left" | "right" | "none";
1391
+ }[];
1392
+ }[];
1393
+ };
1394
+ name: string;
1395
+ description?: string;
1396
+ assetId?: string;
1397
+ autoMeasure?: boolean;
1398
+ cleanupPipelineVersion?: string;
1399
+ userOrientationHint?: string;
1400
+ wallConfidences?: unknown[];
1401
+ deviceTrack?: unknown;
1402
+ referencePhotos?: unknown[];
1403
+ propertyId?: number;
1404
+ floorId?: number;
1405
+ floorName?: string;
1406
+ floorLevel?: number;
1407
+ roomLocalId?: string;
1408
+ roomNotes?: {
1409
+ roomLocalId: string;
1410
+ note: string;
1411
+ }[];
1412
+ deviceModel?: string;
1413
+ appVersion?: string;
1414
+ captureTimestamp?: string;
1415
+ manualMeasurements?: {
1416
+ id: string;
1417
+ roomLocalId: string;
1418
+ wallIndex: number;
1419
+ valueMeters: number;
1420
+ capturedAt: string;
1421
+ capturedBy?: string | null;
1422
+ }[];
1423
+ /** @enum {string} */
1424
+ captureMode?: "session" | "view";
1425
+ sessionId?: string;
1426
+ sessionCapturedAt?: string;
1427
+ clientMirrorApplied?: boolean;
1428
+ };
1429
+ MobileUploadResponse: {
1430
+ scanId: number;
1431
+ processingStatus: string;
1432
+ floorId: number | null;
1433
+ manualMeasurementCount: number;
1434
+ message: string;
1435
+ parentScanId?: number;
1436
+ /** @enum {boolean} */
1437
+ appendRoom?: true;
1438
+ idempotent?: boolean;
1439
+ };
1440
+ FeatureFlags: {
1441
+ floorPlanPivot: boolean;
1442
+ manualMeasurements: boolean;
1443
+ scanRoomSnapshots: boolean;
1444
+ roomConnections: boolean;
1445
+ };
1446
+ JobSummary: {
1447
+ id: number;
1448
+ name: string;
1449
+ description?: string | null;
1450
+ status: string;
1451
+ propertyId?: number | null;
1452
+ contactId?: number | null;
1453
+ workflowId?: number | null;
1454
+ workflowStage?: string | null;
1455
+ startDate?: string | null;
1456
+ dueDate?: string | null;
1457
+ createdAt: string;
1458
+ };
1459
+ JobCreateRequest: {
1460
+ name: string;
1461
+ description?: string;
1462
+ propertyId?: number;
1463
+ contactId?: number;
1464
+ workflowId?: number;
1465
+ startDate?: string;
1466
+ dueDate?: string;
1467
+ };
1468
+ ChattySessionStartRequest: {
1469
+ jobId?: number;
1470
+ contactId?: number;
1471
+ /** @example en-US */
1472
+ locale?: string;
1473
+ /** @example alloy */
1474
+ voice?: string;
1475
+ systemPromptOverride?: string;
1476
+ };
1477
+ ChattySessionToken: {
1478
+ sessionId: string;
1479
+ expiresAt: string;
1480
+ websocketUrl: string;
1481
+ ephemeralToken: string;
1482
+ model: string;
1483
+ voice: string;
1484
+ };
1485
+ ChattyMessage: {
1486
+ id: string;
1487
+ /** @enum {string} */
1488
+ role: "user" | "assistant" | "tool";
1489
+ text?: string | null;
1490
+ audioUrl?: string | null;
1491
+ createdAt: string;
1492
+ toolCalls?: {
1493
+ name: string;
1494
+ arguments?: unknown;
1495
+ }[];
1496
+ };
1497
+ };
1498
+ responses: never;
1499
+ parameters: never;
1500
+ requestBodies: never;
1501
+ headers: never;
1502
+ pathItems: never;
1503
+ }
1504
+ export type $defs = Record<string, never>;
1505
+ export type operations = Record<string, never>;