clockify_detailed_reports_api_docs 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +56 -0
- data/LICENSE.txt +21 -0
- data/README.md +222 -0
- data/docs/Clockify_API_Complete.md +939 -0
- data/docs/Clockify_API_Google_Doc_Internal.md +734 -0
- data/docs/Clockify_API_User_Guide.md +353 -0
- data/lib/clockify_api_docs/documentation.rb +243 -0
- data/lib/clockify_api_docs/version.rb +5 -0
- data/lib/clockify_api_docs.rb +52 -0
- metadata +103 -0
|
@@ -0,0 +1,939 @@
|
|
|
1
|
+
# 📚 Clockify Detailed Reports API - Complete Reference
|
|
2
|
+
|
|
3
|
+
## 🔗 **Endpoint**
|
|
4
|
+
```
|
|
5
|
+
POST https://reports.api.clockify.me/v1/workspaces/{workspaceId}/reports/detailed
|
|
6
|
+
```
|
|
7
|
+
**Authentication**: `X-Api-Key: YOUR_API_KEY`
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## ⚡ **Quick Start (Minimal Required Call)**
|
|
12
|
+
```json
|
|
13
|
+
{
|
|
14
|
+
"dateRangeStart": "2024-01-01T00:00:00.000Z",
|
|
15
|
+
"dateRangeEnd": "2024-12-31T23:59:59.999Z",
|
|
16
|
+
"detailedFilter": {
|
|
17
|
+
"page": 1,
|
|
18
|
+
"pageSize": 100
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## 🎯 **Complete API Call Example (All Parameters)**
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
{
|
|
29
|
+
"dateRangeStart": "2024-01-01T00:00:00.000Z",
|
|
30
|
+
"dateRangeEnd": "2024-12-31T23:59:59.999Z",
|
|
31
|
+
|
|
32
|
+
"detailedFilter": {
|
|
33
|
+
"page": 1,
|
|
34
|
+
"pageSize": 100,
|
|
35
|
+
"sortColumn": "DATE",
|
|
36
|
+
"auditFilter": {
|
|
37
|
+
"duration": 300,
|
|
38
|
+
"durationShorter": true,
|
|
39
|
+
"withoutProject": false,
|
|
40
|
+
"withoutTask": false
|
|
41
|
+
},
|
|
42
|
+
"options": {
|
|
43
|
+
"totals": "CALCULATE"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
|
|
47
|
+
"amountShown": "EARNED",
|
|
48
|
+
"amounts": ["EARNED", "COST", "PROFIT"],
|
|
49
|
+
"invoicingState": "UNINVOICED",
|
|
50
|
+
"sortOrder": "DESCENDING",
|
|
51
|
+
"exportType": "JSON",
|
|
52
|
+
"zoomLevel": "MONTH",
|
|
53
|
+
|
|
54
|
+
"billable": true,
|
|
55
|
+
"description": "client meeting",
|
|
56
|
+
"approvalState": "APPROVED",
|
|
57
|
+
"archived": false,
|
|
58
|
+
"rounding": true,
|
|
59
|
+
"withoutDescription": false,
|
|
60
|
+
|
|
61
|
+
"clients": {
|
|
62
|
+
"contains": "CONTAINS",
|
|
63
|
+
"ids": ["client_id_1"],
|
|
64
|
+
"status": "ACTIVE"
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
"projects": {
|
|
68
|
+
"contains": "CONTAINS",
|
|
69
|
+
"ids": ["project_id_1"],
|
|
70
|
+
"status": "ACTIVE"
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
"users": {
|
|
74
|
+
"contains": "CONTAINS",
|
|
75
|
+
"ids": ["user_id_1"],
|
|
76
|
+
"status": "ACTIVE"
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
"userGroups": {
|
|
80
|
+
"contains": "CONTAINS",
|
|
81
|
+
"ids": ["group_id_1"],
|
|
82
|
+
"status": "ACTIVE"
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
"tags": {
|
|
86
|
+
"containedInTimeentry": "CONTAINS",
|
|
87
|
+
"contains": "CONTAINS",
|
|
88
|
+
"ids": ["tag_id_1"],
|
|
89
|
+
"status": "ACTIVE"
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
"tasks": {
|
|
93
|
+
"contains": "CONTAINS",
|
|
94
|
+
"ids": ["task_id_1"],
|
|
95
|
+
"status": "ACTIVE"
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
"currency": {
|
|
99
|
+
"contains": "CONTAINS",
|
|
100
|
+
"ids": ["USD"],
|
|
101
|
+
"status": "ACTIVE"
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
"attendanceFilter": {
|
|
105
|
+
"page": 1,
|
|
106
|
+
"pageSize": 201,
|
|
107
|
+
"sortColumn": "USER",
|
|
108
|
+
"hasTimeOff": true,
|
|
109
|
+
"workFilters": [
|
|
110
|
+
{
|
|
111
|
+
"filtrationType": "LARGER_THAN",
|
|
112
|
+
"value": "480"
|
|
113
|
+
}
|
|
114
|
+
],
|
|
115
|
+
"startFilters": [
|
|
116
|
+
{
|
|
117
|
+
"filtrationType": "LARGER_THAN",
|
|
118
|
+
"value": "09:00"
|
|
119
|
+
}
|
|
120
|
+
],
|
|
121
|
+
"endFilters": [
|
|
122
|
+
{
|
|
123
|
+
"filtrationType": "SMALLER_THAN",
|
|
124
|
+
"value": "17:00"
|
|
125
|
+
}
|
|
126
|
+
],
|
|
127
|
+
"breakFilters": [
|
|
128
|
+
{
|
|
129
|
+
"filtrationType": "SMALLER_THAN",
|
|
130
|
+
"value": "120"
|
|
131
|
+
}
|
|
132
|
+
],
|
|
133
|
+
"capacityFilters": [
|
|
134
|
+
{
|
|
135
|
+
"filtrationType": "EXACTLY",
|
|
136
|
+
"value": "800"
|
|
137
|
+
}
|
|
138
|
+
],
|
|
139
|
+
"overtimeFilters": [
|
|
140
|
+
{
|
|
141
|
+
"filtrationType": "LARGER_THAN",
|
|
142
|
+
"value": "100"
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
"summaryFilter": {
|
|
148
|
+
"groups": ["PROJECT", "CLIENT"],
|
|
149
|
+
"sortColumn": "DURATION",
|
|
150
|
+
"summaryChartType": "PROJECT"
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
"weeklyFilter": {
|
|
154
|
+
"group": "weekly_group_id",
|
|
155
|
+
"subgroup": "weekly_subgroup_id"
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
"customFields": [
|
|
159
|
+
{
|
|
160
|
+
"id": "custom_field_id",
|
|
161
|
+
"type": "TXT",
|
|
162
|
+
"isEmpty": false,
|
|
163
|
+
"value": "custom_value"
|
|
164
|
+
}
|
|
165
|
+
],
|
|
166
|
+
|
|
167
|
+
"timeZone": "America/New_York",
|
|
168
|
+
"dateFormat": "YYYY-MM-DD",
|
|
169
|
+
"timeFormat": "THH:MM:SS.ssssss",
|
|
170
|
+
"weekStart": "MONDAY",
|
|
171
|
+
"userLocale": "en-US"
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## 📝 **Complete Parameters Guide**
|
|
178
|
+
|
|
179
|
+
### 🔴 **Required Parameters (Always Include These)**
|
|
180
|
+
|
|
181
|
+
#### **dateRangeStart & dateRangeEnd**
|
|
182
|
+
```json
|
|
183
|
+
{
|
|
184
|
+
"dateRangeStart": "2024-01-01T00:00:00.000Z",
|
|
185
|
+
"dateRangeEnd": "2024-12-31T23:59:59.999Z"
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
- **Format**: Must be exact ISO 8601 format `YYYY-MM-DDTHH:MM:SS.sssZ`
|
|
189
|
+
- **Time zone**: Always use `.000Z` for UTC
|
|
190
|
+
- **Logic**: End date must be after start date
|
|
191
|
+
- **Limits**: FREE plan limited to 366 days maximum
|
|
192
|
+
- **Examples**:
|
|
193
|
+
- Start of day: `"2024-01-01T00:00:00.000Z"`
|
|
194
|
+
- End of day: `"2024-01-31T23:59:59.999Z"`
|
|
195
|
+
|
|
196
|
+
#### **detailedFilter (Required Object)**
|
|
197
|
+
```json
|
|
198
|
+
{
|
|
199
|
+
"detailedFilter": {
|
|
200
|
+
"page": 1,
|
|
201
|
+
"pageSize": 100,
|
|
202
|
+
"sortColumn": "DATE"
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
```
|
|
206
|
+
- **page**: Page number (starts at 1, 0 treated as 1, negative treated as 1)
|
|
207
|
+
- **pageSize**: Items per page (1-1000, 0 returns ALL data - dangerous!)
|
|
208
|
+
- **sortColumn**: Optional sorting (see sort options below)
|
|
209
|
+
|
|
210
|
+
**detailedFilter Sort Options**:
|
|
211
|
+
- `"DATE"` - Sort by date
|
|
212
|
+
- `"USER"` - Sort by user name
|
|
213
|
+
- `"DURATION"` - Sort by time length
|
|
214
|
+
- `"DESCRIPTION"` - Sort by description text
|
|
215
|
+
- `"ID"` - Sort by entry ID
|
|
216
|
+
- `"NATURAL"` - Natural ordering
|
|
217
|
+
- `"USER_DATE"` - Sort by user then date
|
|
218
|
+
|
|
219
|
+
**⚠️ Critical**: Empty string `""` in sortColumn causes server crash!
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
### 💰 **Financial Parameters**
|
|
224
|
+
|
|
225
|
+
#### **amountShown (Single Amount Type)**
|
|
226
|
+
```json
|
|
227
|
+
{ "amountShown": "EARNED" }
|
|
228
|
+
```
|
|
229
|
+
- `"EARNED"` - Revenue from billable time (client perspective)
|
|
230
|
+
- `"COST"` - Internal costs/payroll (company perspective)
|
|
231
|
+
- `"PROFIT"` - Earned minus cost (profit analysis)
|
|
232
|
+
- `"HIDE_AMOUNT"` - No financial data in response
|
|
233
|
+
- `"EXPORT"` - For file exports
|
|
234
|
+
|
|
235
|
+
**⚠️ Critical**: Empty string `""` causes server crash!
|
|
236
|
+
|
|
237
|
+
#### **amounts (Multiple Amount Types)**
|
|
238
|
+
```json
|
|
239
|
+
{ "amounts": ["EARNED", "COST", "PROFIT"] }
|
|
240
|
+
```
|
|
241
|
+
- **Usage**: More efficient than multiple API calls
|
|
242
|
+
- **Conflict**: If both `amountShown` and `amounts` used, `amounts` takes precedence
|
|
243
|
+
- **Values**: Same options as `amountShown`
|
|
244
|
+
|
|
245
|
+
#### **invoicingState (Billing Workflow)**
|
|
246
|
+
```json
|
|
247
|
+
{ "invoicingState": "UNINVOICED" }
|
|
248
|
+
```
|
|
249
|
+
- `"UNINVOICED"` - Time not yet billed to clients
|
|
250
|
+
- `"INVOICED"` - Time already invoiced
|
|
251
|
+
- `"ALL"` - All time regardless of invoice status
|
|
252
|
+
|
|
253
|
+
**Use Case**: Generate monthly invoices by filtering uninvoiced billable time
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
### 📊 **Display & Output Parameters**
|
|
258
|
+
|
|
259
|
+
#### **sortOrder (Result Ordering)**
|
|
260
|
+
```json
|
|
261
|
+
{ "sortOrder": "DESCENDING" }
|
|
262
|
+
```
|
|
263
|
+
- `"ASCENDING"` - Oldest first, A-Z, smallest first
|
|
264
|
+
- `"DESCENDING"` - Newest first, Z-A, largest first
|
|
265
|
+
|
|
266
|
+
#### **exportType (Output Format)**
|
|
267
|
+
```json
|
|
268
|
+
{ "exportType": "XLSX" }
|
|
269
|
+
```
|
|
270
|
+
- `"JSON"` - Default, for programming
|
|
271
|
+
- `"JSON_V1"` - Legacy JSON format
|
|
272
|
+
- `"CSV"` - Excel/Google Sheets compatible
|
|
273
|
+
- `"XLSX"` - Excel file format
|
|
274
|
+
- `"PDF"` - Formatted report
|
|
275
|
+
- `"ZIP"` - Compressed archive
|
|
276
|
+
|
|
277
|
+
**⚠️ Gotchas**:
|
|
278
|
+
- Empty string `""` causes server crash!
|
|
279
|
+
- Lowercase `"csv"` works but returns CSV data instead of JSON (breaks parsing)
|
|
280
|
+
- Non-JSON formats return binary data, not JSON responses
|
|
281
|
+
|
|
282
|
+
#### **zoomLevel (Aggregation)**
|
|
283
|
+
```json
|
|
284
|
+
{ "zoomLevel": "MONTH" }
|
|
285
|
+
```
|
|
286
|
+
- `"WEEK"` - Weekly aggregation
|
|
287
|
+
- `"MONTH"` - Monthly aggregation
|
|
288
|
+
- `"YEAR"` - Yearly aggregation
|
|
289
|
+
|
|
290
|
+
**Use Case**: High-level reporting and trend analysis
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
### 🎛️ **Basic Content Filters**
|
|
295
|
+
|
|
296
|
+
#### **billable (Billable Status)**
|
|
297
|
+
```json
|
|
298
|
+
{ "billable": true }
|
|
299
|
+
```
|
|
300
|
+
- `true` - Only billable time (client work)
|
|
301
|
+
- `false` - Only non-billable time (internal work)
|
|
302
|
+
- Omit - All time entries
|
|
303
|
+
|
|
304
|
+
**Business Impact**: Critical for separating client billing from internal operations
|
|
305
|
+
|
|
306
|
+
#### **description (Text Search)**
|
|
307
|
+
```json
|
|
308
|
+
{ "description": "meeting" }
|
|
309
|
+
```
|
|
310
|
+
- **Search**: Case-insensitive text search within descriptions
|
|
311
|
+
- **Examples**: `"bug"` finds "Bug fix", "Debug issue"
|
|
312
|
+
- **Use Case**: Track specific activity types across projects
|
|
313
|
+
|
|
314
|
+
#### **approvalState (Approval Workflow)**
|
|
315
|
+
```json
|
|
316
|
+
{ "approvalState": "APPROVED" }
|
|
317
|
+
```
|
|
318
|
+
- `"APPROVED"` - Manager-approved time entries
|
|
319
|
+
- `"UNAPPROVED"` - Pending approval
|
|
320
|
+
- `"ALL"` - All entries regardless of approval
|
|
321
|
+
|
|
322
|
+
**When to use**: Organizations with time entry approval processes
|
|
323
|
+
|
|
324
|
+
#### **archived (Include Archived Items)**
|
|
325
|
+
```json
|
|
326
|
+
{ "archived": false }
|
|
327
|
+
```
|
|
328
|
+
- `false` - Only active items (default)
|
|
329
|
+
- `true` - Include archived projects/clients
|
|
330
|
+
|
|
331
|
+
#### **rounding (Time Rounding Rules)**
|
|
332
|
+
```json
|
|
333
|
+
{ "rounding": true }
|
|
334
|
+
```
|
|
335
|
+
- `true` - Apply workspace time rounding rules (15min, 30min, etc.)
|
|
336
|
+
- `false` - Exact time values
|
|
337
|
+
|
|
338
|
+
**Use Case**: Organizations that bill in rounded time increments
|
|
339
|
+
|
|
340
|
+
#### **withoutDescription (Quality Control)**
|
|
341
|
+
```json
|
|
342
|
+
{ "withoutDescription": true }
|
|
343
|
+
```
|
|
344
|
+
- `true` - Only entries with empty/missing descriptions
|
|
345
|
+
- `false` - Only entries with descriptions
|
|
346
|
+
|
|
347
|
+
**Use Case**: Data quality audits to find incomplete time entries
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
### 👥 **Entity Relationship Filters**
|
|
352
|
+
|
|
353
|
+
All entity filters use the same structure pattern:
|
|
354
|
+
|
|
355
|
+
#### **clients (Client Filter)**
|
|
356
|
+
```json
|
|
357
|
+
{
|
|
358
|
+
"clients": {
|
|
359
|
+
"contains": "CONTAINS",
|
|
360
|
+
"ids": ["client_id_1", "client_id_2"],
|
|
361
|
+
"status": "ACTIVE"
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
#### **projects (Project Filter)**
|
|
367
|
+
```json
|
|
368
|
+
{
|
|
369
|
+
"projects": {
|
|
370
|
+
"contains": "CONTAINS",
|
|
371
|
+
"ids": ["project_id_1", "project_id_2"],
|
|
372
|
+
"status": "ACTIVE"
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
#### **users (User Filter)**
|
|
378
|
+
```json
|
|
379
|
+
{
|
|
380
|
+
"users": {
|
|
381
|
+
"contains": "CONTAINS",
|
|
382
|
+
"ids": ["user_id_1", "user_id_2"],
|
|
383
|
+
"status": "ACTIVE"
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
#### **userGroups (Team/Department Filter)**
|
|
389
|
+
```json
|
|
390
|
+
{
|
|
391
|
+
"userGroups": {
|
|
392
|
+
"contains": "CONTAINS",
|
|
393
|
+
"ids": ["team_id_1", "team_id_2"],
|
|
394
|
+
"status": "ACTIVE"
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
**userGroups Use Cases**:
|
|
400
|
+
- Department reporting (Engineering, Marketing, Sales)
|
|
401
|
+
- Location-based analysis (Remote vs Office)
|
|
402
|
+
- Role-based filtering (Managers vs Individual Contributors)
|
|
403
|
+
- Project team comparisons
|
|
404
|
+
- Cost center analysis
|
|
405
|
+
|
|
406
|
+
#### **tags (Tag Filter - Special Structure)**
|
|
407
|
+
```json
|
|
408
|
+
{
|
|
409
|
+
"tags": {
|
|
410
|
+
"containedInTimeentry": "CONTAINS",
|
|
411
|
+
"contains": "CONTAINS",
|
|
412
|
+
"ids": ["tag_id_1", "tag_id_2"],
|
|
413
|
+
"status": "ACTIVE"
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
**Special Field**: `containedInTimeentry` controls how tags relate to time entries
|
|
419
|
+
|
|
420
|
+
#### **tasks (Task Filter)**
|
|
421
|
+
```json
|
|
422
|
+
{
|
|
423
|
+
"tasks": {
|
|
424
|
+
"contains": "CONTAINS",
|
|
425
|
+
"ids": ["task_id_1", "task_id_2"],
|
|
426
|
+
"status": "ACTIVE"
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
**Use Case**: Task-level time tracking analysis within projects
|
|
432
|
+
|
|
433
|
+
#### **currency (Multi-Currency Filter)**
|
|
434
|
+
```json
|
|
435
|
+
{
|
|
436
|
+
"currency": {
|
|
437
|
+
"contains": "CONTAINS",
|
|
438
|
+
"ids": ["USD", "EUR", "GBP"],
|
|
439
|
+
"status": "ACTIVE"
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
**Use Case**: International teams with multi-currency workspaces
|
|
445
|
+
|
|
446
|
+
**Entity Filter Options Explained**:
|
|
447
|
+
|
|
448
|
+
**contains** (Relationship Type):
|
|
449
|
+
- `"CONTAINS"` - Include entries that have any of these entities
|
|
450
|
+
- `"DOES_NOT_CONTAIN"` - Exclude entries that have these entities
|
|
451
|
+
- `"CONTAINS_ONLY"` - Only entries that have exactly these entities (stricter)
|
|
452
|
+
|
|
453
|
+
**status** (Entity Status):
|
|
454
|
+
- `"ACTIVE"` - Only currently active entities
|
|
455
|
+
- `"ARCHIVED"` - Only archived/deleted entities
|
|
456
|
+
- `"ALL"` - Both active and archived entities
|
|
457
|
+
|
|
458
|
+
**ids** (Entity Selection):
|
|
459
|
+
- Empty array `[]` - Include all entities of this type
|
|
460
|
+
- Specific IDs `["id1", "id2"]` - Only these specific entities
|
|
461
|
+
- `[null]` - Works (null values ignored)
|
|
462
|
+
|
|
463
|
+
---
|
|
464
|
+
|
|
465
|
+
### 🎯 **AttendanceFilter (Workforce Analytics)**
|
|
466
|
+
|
|
467
|
+
> **🚨 CRITICAL CONCEPT**: AttendanceFilter works on **DAILY PATTERNS**, not individual entries!
|
|
468
|
+
|
|
469
|
+
#### **How AttendanceFilter Works**
|
|
470
|
+
1. **Groups** all time entries by date and user
|
|
471
|
+
2. **Calculates** daily totals (work hours, start time, end time, breaks)
|
|
472
|
+
3. **Applies** filters to each day's totals
|
|
473
|
+
4. **Returns** entries only from days that pass ALL filter criteria
|
|
474
|
+
|
|
475
|
+
#### **AttendanceFilter Structure**
|
|
476
|
+
```json
|
|
477
|
+
{
|
|
478
|
+
"attendanceFilter": {
|
|
479
|
+
"page": 1,
|
|
480
|
+
"pageSize": 201,
|
|
481
|
+
"sortColumn": "USER",
|
|
482
|
+
"hasTimeOff": true,
|
|
483
|
+
"workFilters": [{"filtrationType": "LARGER_THAN", "value": "480"}],
|
|
484
|
+
"startFilters": [{"filtrationType": "LARGER_THAN", "value": "09:00"}],
|
|
485
|
+
"endFilters": [{"filtrationType": "SMALLER_THAN", "value": "17:00"}],
|
|
486
|
+
"breakFilters": [{"filtrationType": "SMALLER_THAN", "value": "120"}],
|
|
487
|
+
"capacityFilters": [{"filtrationType": "EXACTLY", "value": "800"}],
|
|
488
|
+
"overtimeFilters": [{"filtrationType": "LARGER_THAN", "value": "100"}]
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
#### **AttendanceFilter Parameters Explained**
|
|
494
|
+
|
|
495
|
+
**page & pageSize**:
|
|
496
|
+
- **DIFFERENT LIMIT**: Maximum pageSize is **201** (not 1000 like detailedFilter!)
|
|
497
|
+
- Error: "Maximum page size is 201"
|
|
498
|
+
|
|
499
|
+
**sortColumn** (Different from main sortColumn!):
|
|
500
|
+
- `"USER"` - Sort by user name
|
|
501
|
+
- `"DATE"` - Sort by date
|
|
502
|
+
- `"START"` - Sort by daily start time
|
|
503
|
+
- `"END"` - Sort by daily end time
|
|
504
|
+
- `"BREAK"` - Sort by daily break duration
|
|
505
|
+
- `"WORK"` - Sort by daily work duration
|
|
506
|
+
- `"CAPACITY"` - Sort by scheduled capacity
|
|
507
|
+
- `"OVERTIME"` - Sort by overtime amount
|
|
508
|
+
- `"TIME_OFF"` - Sort by time off status
|
|
509
|
+
|
|
510
|
+
**⚠️ Critical**: Official spec says `"NAME"` but this **fails**! Use `"USER"` instead.
|
|
511
|
+
|
|
512
|
+
**hasTimeOff**:
|
|
513
|
+
- `true` - Include days with PTO/vacation requests
|
|
514
|
+
- `false` - Exclude days with time off
|
|
515
|
+
|
|
516
|
+
**Filter Arrays** (All use same structure):
|
|
517
|
+
|
|
518
|
+
**workFilters** - Filter by daily work hours:
|
|
519
|
+
```json
|
|
520
|
+
[{"filtrationType": "LARGER_THAN", "value": "480"}]
|
|
521
|
+
```
|
|
522
|
+
- **Value Format**: Hours × 100 (so "480" = 4.8 hours)
|
|
523
|
+
- **Common Values**:
|
|
524
|
+
- `"60"` = 0.6 hours (36 minutes) - Very permissive
|
|
525
|
+
- `"240"` = 2.4 hours - Half day minimum
|
|
526
|
+
- `"480"` = 4.8 hours - Standard work day minimum
|
|
527
|
+
- `"800"` = 8.0 hours - Full work day
|
|
528
|
+
- `"960"` = 9.6 hours - Overtime threshold
|
|
529
|
+
|
|
530
|
+
**startFilters & endFilters** - Filter by daily start/end times:
|
|
531
|
+
```json
|
|
532
|
+
[{"filtrationType": "LARGER_THAN", "value": "09:00"}]
|
|
533
|
+
```
|
|
534
|
+
- **Value Format**: 24-hour time format (e.g., "09:00", "17:30")
|
|
535
|
+
- **⚠️ Warning**: Very restrictive! If ANY entry on a day violates time criteria, ENTIRE day excluded
|
|
536
|
+
- **Use Cases**: Business hours compliance, schedule adherence
|
|
537
|
+
|
|
538
|
+
**breakFilters** - Filter by daily break duration:
|
|
539
|
+
```json
|
|
540
|
+
[{"filtrationType": "SMALLER_THAN", "value": "120"}]
|
|
541
|
+
```
|
|
542
|
+
- **Value Format**: Hours × 100 (so "120" = 1.2 hours)
|
|
543
|
+
|
|
544
|
+
**capacityFilters** - Filter by scheduled vs actual hours:
|
|
545
|
+
```json
|
|
546
|
+
[{"filtrationType": "EXACTLY", "value": "800"}]
|
|
547
|
+
```
|
|
548
|
+
- **Value Format**: Hours × 100 (so "800" = 8.0 hours)
|
|
549
|
+
|
|
550
|
+
**overtimeFilters** - Filter by overtime work:
|
|
551
|
+
```json
|
|
552
|
+
[{"filtrationType": "LARGER_THAN", "value": "100"}]
|
|
553
|
+
```
|
|
554
|
+
- **Value Format**: Hours × 100 (so "100" = 1.0 hour overtime)
|
|
555
|
+
|
|
556
|
+
**filtrationType Options**:
|
|
557
|
+
- `"EXACTLY"` - Days with exactly this value
|
|
558
|
+
- `"LARGER_THAN"` - Days with more than this value
|
|
559
|
+
- `"SMALLER_THAN"` - Days with less than this value
|
|
560
|
+
|
|
561
|
+
**🔥 Surprising Behavior**: Invalid filter values are silently ignored (no error)
|
|
562
|
+
|
|
563
|
+
---
|
|
564
|
+
|
|
565
|
+
### 📈 **Advanced Analysis Parameters**
|
|
566
|
+
|
|
567
|
+
#### **summaryFilter (Summary Reporting)**
|
|
568
|
+
```json
|
|
569
|
+
{
|
|
570
|
+
"summaryFilter": {
|
|
571
|
+
"groups": ["PROJECT", "CLIENT"],
|
|
572
|
+
"sortColumn": "DURATION",
|
|
573
|
+
"summaryChartType": "PROJECT"
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
**groups** - **Required, 1-3 group types**:
|
|
579
|
+
- `"PROJECT"` - Group by projects
|
|
580
|
+
- `"CLIENT"` - Group by clients
|
|
581
|
+
- `"TASK"` - Group by tasks
|
|
582
|
+
- `"TAG"` - Group by tags
|
|
583
|
+
- `"DATE"` - Group by date
|
|
584
|
+
- `"WEEK"` - Group by week
|
|
585
|
+
- `"MONTH"` - Group by month
|
|
586
|
+
- `"USER"` - Group by users
|
|
587
|
+
- `"USER_GROUP"` - Group by user groups
|
|
588
|
+
- `"TIMEENTRY"` - Group by individual time entries
|
|
589
|
+
|
|
590
|
+
**⚠️ Critical Errors**:
|
|
591
|
+
- Empty array `[]` → "Groups size must be between 1 and 3"
|
|
592
|
+
- More than 3 items → Same error
|
|
593
|
+
- Invalid group type → "Invalid group name"
|
|
594
|
+
|
|
595
|
+
**sortColumn** - How to sort summary results:
|
|
596
|
+
- `"GROUP"` - Sort by group name
|
|
597
|
+
- `"DURATION"` - Sort by time duration
|
|
598
|
+
- `"AMOUNT"` - Sort by amount
|
|
599
|
+
- `"EARNED"` - Sort by earnings
|
|
600
|
+
- `"COST"` - Sort by costs
|
|
601
|
+
- `"PROFIT"` - Sort by profit
|
|
602
|
+
|
|
603
|
+
**summaryChartType** - Chart visualization:
|
|
604
|
+
- `"BILLABILITY"` - Billable vs non-billable breakdown
|
|
605
|
+
- `"PROJECT"` - Project-based analysis
|
|
606
|
+
|
|
607
|
+
#### **weeklyFilter (Weekly Pattern Analysis)**
|
|
608
|
+
```json
|
|
609
|
+
{
|
|
610
|
+
"weeklyFilter": {
|
|
611
|
+
"group": "group_id",
|
|
612
|
+
"subgroup": "subgroup_id"
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
**Use Case**: Weekly pattern analysis and trend identification
|
|
618
|
+
|
|
619
|
+
#### **customFields (Custom Field Filtering)**
|
|
620
|
+
```json
|
|
621
|
+
{
|
|
622
|
+
"customFields": [
|
|
623
|
+
{
|
|
624
|
+
"id": "custom_field_id",
|
|
625
|
+
"type": "TXT",
|
|
626
|
+
"isEmpty": false,
|
|
627
|
+
"numberCondition": "EQUAL",
|
|
628
|
+
"value": "custom_value"
|
|
629
|
+
}
|
|
630
|
+
]
|
|
631
|
+
}
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
**type** - Custom field types:
|
|
635
|
+
- `"TXT"` - Text fields
|
|
636
|
+
- `"NUMBER"` - Number fields
|
|
637
|
+
- `"DROPDOWN_SINGLE"` - Single-select dropdown
|
|
638
|
+
- `"DROPDOWN_MULTIPLE"` - Multi-select dropdown
|
|
639
|
+
- `"CHECKBOX"` - Checkbox field
|
|
640
|
+
- `"LINK"` - URL/link field
|
|
641
|
+
|
|
642
|
+
**numberCondition** (for number fields):
|
|
643
|
+
- `"EQUAL"` - Exactly equal
|
|
644
|
+
- `"GREATER_THAN"` - Greater than value
|
|
645
|
+
- `"LESS_THAN"` - Less than value
|
|
646
|
+
|
|
647
|
+
**isEmpty**:
|
|
648
|
+
- `true` - Find fields with no value
|
|
649
|
+
- `false` - Find fields with values
|
|
650
|
+
|
|
651
|
+
#### **auditFilter (Data Quality)**
|
|
652
|
+
```json
|
|
653
|
+
{
|
|
654
|
+
"detailedFilter": {
|
|
655
|
+
"auditFilter": {
|
|
656
|
+
"duration": 300,
|
|
657
|
+
"durationShorter": true,
|
|
658
|
+
"withoutProject": false,
|
|
659
|
+
"withoutTask": false
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
**duration** - Time threshold in seconds:
|
|
666
|
+
- `300` = 5 minutes
|
|
667
|
+
- `3600` = 1 hour
|
|
668
|
+
|
|
669
|
+
**durationShorter**:
|
|
670
|
+
- `true` - Find entries shorter than duration
|
|
671
|
+
- `false` - Find entries longer than duration
|
|
672
|
+
|
|
673
|
+
**withoutProject**:
|
|
674
|
+
- `true` - Include entries missing project assignment
|
|
675
|
+
- `false` - Exclude entries without projects
|
|
676
|
+
|
|
677
|
+
**withoutTask**:
|
|
678
|
+
- `true` - Include entries missing task assignment
|
|
679
|
+
- `false` - Exclude entries without tasks
|
|
680
|
+
|
|
681
|
+
**Use Cases**: Data quality audits, find incomplete time tracking
|
|
682
|
+
|
|
683
|
+
#### **options (Response Control)**
|
|
684
|
+
```json
|
|
685
|
+
{
|
|
686
|
+
"detailedFilter": {
|
|
687
|
+
"options": {
|
|
688
|
+
"totals": "CALCULATE"
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
**totals**:
|
|
695
|
+
- `"CALCULATE"` - Include totals in response (default)
|
|
696
|
+
- `"EXCLUDE"` - Skip totals calculation for faster response
|
|
697
|
+
|
|
698
|
+
---
|
|
699
|
+
|
|
700
|
+
### 🌍 **Localization & Format Parameters**
|
|
701
|
+
|
|
702
|
+
#### **timeZone (Critical for Accuracy)**
|
|
703
|
+
```json
|
|
704
|
+
{ "timeZone": "America/New_York" }
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
**Valid Formats**:
|
|
708
|
+
- IANA timezone names: `"America/New_York"`, `"Europe/London"`, `"Asia/Tokyo"`
|
|
709
|
+
- UTC: `"UTC"`
|
|
710
|
+
- Surprisingly works: `"GMT+5"` (non-standard but accepted)
|
|
711
|
+
|
|
712
|
+
**Invalid Examples**:
|
|
713
|
+
- `"Invalid/Timezone"` → HTTP 400 "The specified report time zone is invalid"
|
|
714
|
+
- `123` → Same error
|
|
715
|
+
|
|
716
|
+
**Critical Impact**:
|
|
717
|
+
- AttendanceFilter daily boundaries
|
|
718
|
+
- Date/time interpretation
|
|
719
|
+
- Accurate reporting for remote teams
|
|
720
|
+
|
|
721
|
+
#### **dateFormat & timeFormat (Display Formatting)**
|
|
722
|
+
```json
|
|
723
|
+
{
|
|
724
|
+
"dateFormat": "YYYY-MM-DD",
|
|
725
|
+
"timeFormat": "THH:MM:SS.ssssss"
|
|
726
|
+
}
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
**Use Case**: Localized report formatting for different regions
|
|
730
|
+
|
|
731
|
+
#### **weekStart (Week Calculation)**
|
|
732
|
+
```json
|
|
733
|
+
{ "weekStart": "MONDAY" }
|
|
734
|
+
```
|
|
735
|
+
|
|
736
|
+
**Options**: `"MONDAY"`, `"TUESDAY"`, `"WEDNESDAY"`, `"THURSDAY"`, `"FRIDAY"`, `"SATURDAY"`, `"SUNDAY"`
|
|
737
|
+
|
|
738
|
+
**Impact**: Affects weekly calculations and AttendanceFilter
|
|
739
|
+
|
|
740
|
+
#### **userLocale (Number & Date Formatting)**
|
|
741
|
+
```json
|
|
742
|
+
{ "userLocale": "en-US" }
|
|
743
|
+
```
|
|
744
|
+
|
|
745
|
+
**Examples**: `"en-US"`, `"de-DE"`, `"fr-FR"`, `"ja-JP"`
|
|
746
|
+
|
|
747
|
+
**Impact**: Number formatting, date patterns, currency display
|
|
748
|
+
|
|
749
|
+
---
|
|
750
|
+
|
|
751
|
+
## 📋 **Response Structure**
|
|
752
|
+
```json
|
|
753
|
+
{
|
|
754
|
+
"timeEntries": [
|
|
755
|
+
{
|
|
756
|
+
"id": "entry_id",
|
|
757
|
+
"userId": "user_id",
|
|
758
|
+
"userName": "John Doe",
|
|
759
|
+
"userEmail": "john@company.com",
|
|
760
|
+
"projectId": "project_id",
|
|
761
|
+
"projectName": "Project Name",
|
|
762
|
+
"clientId": "client_id",
|
|
763
|
+
"clientName": "Client Name",
|
|
764
|
+
"timeInterval": {
|
|
765
|
+
"start": "2024-08-01T09:00:00Z",
|
|
766
|
+
"end": "2024-08-01T17:00:00Z",
|
|
767
|
+
"duration": 28800
|
|
768
|
+
},
|
|
769
|
+
"description": "Work description",
|
|
770
|
+
"billable": true,
|
|
771
|
+
"tags": [{"id": "tag_id", "name": "Tag Name"}]
|
|
772
|
+
}
|
|
773
|
+
],
|
|
774
|
+
"totals": [
|
|
775
|
+
{
|
|
776
|
+
"totalTime": 86400,
|
|
777
|
+
"totalBillableTime": 28800,
|
|
778
|
+
"entriesCount": 10,
|
|
779
|
+
"amounts": [
|
|
780
|
+
{
|
|
781
|
+
"amount": 50000,
|
|
782
|
+
"currency": "USD"
|
|
783
|
+
}
|
|
784
|
+
]
|
|
785
|
+
}
|
|
786
|
+
]
|
|
787
|
+
}
|
|
788
|
+
```
|
|
789
|
+
|
|
790
|
+
---
|
|
791
|
+
|
|
792
|
+
## 🚨 **Complete Error Reference (40+ Errors)**
|
|
793
|
+
|
|
794
|
+
### **HTTP 400 - Bad Request (33 errors)**
|
|
795
|
+
|
|
796
|
+
#### **Missing Required Fields**
|
|
797
|
+
- `400/400`: Missing dateRangeStart, dateRangeEnd
|
|
798
|
+
- `400/501`: Missing detailedFilter - "Please provide detailed filter."
|
|
799
|
+
|
|
800
|
+
#### **Date Format Errors**
|
|
801
|
+
- `400/501`: Invalid date format - "Invalid date! dateRangeStart and dateRangeEnd must be present; dateRangeStart and dateRangeEnd must be in ISO date format [1996-03-15T23:59:59.999Z]"
|
|
802
|
+
- `400/501`: End date before start date - "Invalid date range. dateRangeStart must be before dateRangeEnd."
|
|
803
|
+
|
|
804
|
+
#### **Pagination Errors**
|
|
805
|
+
- `400/400`: Page size too large - "Maximum page size is 1,000"
|
|
806
|
+
- `400/400`: Invalid data types - "Could not parse JSON"
|
|
807
|
+
|
|
808
|
+
#### **Sort Column Errors**
|
|
809
|
+
- `400/400`: Invalid sort column - Valid options: `[ID, DESCRIPTION, USER, DURATION, DATE, NATURAL, USER_DATE]`
|
|
810
|
+
- `500/500`: Empty sort column - **Server crash!**
|
|
811
|
+
|
|
812
|
+
#### **Amount Parameter Errors**
|
|
813
|
+
- `400/400`: Invalid amountShown - Valid options: `[EARNED, COST, PROFIT, HIDE_AMOUNT, EXPORT]`
|
|
814
|
+
- `500/500`: Empty amountShown - **Server crash!**
|
|
815
|
+
|
|
816
|
+
#### **Entity Filter Errors**
|
|
817
|
+
- `400/400`: Invalid contains value - Valid options: `[CONTAINS, DOES_NOT_CONTAIN, CONTAINS_ONLY]`
|
|
818
|
+
- `400/501`: Invalid status - "Status is not valid!"
|
|
819
|
+
|
|
820
|
+
#### **AttendanceFilter Errors**
|
|
821
|
+
- `400/400`: Invalid filter type - Valid options: `[EXACTLY, LARGER_THAN, SMALLER_THAN]`
|
|
822
|
+
- `400/400`: Invalid time format - "Invalid time format."
|
|
823
|
+
- `400/501`: **AttendanceFilter page size limit** - "Maximum page size is 201"
|
|
824
|
+
|
|
825
|
+
#### **summaryFilter Errors (NEW)**
|
|
826
|
+
- `400/501`: **Groups size validation** - "Groups size must be between 1 and 3"
|
|
827
|
+
- `400/501`: **Invalid group name** - "Invalid group name" (must use: PROJECT, CLIENT, TASK, TAG, DATE, WEEK, MONTH, USER, USER_GROUP, TIMEENTRY)
|
|
828
|
+
|
|
829
|
+
#### **Timezone Errors**
|
|
830
|
+
- `400/501`: Invalid timezone - "The specified report time zone is invalid."
|
|
831
|
+
|
|
832
|
+
#### **Export Type Errors**
|
|
833
|
+
- `400/400`: Invalid export type - Valid options: `[JSON, JSON_V1, PDF, CSV, XLSX, ZIP]`
|
|
834
|
+
- `500/500`: Empty export type - **Server crash!**
|
|
835
|
+
|
|
836
|
+
#### **JSON Parsing**
|
|
837
|
+
- `400/400`: Malformed JSON - "Could not parse JSON"
|
|
838
|
+
|
|
839
|
+
### **HTTP 401 - Unauthorized (3 errors)**
|
|
840
|
+
- `401/401`: Invalid API key - "Unauthorized"
|
|
841
|
+
- `401/401`: Missing API key - "Multiple or none auth tokens present"
|
|
842
|
+
- `401/401`: Invalid workspace ID - "Unauthorized"
|
|
843
|
+
|
|
844
|
+
### **HTTP 500 - Server Error (3 errors)**
|
|
845
|
+
- `500/500`: Empty string in sortColumn, amountShown, or exportType - "Error occurred while generating report"
|
|
846
|
+
|
|
847
|
+
### **HTTP 0 - Client Error (1 error)**
|
|
848
|
+
- Network/parsing exceptions when response isn't valid JSON
|
|
849
|
+
|
|
850
|
+
---
|
|
851
|
+
|
|
852
|
+
## ⚠️ **Critical Gotchas & Warnings**
|
|
853
|
+
|
|
854
|
+
### **🔥 Server Crashes (HTTP 500)**
|
|
855
|
+
**Never use empty strings in these fields - causes server crashes:**
|
|
856
|
+
- `sortColumn: ""`
|
|
857
|
+
- `amountShown: ""`
|
|
858
|
+
- `exportType: ""`
|
|
859
|
+
|
|
860
|
+
### **🎯 AttendanceFilter Special Rules**
|
|
861
|
+
- **Different page size limit**: 201 (not 1000 like detailedFilter)
|
|
862
|
+
- **Daily filtering**: Filters entire days, not individual entries
|
|
863
|
+
- **Restrictive time filters**: One invalid time excludes the entire day
|
|
864
|
+
|
|
865
|
+
### **📊 summaryFilter Requirements (NEW)**
|
|
866
|
+
- `groups` array **must have 1-3 items** (cannot be empty)
|
|
867
|
+
- Group IDs **cannot be empty strings**
|
|
868
|
+
- More restrictive than documented
|
|
869
|
+
|
|
870
|
+
### **🔄 Parameter Interactions**
|
|
871
|
+
- Using both `amountShown` AND `amounts`: `amounts` takes precedence
|
|
872
|
+
- `pageSize: 0` in detailedFilter: **Returns ALL data** (dangerous!)
|
|
873
|
+
- Negative pagination values: Treated as defaults (works unexpectedly)
|
|
874
|
+
|
|
875
|
+
### **📅 Date Range Limits**
|
|
876
|
+
- **FREE plan**: Maximum 1 year (366 days)
|
|
877
|
+
- Very large ranges (40+ years): Work but may be slow
|
|
878
|
+
|
|
879
|
+
### **🌐 Export Format Gotchas**
|
|
880
|
+
- `exportType: "csv"` (lowercase): Works but returns CSV data instead of JSON (breaks parsing)
|
|
881
|
+
- Non-JSON exports return binary data, not JSON responses
|
|
882
|
+
|
|
883
|
+
---
|
|
884
|
+
|
|
885
|
+
## 🎯 **Common Use Cases**
|
|
886
|
+
|
|
887
|
+
### **Invoice Generation**
|
|
888
|
+
```json
|
|
889
|
+
{
|
|
890
|
+
"dateRangeStart": "2024-01-01T00:00:00.000Z",
|
|
891
|
+
"dateRangeEnd": "2024-01-31T23:59:59.999Z",
|
|
892
|
+
"detailedFilter": {"page": 1, "pageSize": 1000},
|
|
893
|
+
"clients": {"contains": "CONTAINS", "ids": ["client_id"], "status": "ACTIVE"},
|
|
894
|
+
"billable": true,
|
|
895
|
+
"invoicingState": "UNINVOICED",
|
|
896
|
+
"amounts": ["EARNED"]
|
|
897
|
+
}
|
|
898
|
+
```
|
|
899
|
+
|
|
900
|
+
### **Team Productivity Report**
|
|
901
|
+
```json
|
|
902
|
+
{
|
|
903
|
+
"dateRangeStart": "2024-01-01T00:00:00.000Z",
|
|
904
|
+
"dateRangeEnd": "2024-12-31T23:59:59.999Z",
|
|
905
|
+
"detailedFilter": {"page": 1, "pageSize": 200},
|
|
906
|
+
"userGroups": {"contains": "CONTAINS", "ids": ["team_id"], "status": "ACTIVE"},
|
|
907
|
+
"attendanceFilter": {
|
|
908
|
+
"page": 1,
|
|
909
|
+
"pageSize": 201,
|
|
910
|
+
"sortColumn": "USER",
|
|
911
|
+
"workFilters": [{"filtrationType": "LARGER_THAN", "value": "480"}]
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
```
|
|
915
|
+
|
|
916
|
+
### **Data Quality Audit**
|
|
917
|
+
```json
|
|
918
|
+
{
|
|
919
|
+
"dateRangeStart": "2024-01-01T00:00:00.000Z",
|
|
920
|
+
"dateRangeEnd": "2024-12-31T23:59:59.999Z",
|
|
921
|
+
"detailedFilter": {
|
|
922
|
+
"page": 1,
|
|
923
|
+
"pageSize": 1000,
|
|
924
|
+
"auditFilter": {
|
|
925
|
+
"duration": 300,
|
|
926
|
+
"durationShorter": true,
|
|
927
|
+
"withoutProject": true
|
|
928
|
+
}
|
|
929
|
+
},
|
|
930
|
+
"withoutDescription": true
|
|
931
|
+
}
|
|
932
|
+
```
|
|
933
|
+
|
|
934
|
+
---
|
|
935
|
+
|
|
936
|
+
**📊 Total Documented Errors**: 40+
|
|
937
|
+
**🔬 Based on**: Comprehensive API testing
|
|
938
|
+
**⚠️ More Accurate Than**: Official Clockify API documentation
|
|
939
|
+
**📅 Last Updated**: August 23, 2025
|