@serviceai/api-spec 1.2.418 → 1.2.419
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/openapi.json +791 -41
- package/openapi.yaml +720 -39
- package/package.json +1 -1
- package/types.d.ts +382 -33
package/openapi.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
openapi: 3.1.0
|
|
2
2
|
info:
|
|
3
3
|
title: ServiceAi API
|
|
4
|
-
version: 1.2.
|
|
4
|
+
version: 1.2.419
|
|
5
5
|
description: >-
|
|
6
6
|
Source-of-truth API contract for ServiceAi. Generated from `shared/schema.ts` Zod schemas by
|
|
7
7
|
`scripts/build-api-spec.ts`. Versioning policy: see `docs/api-versioning.md`. The hand-written docs/ios-contract.md
|
|
@@ -41,6 +41,8 @@ tags:
|
|
|
41
41
|
description: >-
|
|
42
42
|
When a person is expected to work (employee_shifts), and time-off requests against it. Separate from the job
|
|
43
43
|
calendar by design.
|
|
44
|
+
- name: account
|
|
45
|
+
description: 'The signed-in person''s own account: asking for it to be deleted.'
|
|
44
46
|
components:
|
|
45
47
|
schemas:
|
|
46
48
|
ErrorEnvelope:
|
|
@@ -87,7 +89,7 @@ components:
|
|
|
87
89
|
properties:
|
|
88
90
|
apiVersion:
|
|
89
91
|
type: string
|
|
90
|
-
example: 1.2.
|
|
92
|
+
example: 1.2.419
|
|
91
93
|
minClientVersion:
|
|
92
94
|
type: string
|
|
93
95
|
example: 1.0.0
|
|
@@ -2091,6 +2093,71 @@ components:
|
|
|
2091
2093
|
minLength: 1
|
|
2092
2094
|
required:
|
|
2093
2095
|
- sdp
|
|
2096
|
+
PunchTimeCheck:
|
|
2097
|
+
type: object
|
|
2098
|
+
properties:
|
|
2099
|
+
reasons:
|
|
2100
|
+
type: array
|
|
2101
|
+
items:
|
|
2102
|
+
type: string
|
|
2103
|
+
enum:
|
|
2104
|
+
- server_time
|
|
2105
|
+
- unverified
|
|
2106
|
+
- clock_changed
|
|
2107
|
+
- too_old
|
|
2108
|
+
- replaced_auto_close
|
|
2109
|
+
- after_auto_close
|
|
2110
|
+
- auto_close_kept
|
|
2111
|
+
description: >-
|
|
2112
|
+
server_time: the phone's time was more than 2 minutes from the server's, and the server's was recorded.
|
|
2113
|
+
unverified: the phone restarted before sending, so the time couldn't be checked; the phone's was kept.
|
|
2114
|
+
clock_changed: the phone's clock was changed by hand. Late stops (T6): too_old: a stop more than 12 hours
|
|
2115
|
+
old that couldn't be proven was recorded at the 12-hour limit. replaced_auto_close: a proven stop replaced
|
|
2116
|
+
the automatic close (autoAt). after_auto_close: a stop later than the automatic close; the automatic close
|
|
2117
|
+
was kept. auto_close_kept: a stop earlier than the automatic close that wasn't applied (keptBecause).
|
|
2118
|
+
phoneAt:
|
|
2119
|
+
type:
|
|
2120
|
+
- string
|
|
2121
|
+
- 'null'
|
|
2122
|
+
format: date-time
|
|
2123
|
+
description: The phone's own time for the tap.
|
|
2124
|
+
serverAt:
|
|
2125
|
+
type:
|
|
2126
|
+
- string
|
|
2127
|
+
- 'null'
|
|
2128
|
+
format: date-time
|
|
2129
|
+
description: The tap by the server's clock (arrival minus tapElapsedMs); null when the phone couldn't say.
|
|
2130
|
+
receivedAt:
|
|
2131
|
+
type: string
|
|
2132
|
+
format: date-time
|
|
2133
|
+
description: When the request reached the server.
|
|
2134
|
+
tapElapsedMs:
|
|
2135
|
+
type:
|
|
2136
|
+
- integer
|
|
2137
|
+
- 'null'
|
|
2138
|
+
verified:
|
|
2139
|
+
type: boolean
|
|
2140
|
+
description: True when the phone's stopwatch proved the tap's time.
|
|
2141
|
+
autoAt:
|
|
2142
|
+
type: string
|
|
2143
|
+
format: date-time
|
|
2144
|
+
description: The automatic close a late stop replaced or was held against.
|
|
2145
|
+
keptBecause:
|
|
2146
|
+
type: string
|
|
2147
|
+
enum:
|
|
2148
|
+
- unverified
|
|
2149
|
+
- office
|
|
2150
|
+
- locked
|
|
2151
|
+
description: >-
|
|
2152
|
+
Why a late stop wasn't applied: its time couldn't be proven, the office had already changed or approved the
|
|
2153
|
+
time, or the pay period is locked.
|
|
2154
|
+
required:
|
|
2155
|
+
- reasons
|
|
2156
|
+
- phoneAt
|
|
2157
|
+
- serverAt
|
|
2158
|
+
- receivedAt
|
|
2159
|
+
- tapElapsedMs
|
|
2160
|
+
description: A tap whose time the office is asked to look at, with both times. It waits in Team › Needs attention.
|
|
2094
2161
|
TimeEntry:
|
|
2095
2162
|
type: object
|
|
2096
2163
|
properties:
|
|
@@ -2189,6 +2256,46 @@ components:
|
|
|
2189
2256
|
breakMinutes:
|
|
2190
2257
|
type: integer
|
|
2191
2258
|
description: Unpaid break minutes recorded against this entry.
|
|
2259
|
+
startCheck:
|
|
2260
|
+
type:
|
|
2261
|
+
- string
|
|
2262
|
+
- 'null'
|
|
2263
|
+
enum:
|
|
2264
|
+
- away
|
|
2265
|
+
- no_location
|
|
2266
|
+
description: >-
|
|
2267
|
+
Job time started by hand away from the job ('away') or with no usable location ('no_location'); null for a
|
|
2268
|
+
normal start. The office decides it.
|
|
2269
|
+
startDistanceM:
|
|
2270
|
+
type:
|
|
2271
|
+
- integer
|
|
2272
|
+
- 'null'
|
|
2273
|
+
description: How far from the job's site center the start was, when startCheck is 'away'.
|
|
2274
|
+
startReview:
|
|
2275
|
+
type:
|
|
2276
|
+
- string
|
|
2277
|
+
- 'null'
|
|
2278
|
+
enum:
|
|
2279
|
+
- approved
|
|
2280
|
+
- not_approved
|
|
2281
|
+
- moved
|
|
2282
|
+
description: >-
|
|
2283
|
+
The office's decision on a flagged start; null while it waits. 'not_approved' stays on the timesheet but off
|
|
2284
|
+
the job's costing.
|
|
2285
|
+
clockInCheck:
|
|
2286
|
+
allOf:
|
|
2287
|
+
- $ref: '#/components/schemas/PunchTimeCheck'
|
|
2288
|
+
- type:
|
|
2289
|
+
- object
|
|
2290
|
+
- 'null'
|
|
2291
|
+
description: Set when the start's time was checked and the office is asked to look; clockIn holds the time recorded.
|
|
2292
|
+
clockOutCheck:
|
|
2293
|
+
allOf:
|
|
2294
|
+
- $ref: '#/components/schemas/PunchTimeCheck'
|
|
2295
|
+
- type:
|
|
2296
|
+
- object
|
|
2297
|
+
- 'null'
|
|
2298
|
+
description: The same for the stop; clockOut holds the time recorded.
|
|
2192
2299
|
createdAt:
|
|
2193
2300
|
type:
|
|
2194
2301
|
- string
|
|
@@ -2199,7 +2306,7 @@ components:
|
|
|
2199
2306
|
description: Enrichment on /active and /entries. 'Office' for an office entry.
|
|
2200
2307
|
userName:
|
|
2201
2308
|
type: string
|
|
2202
|
-
description: Enrichment on /entries
|
|
2309
|
+
description: Enrichment on /entries.
|
|
2203
2310
|
required:
|
|
2204
2311
|
- id
|
|
2205
2312
|
- organizationId
|
|
@@ -2356,6 +2463,22 @@ components:
|
|
|
2356
2463
|
type:
|
|
2357
2464
|
- string
|
|
2358
2465
|
- 'null'
|
|
2466
|
+
clockInCheck:
|
|
2467
|
+
allOf:
|
|
2468
|
+
- $ref: '#/components/schemas/PunchTimeCheck'
|
|
2469
|
+
- type:
|
|
2470
|
+
- object
|
|
2471
|
+
- 'null'
|
|
2472
|
+
description: >-
|
|
2473
|
+
Set when the Clock In tap's time was checked and the office is asked to look; clockIn holds the time
|
|
2474
|
+
recorded.
|
|
2475
|
+
clockOutCheck:
|
|
2476
|
+
allOf:
|
|
2477
|
+
- $ref: '#/components/schemas/PunchTimeCheck'
|
|
2478
|
+
- type:
|
|
2479
|
+
- object
|
|
2480
|
+
- 'null'
|
|
2481
|
+
description: The same for the Clock Out tap; clockOut holds the time recorded.
|
|
2359
2482
|
editedBy:
|
|
2360
2483
|
type:
|
|
2361
2484
|
- string
|
|
@@ -2451,6 +2574,28 @@ components:
|
|
|
2451
2574
|
MyDayResponse:
|
|
2452
2575
|
type: object
|
|
2453
2576
|
properties:
|
|
2577
|
+
payrollAddon:
|
|
2578
|
+
type: boolean
|
|
2579
|
+
description: >-
|
|
2580
|
+
The company's time tracking (payroll) add-on. False: no Clock In/Out, no work days, schedules, time cards or
|
|
2581
|
+
pay; job time still runs. Then open is null, today is empty, shiftEnd is null, payroll.breakButton and
|
|
2582
|
+
locationTrail are false, and the payroll routes answer 403 PAYROLL_OFF. Not the same as payroll.enabled.
|
|
2583
|
+
payroll:
|
|
2584
|
+
type: object
|
|
2585
|
+
properties:
|
|
2586
|
+
enabled:
|
|
2587
|
+
type: boolean
|
|
2588
|
+
description: A pay period is set (the company's pay rules are on).
|
|
2589
|
+
breakButton:
|
|
2590
|
+
type: boolean
|
|
2591
|
+
description: Show the break button (false when this person's lunch comes off automatically).
|
|
2592
|
+
breaksPaid:
|
|
2593
|
+
type: boolean
|
|
2594
|
+
required:
|
|
2595
|
+
- enabled
|
|
2596
|
+
- breakButton
|
|
2597
|
+
- breaksPaid
|
|
2598
|
+
description: The company's pay rules as they touch this person.
|
|
2454
2599
|
dayModel:
|
|
2455
2600
|
type: boolean
|
|
2456
2601
|
description: True once this person is on the day model.
|
|
@@ -2507,6 +2652,8 @@ components:
|
|
|
2507
2652
|
- address
|
|
2508
2653
|
description: The office fence, when the org profile address is on the map.
|
|
2509
2654
|
required:
|
|
2655
|
+
- payrollAddon
|
|
2656
|
+
- payroll
|
|
2510
2657
|
- dayModel
|
|
2511
2658
|
- open
|
|
2512
2659
|
- today
|
|
@@ -2648,11 +2795,40 @@ components:
|
|
|
2648
2795
|
autoClockEnabled:
|
|
2649
2796
|
type: boolean
|
|
2650
2797
|
description: The user's auto-clock toggle at crossing time. False → the crossing is logged but never acted on.
|
|
2798
|
+
tapElapsedMs:
|
|
2799
|
+
type:
|
|
2800
|
+
- integer
|
|
2801
|
+
- 'null'
|
|
2802
|
+
minimum: 0
|
|
2803
|
+
description: >-
|
|
2804
|
+
Milliseconds from the tap to this send, from the phone's monotonic clock (a stopwatch the person can't
|
|
2805
|
+
change). An offline replay sends the time since the tap. The server's tap time is its own clock when the
|
|
2806
|
+
request arrives minus this. Within 2 minutes of the phone's time, the phone's time stands (never later than
|
|
2807
|
+
the tap); further apart, the server's tap time is recorded and the office is asked to look. A Clock Out or
|
|
2808
|
+
job time stop it proves this way keeps its real time however old; without it, a stop older than 12 hours is
|
|
2809
|
+
recorded at the 12-hour limit and flagged (T6). Send it with every queued tap, clock-outs included.
|
|
2810
|
+
tapTimeUnverified:
|
|
2811
|
+
type:
|
|
2812
|
+
- boolean
|
|
2813
|
+
- 'null'
|
|
2814
|
+
description: >-
|
|
2815
|
+
True when the phone restarted between the tap and this send, so there is no stopwatch reading (send no
|
|
2816
|
+
tapElapsedMs). A tap more than 2 minutes old keeps the phone's time and is flagged for the office.
|
|
2817
|
+
deviceClockChanged:
|
|
2818
|
+
type:
|
|
2819
|
+
- boolean
|
|
2820
|
+
- 'null'
|
|
2821
|
+
description: >-
|
|
2822
|
+
True when the phone's clock was changed by hand since the phone last synced. The tap is flagged for the
|
|
2823
|
+
office.
|
|
2651
2824
|
required:
|
|
2652
2825
|
- clientEventId
|
|
2653
2826
|
- kind
|
|
2654
2827
|
- occurredAt
|
|
2655
|
-
description:
|
|
2828
|
+
description: >-
|
|
2829
|
+
One fence crossing as the device saw it. With tapElapsedMs (the time since the crossing), the server checks
|
|
2830
|
+
occurredAt against its own clock before the resolver uses it, and the entry the crossing opens or closes carries
|
|
2831
|
+
the check. A departure it proves isn't held to the 12-hour limit (T6).
|
|
2656
2832
|
CrossingsAck:
|
|
2657
2833
|
type: object
|
|
2658
2834
|
properties:
|
|
@@ -2802,6 +2978,12 @@ components:
|
|
|
2802
2978
|
canEdit:
|
|
2803
2979
|
type: boolean
|
|
2804
2980
|
description: True only for the primary account.
|
|
2981
|
+
jobSiteTracking:
|
|
2982
|
+
type: boolean
|
|
2983
|
+
description: >-
|
|
2984
|
+
The caller's own switch, set by the office (owner's O9). False: watch no job-site fences and use no location
|
|
2985
|
+
for job time; job time comes only from Start/Stop job time. The office fence, Clock In/Out and the company
|
|
2986
|
+
switches are unaffected. Absent (an older server): treat as true.
|
|
2805
2987
|
required:
|
|
2806
2988
|
- serverResolver
|
|
2807
2989
|
- dwellSeconds
|
|
@@ -2987,6 +3169,11 @@ components:
|
|
|
2987
3169
|
type: string
|
|
2988
3170
|
format: date
|
|
2989
3171
|
description: The org-local date, which is not necessarily the device's.
|
|
3172
|
+
payrollAddon:
|
|
3173
|
+
type: boolean
|
|
3174
|
+
description: >-
|
|
3175
|
+
False when the company has the time tracking add-on off: no shifts, hours or time off come back, and nothing
|
|
3176
|
+
covers now.
|
|
2990
3177
|
hours:
|
|
2991
3178
|
type: object
|
|
2992
3179
|
additionalProperties:
|
|
@@ -3069,12 +3256,73 @@ components:
|
|
|
3069
3256
|
- from
|
|
3070
3257
|
- to
|
|
3071
3258
|
- today
|
|
3259
|
+
- payrollAddon
|
|
3072
3260
|
- hours
|
|
3073
3261
|
- attendance
|
|
3074
3262
|
- shifts
|
|
3075
3263
|
- timeOff
|
|
3076
3264
|
- recentTimeOff
|
|
3077
3265
|
description: When I should be in, plus what I actually worked. The clock-in expectation lives here.
|
|
3266
|
+
OnTheClockRow:
|
|
3267
|
+
type: object
|
|
3268
|
+
properties:
|
|
3269
|
+
userId:
|
|
3270
|
+
type: string
|
|
3271
|
+
userName:
|
|
3272
|
+
type: string
|
|
3273
|
+
entryId:
|
|
3274
|
+
type:
|
|
3275
|
+
- integer
|
|
3276
|
+
- 'null'
|
|
3277
|
+
description: The open site entry; null between sites (a day with nothing open).
|
|
3278
|
+
jobId:
|
|
3279
|
+
type:
|
|
3280
|
+
- integer
|
|
3281
|
+
- 'null'
|
|
3282
|
+
siteType:
|
|
3283
|
+
type: string
|
|
3284
|
+
enum:
|
|
3285
|
+
- job
|
|
3286
|
+
- office
|
|
3287
|
+
- none
|
|
3288
|
+
description: '''none'' between sites.'
|
|
3289
|
+
jobName:
|
|
3290
|
+
type:
|
|
3291
|
+
- string
|
|
3292
|
+
- 'null'
|
|
3293
|
+
since:
|
|
3294
|
+
type: string
|
|
3295
|
+
format: date-time
|
|
3296
|
+
description: When the work day began, else when the entry did.
|
|
3297
|
+
required:
|
|
3298
|
+
- userId
|
|
3299
|
+
- userName
|
|
3300
|
+
- entryId
|
|
3301
|
+
- jobId
|
|
3302
|
+
- siteType
|
|
3303
|
+
- jobName
|
|
3304
|
+
- since
|
|
3305
|
+
description: >-
|
|
3306
|
+
One person on the clock (server/onTheClock.ts). Job time with no paid day behind it is left out: that person is
|
|
3307
|
+
at a job, not on the clock.
|
|
3308
|
+
AccountDeletionRequest:
|
|
3309
|
+
type: object
|
|
3310
|
+
properties:
|
|
3311
|
+
status:
|
|
3312
|
+
type: string
|
|
3313
|
+
enum:
|
|
3314
|
+
- pending
|
|
3315
|
+
- completed
|
|
3316
|
+
- cancelled
|
|
3317
|
+
requestedAt:
|
|
3318
|
+
type: string
|
|
3319
|
+
format: date-time
|
|
3320
|
+
required:
|
|
3321
|
+
- status
|
|
3322
|
+
- requestedAt
|
|
3323
|
+
description: >-
|
|
3324
|
+
The signed-in person's request to have their account deleted. pending: waiting for the company; completed: the
|
|
3325
|
+
company marked it done; cancelled: the company cancelled it (asking again starts a new one).
|
|
3078
3326
|
parameters: {}
|
|
3079
3327
|
paths:
|
|
3080
3328
|
/api/version:
|
|
@@ -4272,13 +4520,33 @@ paths:
|
|
|
4272
4520
|
placementSource:
|
|
4273
4521
|
type: string
|
|
4274
4522
|
enum: *ref_1
|
|
4523
|
+
duplicateOf:
|
|
4524
|
+
type: object
|
|
4525
|
+
properties:
|
|
4526
|
+
roomId:
|
|
4527
|
+
type: integer
|
|
4528
|
+
description: Id of the room whose copy of this doorway is drawn.
|
|
4529
|
+
doorIndex:
|
|
4530
|
+
type: integer
|
|
4531
|
+
minimum: 0
|
|
4532
|
+
description: Index into that room's `doors[]`.
|
|
4533
|
+
required:
|
|
4534
|
+
- roomId
|
|
4535
|
+
- doorIndex
|
|
4536
|
+
description: >-
|
|
4537
|
+
Present only on the later-scanned room's copy of a doorway two rooms in this response
|
|
4538
|
+
share (the rooms are linked by a door link, or their doors coincide on one wall). Skip
|
|
4539
|
+
this door's glyph and keep its wall gap; the door it names is the one to draw. Absent
|
|
4540
|
+
on every other door. Read-time only: never send it back, it is never stored.
|
|
4275
4541
|
required:
|
|
4276
4542
|
- position
|
|
4277
4543
|
- width
|
|
4278
4544
|
- height
|
|
4279
4545
|
description: >-
|
|
4280
4546
|
RoomPlan-classified doors. Distinct from `windows[]` and `openings[]`; append-room
|
|
4281
|
-
`entryDoorwayId` tokens of the form `…-door-<idx>` resolve into THIS array only.
|
|
4547
|
+
`entryDoorwayId` tokens of the form `…-door-<idx>` resolve into THIS array only. A door
|
|
4548
|
+
carrying `duplicateOf` is the hidden copy of a shared doorway (one door per doorway, from
|
|
4549
|
+
the room scanned first).
|
|
4282
4550
|
windows:
|
|
4283
4551
|
type: array
|
|
4284
4552
|
items:
|
|
@@ -4513,13 +4781,34 @@ paths:
|
|
|
4513
4781
|
placementSource:
|
|
4514
4782
|
type: string
|
|
4515
4783
|
enum: *ref_1
|
|
4784
|
+
duplicateOf:
|
|
4785
|
+
type: object
|
|
4786
|
+
properties:
|
|
4787
|
+
roomId:
|
|
4788
|
+
type: integer
|
|
4789
|
+
description: Id of the room whose copy of this doorway is drawn.
|
|
4790
|
+
doorIndex:
|
|
4791
|
+
type: integer
|
|
4792
|
+
minimum: 0
|
|
4793
|
+
description: Index into that room's `doors[]`.
|
|
4794
|
+
required:
|
|
4795
|
+
- roomId
|
|
4796
|
+
- doorIndex
|
|
4797
|
+
description: >-
|
|
4798
|
+
Present only on the later-scanned room's copy of a doorway two rooms in this
|
|
4799
|
+
response share (the rooms are linked by a door link, or their doors coincide on
|
|
4800
|
+
one wall). Skip this door's glyph and keep its wall gap; the door it names is the
|
|
4801
|
+
one to draw. Absent on every other door. Read-time only: never send it back, it is
|
|
4802
|
+
never stored.
|
|
4516
4803
|
required:
|
|
4517
4804
|
- position
|
|
4518
4805
|
- width
|
|
4519
4806
|
- height
|
|
4520
4807
|
description: >-
|
|
4521
4808
|
RoomPlan-classified doors. Distinct from `windows[]` and `openings[]`; append-room
|
|
4522
|
-
`entryDoorwayId` tokens of the form `…-door-<idx>` resolve into THIS array only.
|
|
4809
|
+
`entryDoorwayId` tokens of the form `…-door-<idx>` resolve into THIS array only. A door
|
|
4810
|
+
carrying `duplicateOf` is the hidden copy of a shared doorway (one door per doorway,
|
|
4811
|
+
from the room scanned first).
|
|
4523
4812
|
windows:
|
|
4524
4813
|
type: array
|
|
4525
4814
|
items:
|
|
@@ -5203,7 +5492,37 @@ paths:
|
|
|
5203
5492
|
- string
|
|
5204
5493
|
- 'null'
|
|
5205
5494
|
format: date-time
|
|
5206
|
-
description:
|
|
5495
|
+
description: >-
|
|
5496
|
+
When the tap happened, by the phone's clock. The server checks it against its own (tapElapsedMs) and
|
|
5497
|
+
clamps it. From the web (device 'web') it is ignored: the server's receipt time is used.
|
|
5498
|
+
tapElapsedMs:
|
|
5499
|
+
type:
|
|
5500
|
+
- integer
|
|
5501
|
+
- 'null'
|
|
5502
|
+
minimum: 0
|
|
5503
|
+
description: >-
|
|
5504
|
+
Milliseconds from the tap to this send, from the phone's monotonic clock (a stopwatch the person
|
|
5505
|
+
can't change). An offline replay sends the time since the tap. The server's tap time is its own
|
|
5506
|
+
clock when the request arrives minus this. Within 2 minutes of the phone's time, the phone's time
|
|
5507
|
+
stands (never later than the tap); further apart, the server's tap time is recorded and the office
|
|
5508
|
+
is asked to look. A Clock Out or job time stop it proves this way keeps its real time however old;
|
|
5509
|
+
without it, a stop older than 12 hours is recorded at the 12-hour limit and flagged (T6). Send it
|
|
5510
|
+
with every queued tap, clock-outs included.
|
|
5511
|
+
tapTimeUnverified:
|
|
5512
|
+
type:
|
|
5513
|
+
- boolean
|
|
5514
|
+
- 'null'
|
|
5515
|
+
description: >-
|
|
5516
|
+
True when the phone restarted between the tap and this send, so there is no stopwatch reading (send
|
|
5517
|
+
no tapElapsedMs). A tap more than 2 minutes old keeps the phone's time and is flagged for the
|
|
5518
|
+
office.
|
|
5519
|
+
deviceClockChanged:
|
|
5520
|
+
type:
|
|
5521
|
+
- boolean
|
|
5522
|
+
- 'null'
|
|
5523
|
+
description: >-
|
|
5524
|
+
True when the phone's clock was changed by hand since the phone last synced. The tap is flagged for
|
|
5525
|
+
the office.
|
|
5207
5526
|
notes:
|
|
5208
5527
|
type:
|
|
5209
5528
|
- string
|
|
@@ -5229,7 +5548,10 @@ paths:
|
|
|
5229
5548
|
schema:
|
|
5230
5549
|
$ref: '#/components/schemas/ErrorEnvelope'
|
|
5231
5550
|
'403':
|
|
5232
|
-
description:
|
|
5551
|
+
description: >-
|
|
5552
|
+
Time tracking access denied, no organization on the session, or code PAYROLL_OFF: the company has the time
|
|
5553
|
+
tracking add-on off (GET /api/time-tracking/day says payrollAddon: false). Don't retry; hide Clock In/Out
|
|
5554
|
+
and the other payroll controls.
|
|
5233
5555
|
content:
|
|
5234
5556
|
application/json:
|
|
5235
5557
|
schema:
|
|
@@ -5265,12 +5587,19 @@ paths:
|
|
|
5265
5587
|
$ref: '#/components/schemas/UpgradeRequiredEnvelope'
|
|
5266
5588
|
/api/time-tracking/day/clock-out:
|
|
5267
5589
|
post:
|
|
5268
|
-
summary:
|
|
5590
|
+
summary: >-
|
|
5591
|
+
End my day: the paid day only. Job time (fence or job timer) runs until it is stopped or the phone reports
|
|
5592
|
+
leaving, and is never paid past Clock Out.
|
|
5269
5593
|
tags:
|
|
5270
5594
|
- time-tracking
|
|
5271
5595
|
parameters:
|
|
5272
5596
|
- *ref_3
|
|
5273
5597
|
- *ref_4
|
|
5598
|
+
description: >-
|
|
5599
|
+
A late Clock Out (T6): with tapElapsedMs proving its time, it keeps its real time however old. When the safety
|
|
5600
|
+
net already closed the day (the automatic close), a proven Clock Out earlier than that close replaces it
|
|
5601
|
+
(replacedAutoClose, flagged for the office); anything else about that day is flagged for the office and changes
|
|
5602
|
+
nothing. A proven Clock Out from before the running day started never ends the running day.
|
|
5274
5603
|
requestBody:
|
|
5275
5604
|
content:
|
|
5276
5605
|
application/json:
|
|
@@ -5304,7 +5633,37 @@ paths:
|
|
|
5304
5633
|
- string
|
|
5305
5634
|
- 'null'
|
|
5306
5635
|
format: date-time
|
|
5307
|
-
description:
|
|
5636
|
+
description: >-
|
|
5637
|
+
When the tap happened, by the phone's clock. The server checks it against its own (tapElapsedMs) and
|
|
5638
|
+
clamps it. From the web (device 'web') it is ignored: the server's receipt time is used.
|
|
5639
|
+
tapElapsedMs:
|
|
5640
|
+
type:
|
|
5641
|
+
- integer
|
|
5642
|
+
- 'null'
|
|
5643
|
+
minimum: 0
|
|
5644
|
+
description: >-
|
|
5645
|
+
Milliseconds from the tap to this send, from the phone's monotonic clock (a stopwatch the person
|
|
5646
|
+
can't change). An offline replay sends the time since the tap. The server's tap time is its own
|
|
5647
|
+
clock when the request arrives minus this. Within 2 minutes of the phone's time, the phone's time
|
|
5648
|
+
stands (never later than the tap); further apart, the server's tap time is recorded and the office
|
|
5649
|
+
is asked to look. A Clock Out or job time stop it proves this way keeps its real time however old;
|
|
5650
|
+
without it, a stop older than 12 hours is recorded at the 12-hour limit and flagged (T6). Send it
|
|
5651
|
+
with every queued tap, clock-outs included.
|
|
5652
|
+
tapTimeUnverified:
|
|
5653
|
+
type:
|
|
5654
|
+
- boolean
|
|
5655
|
+
- 'null'
|
|
5656
|
+
description: >-
|
|
5657
|
+
True when the phone restarted between the tap and this send, so there is no stopwatch reading (send
|
|
5658
|
+
no tapElapsedMs). A tap more than 2 minutes old keeps the phone's time and is flagged for the
|
|
5659
|
+
office.
|
|
5660
|
+
deviceClockChanged:
|
|
5661
|
+
type:
|
|
5662
|
+
- boolean
|
|
5663
|
+
- 'null'
|
|
5664
|
+
description: >-
|
|
5665
|
+
True when the phone's clock was changed by hand since the phone last synced. The tap is flagged for
|
|
5666
|
+
the office.
|
|
5308
5667
|
note:
|
|
5309
5668
|
type:
|
|
5310
5669
|
- string
|
|
@@ -5312,7 +5671,7 @@ paths:
|
|
|
5312
5671
|
maxLength: 2000
|
|
5313
5672
|
responses:
|
|
5314
5673
|
'200':
|
|
5315
|
-
description: Day ended.
|
|
5674
|
+
description: Day ended, or the automatic close of the day this tap belongs to replaced (replacedAutoClose).
|
|
5316
5675
|
content:
|
|
5317
5676
|
application/json:
|
|
5318
5677
|
schema:
|
|
@@ -5324,11 +5683,10 @@ paths:
|
|
|
5324
5683
|
- type:
|
|
5325
5684
|
- object
|
|
5326
5685
|
- 'null'
|
|
5327
|
-
|
|
5328
|
-
type:
|
|
5686
|
+
replacedAutoClose:
|
|
5687
|
+
type: boolean
|
|
5329
5688
|
required:
|
|
5330
5689
|
- day
|
|
5331
|
-
- closedEntries
|
|
5332
5690
|
'401':
|
|
5333
5691
|
description: Not signed in.
|
|
5334
5692
|
content:
|
|
@@ -5336,19 +5694,24 @@ paths:
|
|
|
5336
5694
|
schema:
|
|
5337
5695
|
$ref: '#/components/schemas/ErrorEnvelope'
|
|
5338
5696
|
'403':
|
|
5339
|
-
description:
|
|
5697
|
+
description: >-
|
|
5698
|
+
Time tracking access denied, no organization on the session, or code PAYROLL_OFF: the company has the time
|
|
5699
|
+
tracking add-on off (GET /api/time-tracking/day says payrollAddon: false). Don't retry; hide Clock In/Out
|
|
5700
|
+
and the other payroll controls.
|
|
5340
5701
|
content:
|
|
5341
5702
|
application/json:
|
|
5342
5703
|
schema:
|
|
5343
5704
|
$ref: '#/components/schemas/ErrorEnvelope'
|
|
5344
5705
|
'404':
|
|
5345
|
-
description: No day is running (code NO_OPEN_DAY).
|
|
5706
|
+
description: No day is running (code NO_OPEN_DAY). Also when the tap was only flagged for the office.
|
|
5346
5707
|
content:
|
|
5347
5708
|
application/json:
|
|
5348
5709
|
schema:
|
|
5349
5710
|
$ref: '#/components/schemas/ErrorEnvelope'
|
|
5350
5711
|
'409':
|
|
5351
|
-
description:
|
|
5712
|
+
description: >-
|
|
5713
|
+
The day was already closed; or code DAY_CLOSED_AUTOMATICALLY: the tap belongs to an earlier day the safety
|
|
5714
|
+
net closed, and was flagged for the office.
|
|
5352
5715
|
content:
|
|
5353
5716
|
application/json:
|
|
5354
5717
|
schema:
|
|
@@ -5507,7 +5870,9 @@ paths:
|
|
|
5507
5870
|
description: Prepend the office fence (jobId null). Only send it if this client can decode a null jobId.
|
|
5508
5871
|
responses:
|
|
5509
5872
|
'200':
|
|
5510
|
-
description:
|
|
5873
|
+
description: >-
|
|
5874
|
+
Fences, office first when requested. No job fences for someone the office turned job-site tracking off for
|
|
5875
|
+
(clock-config jobSiteTracking false), except with includeClosed for the manual picker.
|
|
5511
5876
|
content:
|
|
5512
5877
|
application/json:
|
|
5513
5878
|
schema:
|
|
@@ -5534,7 +5899,7 @@ paths:
|
|
|
5534
5899
|
$ref: '#/components/schemas/UpgradeRequiredEnvelope'
|
|
5535
5900
|
/api/time-tracking/active:
|
|
5536
5901
|
get:
|
|
5537
|
-
summary: My open entries right now
|
|
5902
|
+
summary: My open entries right now, or who is on the clock.
|
|
5538
5903
|
tags:
|
|
5539
5904
|
- time-tracking
|
|
5540
5905
|
parameters:
|
|
@@ -5547,16 +5912,23 @@ paths:
|
|
|
5547
5912
|
type: string
|
|
5548
5913
|
enum:
|
|
5549
5914
|
- team
|
|
5550
|
-
|
|
5915
|
+
- me
|
|
5916
|
+
description: >-
|
|
5917
|
+
`team`: everyone on the clock, one OnTheClockRow per person; requires time_tracking.view_all. `me`: the
|
|
5918
|
+
caller's own row while on the clock. Without scope: the caller's open entries.
|
|
5551
5919
|
responses:
|
|
5552
5920
|
'200':
|
|
5553
|
-
description:
|
|
5921
|
+
description: 'Without scope: open entries, normally zero or one. With scope: one OnTheClockRow per person on the clock.'
|
|
5554
5922
|
content:
|
|
5555
5923
|
application/json:
|
|
5556
5924
|
schema:
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5925
|
+
anyOf:
|
|
5926
|
+
- type: array
|
|
5927
|
+
items:
|
|
5928
|
+
$ref: '#/components/schemas/TimeEntry'
|
|
5929
|
+
- type: array
|
|
5930
|
+
items:
|
|
5931
|
+
$ref: '#/components/schemas/OnTheClockRow'
|
|
5560
5932
|
'401':
|
|
5561
5933
|
description: Not signed in.
|
|
5562
5934
|
content:
|
|
@@ -5647,10 +6019,15 @@ paths:
|
|
|
5647
6019
|
$ref: '#/components/schemas/UpgradeRequiredEnvelope'
|
|
5648
6020
|
/api/time-tracking/clock-in:
|
|
5649
6021
|
post:
|
|
5650
|
-
summary:
|
|
6022
|
+
summary: Start time on a job or at the office by hand.
|
|
5651
6023
|
description: >-
|
|
5652
|
-
A deliberate button press.
|
|
5653
|
-
|
|
6024
|
+
A deliberate button press. The entry joins the person's work day when one is running. With none running: a job
|
|
6025
|
+
timer press (startDay: false) records job time only and never starts the paid day; a Clock In press (startDay
|
|
6026
|
+
omitted: older iPhones' job picker, the office's "Clock X in") starts the day at that moment; an automatic
|
|
6027
|
+
clock-in is refused with NO_OPEN_DAY, because the fence crossing already records the arrival. A person starting
|
|
6028
|
+
their own job time away from the job's site, or with no usable location, is asked first (send canConfirmAway:
|
|
6029
|
+
409 JOB_TIME_AWAY carries the question; resend with confirmAway once they say yes) and the entry is flagged
|
|
6030
|
+
(startCheck) for the office to approve, move or not count. Older apps start straight away, flagged the same.
|
|
5654
6031
|
tags:
|
|
5655
6032
|
- time-tracking
|
|
5656
6033
|
parameters:
|
|
@@ -5674,6 +6051,10 @@ paths:
|
|
|
5674
6051
|
userId:
|
|
5675
6052
|
type: string
|
|
5676
6053
|
description: Clock someone else in. Requires time_tracking.edit_all.
|
|
6054
|
+
note:
|
|
6055
|
+
type: string
|
|
6056
|
+
maxLength: 2000
|
|
6057
|
+
description: Why, when clocking someone else in. Required with userId.
|
|
5677
6058
|
lat:
|
|
5678
6059
|
type: number
|
|
5679
6060
|
lng:
|
|
@@ -5683,6 +6064,11 @@ paths:
|
|
|
5683
6064
|
enum:
|
|
5684
6065
|
- manual
|
|
5685
6066
|
- auto
|
|
6067
|
+
startDay:
|
|
6068
|
+
type: boolean
|
|
6069
|
+
description: >-
|
|
6070
|
+
false: a job timer press, job time only; it never starts the paid day. Omitted: a Clock In press
|
|
6071
|
+
starts the day when none is running.
|
|
5686
6072
|
notes:
|
|
5687
6073
|
type: string
|
|
5688
6074
|
budgetItemId:
|
|
@@ -5692,7 +6078,10 @@ paths:
|
|
|
5692
6078
|
occurredAt:
|
|
5693
6079
|
type: string
|
|
5694
6080
|
format: date-time
|
|
5695
|
-
description:
|
|
6081
|
+
description: >-
|
|
6082
|
+
When the tech actually arrived, by the phone's clock. The server checks it against its own
|
|
6083
|
+
(tapElapsedMs) and clamps it. From the web (device 'web') it is ignored: the server's receipt time
|
|
6084
|
+
is used.
|
|
5696
6085
|
accuracyM:
|
|
5697
6086
|
type:
|
|
5698
6087
|
- number
|
|
@@ -5703,6 +6092,42 @@ paths:
|
|
|
5703
6092
|
- string
|
|
5704
6093
|
- 'null'
|
|
5705
6094
|
enum: *ref_5
|
|
6095
|
+
canConfirmAway:
|
|
6096
|
+
type: boolean
|
|
6097
|
+
description: >-
|
|
6098
|
+
This app can ask the person before starting job time away from the job (it handles 409
|
|
6099
|
+
JOB_TIME_AWAY).
|
|
6100
|
+
confirmAway:
|
|
6101
|
+
type: boolean
|
|
6102
|
+
description: The person said yes to starting away from the job.
|
|
6103
|
+
tapElapsedMs:
|
|
6104
|
+
type:
|
|
6105
|
+
- integer
|
|
6106
|
+
- 'null'
|
|
6107
|
+
minimum: 0
|
|
6108
|
+
description: >-
|
|
6109
|
+
Milliseconds from the tap to this send, from the phone's monotonic clock (a stopwatch the person
|
|
6110
|
+
can't change). An offline replay sends the time since the tap. The server's tap time is its own
|
|
6111
|
+
clock when the request arrives minus this. Within 2 minutes of the phone's time, the phone's time
|
|
6112
|
+
stands (never later than the tap); further apart, the server's tap time is recorded and the office
|
|
6113
|
+
is asked to look. A Clock Out or job time stop it proves this way keeps its real time however old;
|
|
6114
|
+
without it, a stop older than 12 hours is recorded at the 12-hour limit and flagged (T6). Send it
|
|
6115
|
+
with every queued tap, clock-outs included.
|
|
6116
|
+
tapTimeUnverified:
|
|
6117
|
+
type:
|
|
6118
|
+
- boolean
|
|
6119
|
+
- 'null'
|
|
6120
|
+
description: >-
|
|
6121
|
+
True when the phone restarted between the tap and this send, so there is no stopwatch reading (send
|
|
6122
|
+
no tapElapsedMs). A tap more than 2 minutes old keeps the phone's time and is flagged for the
|
|
6123
|
+
office.
|
|
6124
|
+
deviceClockChanged:
|
|
6125
|
+
type:
|
|
6126
|
+
- boolean
|
|
6127
|
+
- 'null'
|
|
6128
|
+
description: >-
|
|
6129
|
+
True when the phone's clock was changed by hand since the phone last synced. The tap is flagged for
|
|
6130
|
+
the office.
|
|
5706
6131
|
responses:
|
|
5707
6132
|
'201':
|
|
5708
6133
|
description: Entry opened.
|
|
@@ -5711,7 +6136,7 @@ paths:
|
|
|
5711
6136
|
schema:
|
|
5712
6137
|
$ref: '#/components/schemas/TimeEntry'
|
|
5713
6138
|
'400':
|
|
5714
|
-
description: Validation failure,
|
|
6139
|
+
description: Validation failure, jobId missing on a job clock-in, or no note when clocking someone else in.
|
|
5715
6140
|
content:
|
|
5716
6141
|
application/json:
|
|
5717
6142
|
schema:
|
|
@@ -5723,7 +6148,10 @@ paths:
|
|
|
5723
6148
|
schema:
|
|
5724
6149
|
$ref: '#/components/schemas/ErrorEnvelope'
|
|
5725
6150
|
'403':
|
|
5726
|
-
description:
|
|
6151
|
+
description: >-
|
|
6152
|
+
Time tracking access denied, or no organization on the session. PAYROLL_OFF: a Clock In press that would
|
|
6153
|
+
start the day at a company with the time tracking add-on off. JOB_TIME_OFF: the company has both the time
|
|
6154
|
+
tracking add-on and location tracking off, so job time isn't used; stopping running job time still works.
|
|
5727
6155
|
content:
|
|
5728
6156
|
application/json:
|
|
5729
6157
|
schema:
|
|
@@ -5736,8 +6164,13 @@ paths:
|
|
|
5736
6164
|
$ref: '#/components/schemas/ErrorEnvelope'
|
|
5737
6165
|
'409':
|
|
5738
6166
|
description: >-
|
|
5739
|
-
|
|
5740
|
-
|
|
6167
|
+
ALREADY_CLOCKED_IN_SAME_JOB: already at this site; the body carries the existing entry — adopt it.
|
|
6168
|
+
ALREADY_CLOCKED_IN_OTHER_JOB: an automatic clock-in while another entry is open; the body carries it.
|
|
6169
|
+
NO_OPEN_DAY: an automatic clock-in with no work day running; the fence crossing records the arrival.
|
|
6170
|
+
JOB_SITE_TRACKING_OFF: an automatic clock-in for someone the office turned job-site tracking off for; start
|
|
6171
|
+
job time by hand. PERIOD_LOCKED: an admin clock-in inside a locked pay period. JOB_TIME_AWAY: starting job
|
|
6172
|
+
time away from the job (reason 'away', with distanceM) or with no usable location (reason 'no_location');
|
|
6173
|
+
show message as the question and resend with confirmAway: true.
|
|
5741
6174
|
content:
|
|
5742
6175
|
application/json:
|
|
5743
6176
|
schema:
|
|
@@ -5749,10 +6182,22 @@ paths:
|
|
|
5749
6182
|
type: string
|
|
5750
6183
|
entry:
|
|
5751
6184
|
$ref: '#/components/schemas/TimeEntry'
|
|
6185
|
+
reason:
|
|
6186
|
+
type: string
|
|
6187
|
+
enum:
|
|
6188
|
+
- away
|
|
6189
|
+
- no_location
|
|
6190
|
+
distanceM:
|
|
6191
|
+
type:
|
|
6192
|
+
- integer
|
|
6193
|
+
- 'null'
|
|
6194
|
+
jobName:
|
|
6195
|
+
type:
|
|
6196
|
+
- string
|
|
6197
|
+
- 'null'
|
|
5752
6198
|
required:
|
|
5753
6199
|
- message
|
|
5754
6200
|
- code
|
|
5755
|
-
- entry
|
|
5756
6201
|
'426':
|
|
5757
6202
|
description: Client major below minClientVersion.
|
|
5758
6203
|
content:
|
|
@@ -5798,7 +6243,10 @@ paths:
|
|
|
5798
6243
|
occurredAt:
|
|
5799
6244
|
type: string
|
|
5800
6245
|
format: date-time
|
|
5801
|
-
description:
|
|
6246
|
+
description: >-
|
|
6247
|
+
When the tech actually left, by the phone's clock. Checked against the server's (tapElapsedMs) and
|
|
6248
|
+
clamped to [entry.clockIn, now], and to the last 12 hours unless tapElapsedMs proves it (T6). From
|
|
6249
|
+
the web (device 'web') it is ignored: the server's receipt time is used.
|
|
5802
6250
|
accuracyM:
|
|
5803
6251
|
type:
|
|
5804
6252
|
- number
|
|
@@ -5809,9 +6257,39 @@ paths:
|
|
|
5809
6257
|
- string
|
|
5810
6258
|
- 'null'
|
|
5811
6259
|
enum: *ref_5
|
|
6260
|
+
tapElapsedMs:
|
|
6261
|
+
type:
|
|
6262
|
+
- integer
|
|
6263
|
+
- 'null'
|
|
6264
|
+
minimum: 0
|
|
6265
|
+
description: >-
|
|
6266
|
+
Milliseconds from the tap to this send, from the phone's monotonic clock (a stopwatch the person
|
|
6267
|
+
can't change). An offline replay sends the time since the tap. The server's tap time is its own
|
|
6268
|
+
clock when the request arrives minus this. Within 2 minutes of the phone's time, the phone's time
|
|
6269
|
+
stands (never later than the tap); further apart, the server's tap time is recorded and the office
|
|
6270
|
+
is asked to look. A Clock Out or job time stop it proves this way keeps its real time however old;
|
|
6271
|
+
without it, a stop older than 12 hours is recorded at the 12-hour limit and flagged (T6). Send it
|
|
6272
|
+
with every queued tap, clock-outs included.
|
|
6273
|
+
tapTimeUnverified:
|
|
6274
|
+
type:
|
|
6275
|
+
- boolean
|
|
6276
|
+
- 'null'
|
|
6277
|
+
description: >-
|
|
6278
|
+
True when the phone restarted between the tap and this send, so there is no stopwatch reading (send
|
|
6279
|
+
no tapElapsedMs). A tap more than 2 minutes old keeps the phone's time and is flagged for the
|
|
6280
|
+
office.
|
|
6281
|
+
deviceClockChanged:
|
|
6282
|
+
type:
|
|
6283
|
+
- boolean
|
|
6284
|
+
- 'null'
|
|
6285
|
+
description: >-
|
|
6286
|
+
True when the phone's clock was changed by hand since the phone last synced. The tap is flagged for
|
|
6287
|
+
the office.
|
|
5812
6288
|
responses:
|
|
5813
6289
|
'200':
|
|
5814
|
-
description:
|
|
6290
|
+
description: >-
|
|
6291
|
+
Entry closed; or, for a stop tapElapsedMs proves that is earlier than the automatic close of the job time
|
|
6292
|
+
there, that close replaced (T6).
|
|
5815
6293
|
content:
|
|
5816
6294
|
application/json:
|
|
5817
6295
|
schema:
|
|
@@ -5835,7 +6313,9 @@ paths:
|
|
|
5835
6313
|
schema:
|
|
5836
6314
|
$ref: '#/components/schemas/ErrorEnvelope'
|
|
5837
6315
|
'404':
|
|
5838
|
-
description:
|
|
6316
|
+
description: >-
|
|
6317
|
+
No open entry at that site. Also when the stop belongs to job time the safety net closed and was only
|
|
6318
|
+
flagged for the office.
|
|
5839
6319
|
content:
|
|
5840
6320
|
application/json:
|
|
5841
6321
|
schema:
|
|
@@ -5851,7 +6331,13 @@ paths:
|
|
|
5851
6331
|
summary: Move my clock to another job in one atomic call.
|
|
5852
6332
|
description: >-
|
|
5853
6333
|
Closes the caller's open entry and opens one on the target. One request instead of clock-out + clock-in, so an
|
|
5854
|
-
offline drop between the two cannot strand the tech clocked out. Own entry only.
|
|
6334
|
+
offline drop between the two cannot strand the tech clocked out. Own entry only. Moving job time to a job the
|
|
6335
|
+
person isn't at, or with no usable location, is asked first (send canConfirmAway: 409 JOB_TIME_AWAY carries the
|
|
6336
|
+
question; resend with confirmAway once they say yes) and the new entry is flagged (startCheck) for the office.
|
|
6337
|
+
Older apps move straight away, flagged the same. switchAt is a time the person picked, so earlier than the tap
|
|
6338
|
+
is normal. With tapElapsedMs it is never later than the tap by the server's clock, and more than 2 minutes later
|
|
6339
|
+
is replaced by the tap time and flagged (opened.clockInCheck). tapTimeUnverified doesn't apply;
|
|
6340
|
+
deviceClockChanged flags it.
|
|
5855
6341
|
tags:
|
|
5856
6342
|
- time-tracking
|
|
5857
6343
|
parameters:
|
|
@@ -5874,6 +6360,47 @@ paths:
|
|
|
5874
6360
|
type: number
|
|
5875
6361
|
lng:
|
|
5876
6362
|
type: number
|
|
6363
|
+
accuracyM:
|
|
6364
|
+
type:
|
|
6365
|
+
- number
|
|
6366
|
+
- 'null'
|
|
6367
|
+
minimum: 0
|
|
6368
|
+
canConfirmAway:
|
|
6369
|
+
type: boolean
|
|
6370
|
+
description: >-
|
|
6371
|
+
This app can ask the person before moving job time to a job they aren't at (it handles 409
|
|
6372
|
+
JOB_TIME_AWAY).
|
|
6373
|
+
confirmAway:
|
|
6374
|
+
type: boolean
|
|
6375
|
+
description: The person said yes to moving it anyway.
|
|
6376
|
+
tapElapsedMs:
|
|
6377
|
+
type:
|
|
6378
|
+
- integer
|
|
6379
|
+
- 'null'
|
|
6380
|
+
minimum: 0
|
|
6381
|
+
description: >-
|
|
6382
|
+
Milliseconds from the tap to this send, from the phone's monotonic clock (a stopwatch the person
|
|
6383
|
+
can't change). An offline replay sends the time since the tap. The server's tap time is its own
|
|
6384
|
+
clock when the request arrives minus this. Within 2 minutes of the phone's time, the phone's time
|
|
6385
|
+
stands (never later than the tap); further apart, the server's tap time is recorded and the office
|
|
6386
|
+
is asked to look. A Clock Out or job time stop it proves this way keeps its real time however old;
|
|
6387
|
+
without it, a stop older than 12 hours is recorded at the 12-hour limit and flagged (T6). Send it
|
|
6388
|
+
with every queued tap, clock-outs included.
|
|
6389
|
+
tapTimeUnverified:
|
|
6390
|
+
type:
|
|
6391
|
+
- boolean
|
|
6392
|
+
- 'null'
|
|
6393
|
+
description: >-
|
|
6394
|
+
True when the phone restarted between the tap and this send, so there is no stopwatch reading (send
|
|
6395
|
+
no tapElapsedMs). A tap more than 2 minutes old keeps the phone's time and is flagged for the
|
|
6396
|
+
office.
|
|
6397
|
+
deviceClockChanged:
|
|
6398
|
+
type:
|
|
6399
|
+
- boolean
|
|
6400
|
+
- 'null'
|
|
6401
|
+
description: >-
|
|
6402
|
+
True when the phone's clock was changed by hand since the phone last synced. The tap is flagged for
|
|
6403
|
+
the office.
|
|
5877
6404
|
required:
|
|
5878
6405
|
- targetJobId
|
|
5879
6406
|
responses:
|
|
@@ -5907,7 +6434,9 @@ paths:
|
|
|
5907
6434
|
schema:
|
|
5908
6435
|
$ref: '#/components/schemas/ErrorEnvelope'
|
|
5909
6436
|
'403':
|
|
5910
|
-
description:
|
|
6437
|
+
description: >-
|
|
6438
|
+
Time tracking access denied, or no organization on the session. JOB_TIME_OFF: the company has both the time
|
|
6439
|
+
tracking add-on and location tracking off, so job time isn't used; stopping running job time still works.
|
|
5911
6440
|
content:
|
|
5912
6441
|
application/json:
|
|
5913
6442
|
schema:
|
|
@@ -5918,6 +6447,36 @@ paths:
|
|
|
5918
6447
|
application/json:
|
|
5919
6448
|
schema:
|
|
5920
6449
|
$ref: '#/components/schemas/ErrorEnvelope'
|
|
6450
|
+
'409':
|
|
6451
|
+
description: >-
|
|
6452
|
+
PERIOD_LOCKED: the switch time is inside a locked pay period. JOB_TIME_AWAY: the person isn't at the target
|
|
6453
|
+
job (reason 'away', with distanceM) or has no usable location (reason 'no_location'); nothing moved. Show
|
|
6454
|
+
message as the question and resend with confirmAway: true.
|
|
6455
|
+
content:
|
|
6456
|
+
application/json:
|
|
6457
|
+
schema:
|
|
6458
|
+
type: object
|
|
6459
|
+
properties:
|
|
6460
|
+
message:
|
|
6461
|
+
type: string
|
|
6462
|
+
code:
|
|
6463
|
+
type: string
|
|
6464
|
+
reason:
|
|
6465
|
+
type: string
|
|
6466
|
+
enum:
|
|
6467
|
+
- away
|
|
6468
|
+
- no_location
|
|
6469
|
+
distanceM:
|
|
6470
|
+
type:
|
|
6471
|
+
- integer
|
|
6472
|
+
- 'null'
|
|
6473
|
+
jobName:
|
|
6474
|
+
type:
|
|
6475
|
+
- string
|
|
6476
|
+
- 'null'
|
|
6477
|
+
required:
|
|
6478
|
+
- message
|
|
6479
|
+
- code
|
|
5921
6480
|
'426':
|
|
5922
6481
|
description: Client major below minClientVersion.
|
|
5923
6482
|
content:
|
|
@@ -6174,7 +6733,10 @@ paths:
|
|
|
6174
6733
|
schema:
|
|
6175
6734
|
$ref: '#/components/schemas/ErrorEnvelope'
|
|
6176
6735
|
'403':
|
|
6177
|
-
description:
|
|
6736
|
+
description: >-
|
|
6737
|
+
Time tracking access denied, no organization on the session, or code PAYROLL_OFF: the company has the time
|
|
6738
|
+
tracking add-on off (GET /api/time-tracking/day says payrollAddon: false). Don't retry; hide Clock In/Out
|
|
6739
|
+
and the other payroll controls.
|
|
6178
6740
|
content:
|
|
6179
6741
|
application/json:
|
|
6180
6742
|
schema:
|
|
@@ -6342,6 +6904,15 @@ paths:
|
|
|
6342
6904
|
application/json:
|
|
6343
6905
|
schema:
|
|
6344
6906
|
$ref: '#/components/schemas/ErrorEnvelope'
|
|
6907
|
+
'403':
|
|
6908
|
+
description: >-
|
|
6909
|
+
Time tracking access denied, no organization on the session, or code PAYROLL_OFF: the company has the time
|
|
6910
|
+
tracking add-on off (GET /api/time-tracking/day says payrollAddon: false). Don't retry; hide Clock In/Out
|
|
6911
|
+
and the other payroll controls.
|
|
6912
|
+
content:
|
|
6913
|
+
application/json:
|
|
6914
|
+
schema:
|
|
6915
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
6345
6916
|
'409':
|
|
6346
6917
|
description: A request for those dates is already waiting.
|
|
6347
6918
|
content:
|
|
@@ -6354,4 +6925,114 @@ paths:
|
|
|
6354
6925
|
application/json:
|
|
6355
6926
|
schema:
|
|
6356
6927
|
$ref: '#/components/schemas/UpgradeRequiredEnvelope'
|
|
6928
|
+
/api/account/deletion-request:
|
|
6929
|
+
post:
|
|
6930
|
+
summary: Ask for my account to be deleted.
|
|
6931
|
+
description: >-
|
|
6932
|
+
Nothing is deleted by this call. The request goes to the company's owner and Team admins (bell, push and email)
|
|
6933
|
+
and to ServiceAi support (email); the company removes the account. Asking again while a request is pending
|
|
6934
|
+
answers that request with 200 and creates nothing; everyone is reminded at most once a day. The reason is never
|
|
6935
|
+
put in a push.
|
|
6936
|
+
tags:
|
|
6937
|
+
- account
|
|
6938
|
+
parameters:
|
|
6939
|
+
- *ref_3
|
|
6940
|
+
requestBody:
|
|
6941
|
+
content:
|
|
6942
|
+
application/json:
|
|
6943
|
+
schema:
|
|
6944
|
+
type: object
|
|
6945
|
+
properties:
|
|
6946
|
+
reason:
|
|
6947
|
+
type:
|
|
6948
|
+
- string
|
|
6949
|
+
- 'null'
|
|
6950
|
+
maxLength: 1000
|
|
6951
|
+
description: Optional. Trimmed; at most 1000 characters after trimming.
|
|
6952
|
+
responses:
|
|
6953
|
+
'200':
|
|
6954
|
+
description: 'A request was already pending: this is that request.'
|
|
6955
|
+
content:
|
|
6956
|
+
application/json:
|
|
6957
|
+
schema:
|
|
6958
|
+
$ref: '#/components/schemas/AccountDeletionRequest'
|
|
6959
|
+
'202':
|
|
6960
|
+
description: Request created.
|
|
6961
|
+
content:
|
|
6962
|
+
application/json:
|
|
6963
|
+
schema:
|
|
6964
|
+
$ref: '#/components/schemas/AccountDeletionRequest'
|
|
6965
|
+
'400':
|
|
6966
|
+
description: Validation failure (a reason longer than 1000 characters).
|
|
6967
|
+
content:
|
|
6968
|
+
application/json:
|
|
6969
|
+
schema:
|
|
6970
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
6971
|
+
'401':
|
|
6972
|
+
description: Not signed in.
|
|
6973
|
+
content:
|
|
6974
|
+
application/json:
|
|
6975
|
+
schema:
|
|
6976
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
6977
|
+
'403':
|
|
6978
|
+
description: No organization on the session, or viewing the app as someone else.
|
|
6979
|
+
content:
|
|
6980
|
+
application/json:
|
|
6981
|
+
schema:
|
|
6982
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
6983
|
+
'426':
|
|
6984
|
+
description: Client major below minClientVersion.
|
|
6985
|
+
content:
|
|
6986
|
+
application/json:
|
|
6987
|
+
schema:
|
|
6988
|
+
$ref: '#/components/schemas/UpgradeRequiredEnvelope'
|
|
6989
|
+
'429':
|
|
6990
|
+
description: Too many requests from this person; try again later.
|
|
6991
|
+
content:
|
|
6992
|
+
application/json:
|
|
6993
|
+
schema:
|
|
6994
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
6995
|
+
get:
|
|
6996
|
+
summary: My newest account deletion request.
|
|
6997
|
+
tags:
|
|
6998
|
+
- account
|
|
6999
|
+
parameters:
|
|
7000
|
+
- *ref_3
|
|
7001
|
+
responses:
|
|
7002
|
+
'200':
|
|
7003
|
+
description: The newest request, whatever its status.
|
|
7004
|
+
content:
|
|
7005
|
+
application/json:
|
|
7006
|
+
schema:
|
|
7007
|
+
$ref: '#/components/schemas/AccountDeletionRequest'
|
|
7008
|
+
'401':
|
|
7009
|
+
description: Not signed in.
|
|
7010
|
+
content:
|
|
7011
|
+
application/json:
|
|
7012
|
+
schema:
|
|
7013
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
7014
|
+
'403':
|
|
7015
|
+
description: No organization on the session.
|
|
7016
|
+
content:
|
|
7017
|
+
application/json:
|
|
7018
|
+
schema:
|
|
7019
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
7020
|
+
'404':
|
|
7021
|
+
description: No request yet.
|
|
7022
|
+
content:
|
|
7023
|
+
application/json:
|
|
7024
|
+
schema:
|
|
7025
|
+
type: object
|
|
7026
|
+
properties:
|
|
7027
|
+
message:
|
|
7028
|
+
type: string
|
|
7029
|
+
example: No deletion request
|
|
7030
|
+
required:
|
|
7031
|
+
- message
|
|
7032
|
+
'426':
|
|
7033
|
+
description: Client major below minClientVersion.
|
|
7034
|
+
content:
|
|
7035
|
+
application/json:
|
|
7036
|
+
schema:
|
|
7037
|
+
$ref: '#/components/schemas/UpgradeRequiredEnvelope'
|
|
6357
7038
|
webhooks: {}
|