@wangjs-jacky/ticktick-cli 0.1.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.
Files changed (40) hide show
  1. package/.github/workflows/npm-publish.yml +26 -0
  2. package/CLAUDE.md +34 -0
  3. package/README.md +62 -0
  4. package/README_CN.md +62 -0
  5. package/bin/cli.ts +2 -0
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.js +1490 -0
  8. package/dist/index.js.map +1 -0
  9. package/docs/oauth-credential-pre-validation.md +253 -0
  10. package/docs/reference/cli-usage-guide.md +587 -0
  11. package/docs/reference/dida365-open-api-zh.md +999 -0
  12. package/docs/reference/dida365-open-api.md +999 -0
  13. package/docs/reference/project-guide.md +63 -0
  14. package/docs/superpowers/plans/2026-04-03-tt-cli-auth.md +1110 -0
  15. package/docs/superpowers/specs/2026-04-03-tt-cli-design.md +142 -0
  16. package/package.json +45 -0
  17. package/skills/tt-cli-guide/SKILL.md +152 -0
  18. package/skills/tt-cli-guide/references/intent-mapping.md +169 -0
  19. package/src/api/client.ts +61 -0
  20. package/src/api/oauth.ts +146 -0
  21. package/src/api/resources.ts +291 -0
  22. package/src/commands/auth.ts +218 -0
  23. package/src/commands/project.ts +303 -0
  24. package/src/commands/task.ts +806 -0
  25. package/src/commands/user.ts +43 -0
  26. package/src/index.ts +46 -0
  27. package/src/types.ts +211 -0
  28. package/src/utils/config.ts +88 -0
  29. package/src/utils/endpoints.ts +22 -0
  30. package/src/utils/format.ts +71 -0
  31. package/src/utils/server.ts +81 -0
  32. package/tests/config.test.ts +87 -0
  33. package/tests/format.test.ts +56 -0
  34. package/tests/oauth.test.ts +42 -0
  35. package/tests/parity-fields.test.ts +89 -0
  36. package/tests/parity-map.ts +184 -0
  37. package/tests/parity.test.ts +101 -0
  38. package/tsconfig.json +22 -0
  39. package/tsup.config.ts +12 -0
  40. package/vitest.config.ts +7 -0
@@ -0,0 +1,999 @@
1
+ # Dida365 Open API
2
+
3
+ ## Introduction
4
+
5
+ Welcome to the Dida365 Open API documentation. Dida365 is a powerful task management application that allows users to easily manage and organize their daily tasks, deadlines, and projects. With Dida365 Open API, developers can integrate Dida365's powerful task management features into their own applications and create a seamless user experience.
6
+
7
+ ## Getting Started
8
+
9
+ To get started using the Dida365 Open API, you will need to register your application and obtain a client ID and client secret. You can register your application by visiting the [Dida365 Developer Center](https://developer.dida365.com/manage). Once registered, you will receive a client ID and client secret which you will use to authenticate your requests.
10
+
11
+ ## Authorization
12
+
13
+ ### Get Access Token
14
+
15
+ In order to call Dida365's Open API, it is necessary to obtain an access token for the corresponding user. Dida365 uses the OAuth2 protocol to obtain the access token.
16
+
17
+ #### First Step
18
+
19
+ Redirect the user to the Dida365 authorization page: `https://dida365.com/oauth/authorize`
20
+
21
+ | Name | Description |
22
+ |------|-------------|
23
+ | client_id | Application unique id |
24
+ | scope | Spaces-separated permission scope. The currently available scopes are `tasks:write` `tasks:read` |
25
+ | state | Passed to redirect url as is |
26
+ | redirect_uri | User-configured redirect url |
27
+ | response_type | Fixed as `code` |
28
+
29
+ Example:
30
+
31
+ ```
32
+ https://dida365.com/oauth/authorize?scope=scope&client_id=client_id&state=state&redirect_uri=redirect_uri&response_type=code
33
+ ```
34
+
35
+ #### Second Step
36
+
37
+ After the user grants access, Dida365 will redirect the user back to your application's `redirect_uri` with an authorization code as a query parameter.
38
+
39
+ | Name | Description |
40
+ |------|-------------|
41
+ | code | Authorization code for subsequent access tokens |
42
+ | state | state parameter passed in the first step |
43
+
44
+ #### Third Step
45
+
46
+ To exchange the authorization code for an access token, make a POST request to `https://dida365.com/oauth/token` with the following parameters (Content-Type: application/x-www-form-urlencoded):
47
+
48
+ | Name | Description |
49
+ |------|-------------|
50
+ | client_id | The username is located in the **HEADER** using the **Basic Auth** authentication method |
51
+ | client_secret | The password is located in the **HEADER** using the **Basic Auth** authentication method |
52
+ | code | The code obtained in the second step |
53
+ | grant_type | Grant type, now only `authorization_code` |
54
+ | scope | Spaces-separated permission scope. The currently available scopes are `tasks:write`, `tasks:read` |
55
+ | redirect_uri | User-configured redirect url |
56
+
57
+ Access_token for OpenAPI request authentication in the request response:
58
+
59
+ ```json
60
+ {
61
+ "access_token": "access token value"
62
+ }
63
+ ```
64
+
65
+ #### Request OpenAPI
66
+
67
+ Set **Authorization** in the header, the value is **Bearer** `access token value`:
68
+
69
+ ```
70
+ Authorization: Bearer e*****b
71
+ ```
72
+
73
+ ## API Reference
74
+
75
+ The Dida365 Open API provides a RESTful interface for accessing and managing user tasks, lists, and other related resources. The API is based on the standard HTTP protocol and supports JSON data formats.
76
+
77
+ ### Task
78
+
79
+ #### Get Task By Project ID And Task ID
80
+
81
+ ```
82
+ GET /open/v1/project/{projectId}/task/{taskId}
83
+ ```
84
+
85
+ **Parameters**
86
+
87
+ | Type | Name | Description | Schema |
88
+ |------|------|-------------|--------|
89
+ | Path | **projectId** *required* | Project identifier | string |
90
+ | Path | **taskId** *required* | Task identifier | string |
91
+
92
+ **Responses**
93
+
94
+ | HTTP Code | Description | Schema |
95
+ |-----------|-------------|--------|
96
+ | 200 | OK | [Task](#task) |
97
+ | 401 | Unauthorized | No Content |
98
+ | 403 | Forbidden | No Content |
99
+ | 404 | Not Found | No Content |
100
+
101
+ **Example**
102
+
103
+ Request:
104
+
105
+ ```http
106
+ GET /open/v1/project/{{projectId}}/task/{{taskId}} HTTP/1.1
107
+ Host: api.dida365.com
108
+ Authorization: Bearer {{token}}
109
+ ```
110
+
111
+ Response:
112
+
113
+ ```json
114
+ {
115
+ "id": "63b7bebb91c0a5474805fcd4",
116
+ "isAllDay": true,
117
+ "projectId": "6226ff9877acee87727f6bca",
118
+ "title": "Task Title",
119
+ "content": "Task Content",
120
+ "desc": "Task Description",
121
+ "timeZone": "America/Los_Angeles",
122
+ "repeatFlag": "RRULE:FREQ=DAILY;INTERVAL=1",
123
+ "startDate": "2019-11-13T03:00:00+0000",
124
+ "dueDate": "2019-11-14T03:00:00+0000",
125
+ "reminders": ["TRIGGER:P0DT9H0M0S", "TRIGGER:PT0S"],
126
+ "priority": 1,
127
+ "status": 0,
128
+ "completedTime": "2019-11-13T03:00:00+0000",
129
+ "sortOrder": 12345,
130
+ "items": [
131
+ {
132
+ "id": "6435074647fd2e6387145f20",
133
+ "status": 0,
134
+ "title": "Item Title",
135
+ "sortOrder": 12345,
136
+ "startDate": "2019-11-13T03:00:00+0000",
137
+ "isAllDay": false,
138
+ "timeZone": "America/Los_Angeles",
139
+ "completedTime": "2019-11-13T03:00:00+0000"
140
+ }
141
+ ]
142
+ }
143
+ ```
144
+
145
+ #### Create Task
146
+
147
+ ```
148
+ POST /open/v1/task
149
+ ```
150
+
151
+ **Parameters**
152
+
153
+ | Type | Name | Description | Schema |
154
+ |------|------|-------------|--------|
155
+ | Body | title *required* | Task title | string |
156
+ | Body | projectId *required* | Project id | string |
157
+ | Body | content | Task content | string |
158
+ | Body | desc | Description of checklist | string |
159
+ | Body | isAllDay | All day | boolean |
160
+ | Body | startDate | Start date and time in `"yyyy-MM-dd'T'HH:mm:ssZ"` format. **Example**: `"2019-11-13T03:00:00+0000"` | date |
161
+ | Body | dueDate | Due date and time in `"yyyy-MM-dd'T'HH:mm:ssZ"` format. **Example**: `"2019-11-13T03:00:00+0000"` | date |
162
+ | Body | timeZone | The time zone in which the time is specified | string |
163
+ | Body | reminders | Lists of reminders specific to the task | list |
164
+ | Body | repeatFlag | Recurring rules of task | string |
165
+ | Body | priority | The priority of task, default is "0" | integer |
166
+ | Body | sortOrder | The order of task | integer |
167
+ | Body | items | The list of subtasks | list |
168
+ | Body | items.title | Subtask title | string |
169
+ | Body | items.startDate | Start date and time in `"yyyy-MM-dd'T'HH:mm:ssZ"` format | date |
170
+ | Body | items.isAllDay | All day | boolean |
171
+ | Body | items.sortOrder | The order of subtask | integer |
172
+ | Body | items.timeZone | The time zone in which the Start time is specified | string |
173
+ | Body | items.status | The completion status of subtask | integer |
174
+ | Body | items.completedTime | Completed time in `"yyyy-MM-dd'T'HH:mm:ssZ"` format. **Example**: `"2019-11-13T03:00:00+0000"` | date |
175
+
176
+ **Responses**
177
+
178
+ | HTTP Code | Description | Schema |
179
+ |-----------|-------------|--------|
180
+ | 200 | OK | [Task](#task) |
181
+ | 201 | Created | No Content |
182
+ | 401 | Unauthorized | No Content |
183
+ | 403 | Forbidden | No Content |
184
+ | 404 | Not Found | No Content |
185
+
186
+ **Example**
187
+
188
+ Request:
189
+
190
+ ```http
191
+ POST /open/v1/task HTTP/1.1
192
+ Host: api.dida365.com
193
+ Content-Type: application/json
194
+ Authorization: Bearer {{token}}
195
+
196
+ {
197
+ "title": "Task Title",
198
+ "projectId": "6226ff9877acee87727f6bca"
199
+ }
200
+ ```
201
+
202
+ Response:
203
+
204
+ ```json
205
+ {
206
+ "id": "63b7bebb91c0a5474805fcd4",
207
+ "projectId": "6226ff9877acee87727f6bca",
208
+ "title": "Task Title",
209
+ "content": "Task Content",
210
+ "desc": "Task Description",
211
+ "isAllDay": true,
212
+ "startDate": "2019-11-13T03:00:00+0000",
213
+ "dueDate": "2019-11-14T03:00:00+0000",
214
+ "timeZone": "America/Los_Angeles",
215
+ "reminders": ["TRIGGER:P0DT9H0M0S", "TRIGGER:PT0S"],
216
+ "repeatFlag": "RRULE:FREQ=DAILY;INTERVAL=1",
217
+ "priority": 1,
218
+ "status": 0,
219
+ "completedTime": "2019-11-13T03:00:00+0000",
220
+ "sortOrder": 12345,
221
+ "items": [
222
+ {
223
+ "id": "6435074647fd2e6387145f20",
224
+ "status": 1,
225
+ "title": "Subtask Title",
226
+ "sortOrder": 12345,
227
+ "startDate": "2019-11-13T03:00:00+0000",
228
+ "isAllDay": false,
229
+ "timeZone": "America/Los_Angeles",
230
+ "completedTime": "2019-11-13T03:00:00+0000"
231
+ }
232
+ ]
233
+ }
234
+ ```
235
+
236
+ #### Update Task
237
+
238
+ ```
239
+ POST /open/v1/task/{taskId}
240
+ ```
241
+
242
+ **Parameters**
243
+
244
+ | Type | Name | Description | Schema |
245
+ |------|------|-------------|--------|
246
+ | Path | **taskId** *required* | Task identifier | string |
247
+ | Body | id *required* | Task id | string |
248
+ | Body | projectId *required* | Project id | string |
249
+ | Body | title | Task title | string |
250
+ | Body | content | Task content | string |
251
+ | Body | desc | Description of checklist | string |
252
+ | Body | isAllDay | All day | boolean |
253
+ | Body | startDate | Start date and time in `"yyyy-MM-dd'T'HH:mm:ssZ"` format. **Example**: `"2019-11-13T03:00:00+0000"` | date |
254
+ | Body | dueDate | Due date and time in `"yyyy-MM-dd'T'HH:mm:ssZ"` format. **Example**: `"2019-11-13T03:00:00+0000"` | date |
255
+ | Body | timeZone | The time zone in which the time is specified | string |
256
+ | Body | reminders | Lists of reminders specific to the task | list |
257
+ | Body | repeatFlag | Recurring rules of task | string |
258
+ | Body | priority | The priority of task, default is "normal" | integer |
259
+ | Body | sortOrder | The order of task | integer |
260
+ | Body | items | The list of subtasks | list |
261
+ | Body | items.title | Subtask title | string |
262
+ | Body | items.startDate | Start date and time in `"yyyy-MM-dd'T'HH:mm:ssZ"` format | date |
263
+ | Body | items.isAllDay | All day | boolean |
264
+ | Body | items.sortOrder | The order of subtask | integer |
265
+ | Body | items.timeZone | The time zone in which the Start time is specified | string |
266
+ | Body | items.status | The completion status of subtask | integer |
267
+ | Body | items.completedTime | Completed time in `"yyyy-MM-dd'T'HH:mm:ssZ"` format. **Example**: `"2019-11-13T03:00:00+0000"` | date |
268
+
269
+ **Responses**
270
+
271
+ | HTTP Code | Description | Schema |
272
+ |-----------|-------------|--------|
273
+ | 200 | OK | [Task](#task) |
274
+ | 201 | Created | No Content |
275
+ | 401 | Unauthorized | No Content |
276
+ | 403 | Forbidden | No Content |
277
+ | 404 | Not Found | No Content |
278
+
279
+ **Example**
280
+
281
+ Request:
282
+
283
+ ```http
284
+ POST /open/v1/task/{{taskId}} HTTP/1.1
285
+ Host: api.dida365.com
286
+ Content-Type: application/json
287
+ Authorization: Bearer {{token}}
288
+
289
+ {
290
+ "id": "{{taskId}}",
291
+ "projectId": "{{projectId}}",
292
+ "title": "Task Title",
293
+ "priority": 1
294
+ }
295
+ ```
296
+
297
+ Response:
298
+
299
+ ```json
300
+ {
301
+ "id": "63b7bebb91c0a5474805fcd4",
302
+ "projectId": "6226ff9877acee87727f6bca",
303
+ "title": "Task Title",
304
+ "content": "Task Content",
305
+ "desc": "Task Description",
306
+ "isAllDay": true,
307
+ "startDate": "2019-11-13T03:00:00+0000",
308
+ "dueDate": "2019-11-14T03:00:00+0000",
309
+ "timeZone": "America/Los_Angeles",
310
+ "reminders": ["TRIGGER:P0DT9H0M0S", "TRIGGER:PT0S"],
311
+ "repeatFlag": "RRULE:FREQ=DAILY;INTERVAL=1",
312
+ "priority": 1,
313
+ "status": 0,
314
+ "completedTime": "2019-11-13T03:00:00+0000",
315
+ "sortOrder": 12345,
316
+ "items": [
317
+ {
318
+ "id": "6435074647fd2e6387145f20",
319
+ "status": 1,
320
+ "title": "Item Title",
321
+ "sortOrder": 12345,
322
+ "startDate": "2019-11-13T03:00:00+0000",
323
+ "isAllDay": false,
324
+ "timeZone": "America/Los_Angeles",
325
+ "completedTime": "2019-11-13T03:00:00+0000"
326
+ }
327
+ ],
328
+ "kind": "CHECKLIST"
329
+ }
330
+ ```
331
+
332
+ #### Complete Task
333
+
334
+ ```
335
+ POST /open/v1/project/{projectId}/task/{taskId}/complete
336
+ ```
337
+
338
+ **Parameters**
339
+
340
+ | Type | Name | Description | Schema |
341
+ |------|------|-------------|--------|
342
+ | Path | **projectId** *required* | Project identifier | string |
343
+ | Path | **taskId** *required* | Task identifier | string |
344
+
345
+ **Responses**
346
+
347
+ | HTTP Code | Description | Schema |
348
+ |-----------|-------------|--------|
349
+ | 200 | OK | No Content |
350
+ | 201 | Created | No Content |
351
+ | 401 | Unauthorized | No Content |
352
+ | 403 | Forbidden | No Content |
353
+ | 404 | Not Found | No Content |
354
+
355
+ **Example**
356
+
357
+ Request:
358
+
359
+ ```http
360
+ POST /open/v1/project/{{projectId}}/task/{{taskId}}/complete HTTP/1.1
361
+ Host: api.dida365.com
362
+ Authorization: Bearer {{token}}
363
+ ```
364
+
365
+ #### Delete Task
366
+
367
+ ```
368
+ DELETE /open/v1/project/{projectId}/task/{taskId}
369
+ ```
370
+
371
+ **Parameters**
372
+
373
+ | Type | Name | Description | Schema |
374
+ |------|------|-------------|--------|
375
+ | Path | **projectId** *required* | Project identifier | string |
376
+ | Path | **taskId** *required* | Task identifier | string |
377
+
378
+ **Responses**
379
+
380
+ | HTTP Code | Description | Schema |
381
+ |-----------|-------------|--------|
382
+ | 200 | OK | No Content |
383
+ | 201 | Created | No Content |
384
+ | 401 | Unauthorized | No Content |
385
+ | 403 | Forbidden | No Content |
386
+ | 404 | Not Found | No Content |
387
+
388
+ **Example**
389
+
390
+ Request:
391
+
392
+ ```http
393
+ DELETE /open/v1/project/{{projectId}}/task/{{taskId}} HTTP/1.1
394
+ Host: api.dida365.com
395
+ Authorization: Bearer {{token}}
396
+ ```
397
+
398
+ #### Move Task
399
+
400
+ ```
401
+ POST /open/v1/task/move
402
+ ```
403
+
404
+ Moves one or more tasks between projects.
405
+
406
+ **Request Body**
407
+
408
+ A JSON array containing task move operations.
409
+
410
+ | Type | Name | Description | Schema |
411
+ |------|------|-------------|--------|
412
+ | Body | **fromProjectId** *required* | The ID of the source project | string |
413
+ | Body | **toProjectId** *required* | The ID of the destination project | string |
414
+ | Body | **taskId** *required* | The ID of the task to move | string |
415
+
416
+ **Responses**
417
+
418
+ | HTTP Code | Description | Schema |
419
+ |-----------|-------------|--------|
420
+ | 200 | OK | Returns an array of move results, including the task ID and its new etag |
421
+ | 201 | Created | No Content |
422
+ | 401 | Unauthorized | No Content |
423
+ | 403 | Forbidden | No Content |
424
+ | 404 | Not Found | No Content |
425
+
426
+ **Example**
427
+
428
+ Request:
429
+
430
+ ```http
431
+ POST /open/v1/task/move HTTP/1.1
432
+ Host: api.dida365.com
433
+ Authorization: Bearer {{token}}
434
+
435
+ [
436
+ {
437
+ "fromProjectId": "69a850ef1c20d2030e148fdd",
438
+ "toProjectId": "69a850f41c20d2030e148fdf",
439
+ "taskId": "69a850f8b9061f374d54a046"
440
+ }
441
+ ]
442
+ ```
443
+
444
+ Response:
445
+
446
+ ```json
447
+ [
448
+ {
449
+ "id": "69a850f8b9061f374d54a046",
450
+ "etag": "43p2zso1"
451
+ }
452
+ ]
453
+ ```
454
+
455
+ #### List Completed Tasks
456
+
457
+ ```
458
+ POST /open/v1/task/completed
459
+ ```
460
+
461
+ Retrieves a list of tasks marked as completed within specific projects and a given time range.
462
+
463
+ **Request Body**
464
+
465
+ A JSON object containing filter criteria. All fields are optional, but at least one filter is recommended to narrow down results.
466
+
467
+ | Type | Name | Description | Schema |
468
+ |------|------|-------------|--------|
469
+ | Body | **projectIds** | List of project identifier | list |
470
+ | Body | **startDate** | The start of the time range (inclusive). Filters tasks where completedTime >= startDate | date |
471
+ | Body | **endDate** | The end of the time range (inclusive). Filters tasks where completedTime <= endDate | date |
472
+
473
+ **Responses**
474
+
475
+ | HTTP Code | Description | Schema |
476
+ |-----------|-------------|--------|
477
+ | 200 | OK | < [Task](#task) > array |
478
+ | 201 | Created | No Content |
479
+ | 401 | Unauthorized | No Content |
480
+ | 403 | Forbidden | No Content |
481
+ | 404 | Not Found | No Content |
482
+
483
+ **Example**
484
+
485
+ Request:
486
+
487
+ ```http
488
+ POST /open/v1/task/completed HTTP/1.1
489
+ Host: api.dida365.com
490
+ Authorization: Bearer {{token}}
491
+
492
+ {
493
+ "projectIds": ["69a850f41c20d2030e148fdf"],
494
+ "startDate": "2026-03-01T00:58:20.000+0000",
495
+ "endDate": "2026-03-05T10:58:20.000+0000"
496
+ }
497
+ ```
498
+
499
+ Response:
500
+
501
+ ```json
502
+ [
503
+ {
504
+ "id": "69a850f8b9061f374d54a046",
505
+ "projectId": "69a850f41c20d2030e148fdf",
506
+ "sortOrder": -1099511627776,
507
+ "title": "update",
508
+ "content": "",
509
+ "timeZone": "America/Los_Angeles",
510
+ "isAllDay": false,
511
+ "priority": 0,
512
+ "completedTime": "2026-03-04T23:58:20.000+0000",
513
+ "status": 2,
514
+ "etag": "t3kc5m5f",
515
+ "kind": "TEXT"
516
+ }
517
+ ]
518
+ ```
519
+
520
+ #### Filter Tasks
521
+
522
+ ```
523
+ POST /open/v1/task/filter
524
+ ```
525
+
526
+ Retrieves a list of tasks based on advanced filtering criteria, including project scope, date ranges, priority levels, tags, and status.
527
+
528
+ **Parameters**
529
+
530
+ | Type | Name | Description | Schema |
531
+ |------|------|-------------|--------|
532
+ | Body | **projectIds** | Filters tasks belonging to the specified project ID | list |
533
+ | Body | **startDate** | Filters tasks where the task's startDate >= startDate | date |
534
+ | Body | **endDate** | Filters tasks where the task's startDate <= endDate | date |
535
+ | Body | **priority** | Filters tasks by specific priority levels. Valid Values: None(0), Low(1), Medium(3), High(5) | list |
536
+ | Body | **tag** | Filters tasks that contain all of the specified tags | list |
537
+ | Body | **status** | Filters tasks by their current status codes (e.g., `[0]` for Open, `[2]` for Completed) | list |
538
+
539
+ **Responses**
540
+
541
+ | HTTP Code | Description | Schema |
542
+ |-----------|-------------|--------|
543
+ | 200 | OK | < [Task](#task) > array |
544
+ | 201 | Created | No Content |
545
+ | 401 | Unauthorized | No Content |
546
+ | 403 | Forbidden | No Content |
547
+ | 404 | Not Found | No Content |
548
+
549
+ **Example**
550
+
551
+ Request:
552
+
553
+ ```http
554
+ POST /open/v1/task/filter HTTP/1.1
555
+ Host: api.dida365.com
556
+ Authorization: Bearer {{token}}
557
+
558
+ {
559
+ "projectIds": ["69a850f41c20d2030e148fdf"],
560
+ "startDate": "2026-03-01T00:58:20.000+0000",
561
+ "endDate": "2026-03-06T10:58:20.000+0000",
562
+ "priority": [0],
563
+ "tag": ["urgent"],
564
+ "status": [0]
565
+ }
566
+ ```
567
+
568
+ Response:
569
+
570
+ ```json
571
+ [
572
+ {
573
+ "id": "69a85785b9061f3c217e9de6",
574
+ "projectId": "69a850f41c20d2030e148fdf",
575
+ "sortOrder": -2199023255552,
576
+ "title": "task1",
577
+ "content": "",
578
+ "desc": "",
579
+ "startDate": "2026-03-05T00:00:00.000+0000",
580
+ "dueDate": "2026-03-05T00:00:00.000+0000",
581
+ "timeZone": "America/Los_Angeles",
582
+ "isAllDay": false,
583
+ "priority": 0,
584
+ "status": 0,
585
+ "tags": ["tag"],
586
+ "etag": "cic6e3cg",
587
+ "kind": "TEXT"
588
+ },
589
+ {
590
+ "id": "69a8ea79b9061f4d803f6b32",
591
+ "projectId": "69a850f41c20d2030e148fdf",
592
+ "sortOrder": -3298534883328,
593
+ "title": "task2",
594
+ "content": "",
595
+ "startDate": "2026-03-05T00:00:00.000+0000",
596
+ "dueDate": "2026-03-05T00:00:00.000+0000",
597
+ "timeZone": "America/Los_Angeles",
598
+ "isAllDay": false,
599
+ "priority": 0,
600
+ "status": 0,
601
+ "tags": ["tag"],
602
+ "etag": "0nvpcxzh",
603
+ "kind": "TEXT"
604
+ }
605
+ ]
606
+ ```
607
+
608
+ ### Project
609
+
610
+ #### Get User Projects
611
+
612
+ ```
613
+ GET /open/v1/project
614
+ ```
615
+
616
+ **Responses**
617
+
618
+ | HTTP Code | Description | Schema |
619
+ |-----------|-------------|--------|
620
+ | 200 | OK | < [Project](#project) > array |
621
+ | 401 | Unauthorized | No Content |
622
+ | 403 | Forbidden | No Content |
623
+ | 404 | Not Found | No Content |
624
+
625
+ **Example**
626
+
627
+ Request:
628
+
629
+ ```http
630
+ GET /open/v1/project HTTP/1.1
631
+ Host: api.dida365.com
632
+ Authorization: Bearer {{token}}
633
+ ```
634
+
635
+ Response:
636
+
637
+ ```json
638
+ [
639
+ {
640
+ "id": "6226ff9877acee87727f6bca",
641
+ "name": "project name",
642
+ "color": "#F18181",
643
+ "closed": false,
644
+ "groupId": "6436176a47fd2e05f26ef56e",
645
+ "viewMode": "list",
646
+ "permission": "write",
647
+ "kind": "TASK"
648
+ }
649
+ ]
650
+ ```
651
+
652
+ #### Get Project By ID
653
+
654
+ ```
655
+ GET /open/v1/project/{projectId}
656
+ ```
657
+
658
+ **Parameters**
659
+
660
+ | Type | Name | Description | Schema |
661
+ |------|------|-------------|--------|
662
+ | Path | **projectId** *required* | Project identifier | string |
663
+
664
+ **Responses**
665
+
666
+ | HTTP Code | Description | Schema |
667
+ |-----------|-------------|--------|
668
+ | 200 | OK | [Project](#project) |
669
+ | 401 | Unauthorized | No Content |
670
+ | 403 | Forbidden | No Content |
671
+ | 404 | Not Found | No Content |
672
+
673
+ **Example**
674
+
675
+ Request:
676
+
677
+ ```http
678
+ GET /open/v1/project/{{projectId}} HTTP/1.1
679
+ Host: api.dida365.com
680
+ Authorization: Bearer {{token}}
681
+ ```
682
+
683
+ Response:
684
+
685
+ ```json
686
+ {
687
+ "id": "6226ff9877acee87727f6bca",
688
+ "name": "project name",
689
+ "color": "#F18181",
690
+ "closed": false,
691
+ "groupId": "6436176a47fd2e05f26ef56e",
692
+ "viewMode": "list",
693
+ "kind": "TASK"
694
+ }
695
+ ```
696
+
697
+ #### Get Project With Data
698
+
699
+ ```
700
+ GET /open/v1/project/{projectId}/data
701
+ ```
702
+
703
+ **Parameters**
704
+
705
+ | Type | Name | Description | Schema |
706
+ |------|------|-------------|--------|
707
+ | Path | **projectId** *required* | Project identifier, "inbox" | string |
708
+
709
+ **Responses**
710
+
711
+ | HTTP Code | Description | Schema |
712
+ |-----------|-------------|--------|
713
+ | 200 | OK | [ProjectData](#projectdata) |
714
+ | 401 | Unauthorized | No Content |
715
+ | 403 | Forbidden | No Content |
716
+ | 404 | Not Found | No Content |
717
+
718
+ **Example**
719
+
720
+ Request:
721
+
722
+ ```http
723
+ GET /open/v1/project/{{projectId}}/data HTTP/1.1
724
+ Host: api.dida365.com
725
+ Authorization: Bearer {{token}}
726
+ ```
727
+
728
+ Response:
729
+
730
+ ```json
731
+ {
732
+ "project": {
733
+ "id": "6226ff9877acee87727f6bca",
734
+ "name": "project name",
735
+ "color": "#F18181",
736
+ "closed": false,
737
+ "groupId": "6436176a47fd2e05f26ef56e",
738
+ "viewMode": "list",
739
+ "kind": "TASK"
740
+ },
741
+ "tasks": [
742
+ {
743
+ "id": "6247ee29630c800f064fd145",
744
+ "isAllDay": true,
745
+ "projectId": "6226ff9877acee87727f6bca",
746
+ "title": "Task Title",
747
+ "content": "Task Content",
748
+ "desc": "Task Description",
749
+ "timeZone": "America/Los_Angeles",
750
+ "repeatFlag": "RRULE:FREQ=DAILY;INTERVAL=1",
751
+ "startDate": "2019-11-13T03:00:00+0000",
752
+ "dueDate": "2019-11-14T03:00:00+0000",
753
+ "reminders": ["TRIGGER:P0DT9H0M0S", "TRIGGER:PT0S"],
754
+ "priority": 1,
755
+ "status": 0,
756
+ "completedTime": "2019-11-13T03:00:00+0000",
757
+ "sortOrder": 12345,
758
+ "items": [
759
+ {
760
+ "id": "6435074647fd2e6387145f20",
761
+ "status": 0,
762
+ "title": "Subtask Title",
763
+ "sortOrder": 12345,
764
+ "startDate": "2019-11-13T03:00:00+0000",
765
+ "isAllDay": false,
766
+ "timeZone": "America/Los_Angeles",
767
+ "completedTime": "2019-11-13T03:00:00+0000"
768
+ }
769
+ ]
770
+ }
771
+ ],
772
+ "columns": [
773
+ {
774
+ "id": "6226ff9e76e5fc39f2862d1b",
775
+ "projectId": "6226ff9877acee87727f6bca",
776
+ "name": "Column Name",
777
+ "sortOrder": 0
778
+ }
779
+ ]
780
+ }
781
+ ```
782
+
783
+ #### Create Project
784
+
785
+ ```
786
+ POST /open/v1/project
787
+ ```
788
+
789
+ **Parameters**
790
+
791
+ | Type | Name | Description | Schema |
792
+ |------|------|-------------|--------|
793
+ | Body | name *required* | Name of the project | string |
794
+ | Body | color | Color of project, e.g. `"#F18181"` | string |
795
+ | Body | sortOrder | Sort order value of the project | integer (int64) |
796
+ | Body | viewMode | View mode: `"list"`, `"kanban"`, `"timeline"` | string |
797
+ | Body | kind | Project kind: `"TASK"`, `"NOTE"` | string |
798
+
799
+ **Responses**
800
+
801
+ | HTTP Code | Description | Schema |
802
+ |-----------|-------------|--------|
803
+ | 200 | OK | [Project](#project) |
804
+ | 201 | Created | No Content |
805
+ | 401 | Unauthorized | No Content |
806
+ | 403 | Forbidden | No Content |
807
+ | 404 | Not Found | No Content |
808
+
809
+ **Example**
810
+
811
+ Request:
812
+
813
+ ```http
814
+ POST /open/v1/project HTTP/1.1
815
+ Host: api.dida365.com
816
+ Content-Type: application/json
817
+ Authorization: Bearer {{token}}
818
+
819
+ {
820
+ "name": "project name",
821
+ "color": "#F18181",
822
+ "viewMode": "list",
823
+ "kind": "task"
824
+ }
825
+ ```
826
+
827
+ Response:
828
+
829
+ ```json
830
+ {
831
+ "id": "6226ff9877acee87727f6bca",
832
+ "name": "project name",
833
+ "color": "#F18181",
834
+ "sortOrder": 0,
835
+ "viewMode": "list",
836
+ "kind": "TASK"
837
+ }
838
+ ```
839
+
840
+ #### Update Project
841
+
842
+ ```
843
+ POST /open/v1/project/{projectId}
844
+ ```
845
+
846
+ **Parameters**
847
+
848
+ | Type | Name | Description | Schema |
849
+ |------|------|-------------|--------|
850
+ | Path | projectId *required* | Project identifier | string |
851
+ | Body | name | Name of the project | string |
852
+ | Body | color | Color of the project | string |
853
+ | Body | sortOrder | Sort order value, default 0 | integer (int64) |
854
+ | Body | viewMode | View mode: `"list"`, `"kanban"`, `"timeline"` | string |
855
+ | Body | kind | Project kind: `"TASK"`, `"NOTE"` | string |
856
+
857
+ **Responses**
858
+
859
+ | HTTP Code | Description | Schema |
860
+ |-----------|-------------|--------|
861
+ | 200 | OK | [Project](#project) |
862
+ | 201 | Created | No Content |
863
+ | 401 | Unauthorized | No Content |
864
+ | 403 | Forbidden | No Content |
865
+ | 404 | Not Found | No Content |
866
+
867
+ **Example**
868
+
869
+ Request:
870
+
871
+ ```http
872
+ POST /open/v1/project/{{projectId}} HTTP/1.1
873
+ Host: api.dida365.com
874
+ Content-Type: application/json
875
+ Authorization: Bearer {{token}}
876
+
877
+ {
878
+ "name": "Project Name",
879
+ "color": "#F18181",
880
+ "viewMode": "list",
881
+ "kind": "TASK"
882
+ }
883
+ ```
884
+
885
+ Response:
886
+
887
+ ```json
888
+ {
889
+ "id": "6226ff9877acee87727f6bca",
890
+ "name": "Project Name",
891
+ "color": "#F18181",
892
+ "sortOrder": 0,
893
+ "viewMode": "list",
894
+ "kind": "TASK"
895
+ }
896
+ ```
897
+
898
+ #### Delete Project
899
+
900
+ ```
901
+ DELETE /open/v1/project/{projectId}
902
+ ```
903
+
904
+ **Parameters**
905
+
906
+ | Type | Name | Description | Schema |
907
+ |------|------|-------------|--------|
908
+ | Path | **projectId** *required* | Project identifier | string |
909
+
910
+ **Responses**
911
+
912
+ | HTTP Code | Description | Schema |
913
+ |-----------|-------------|--------|
914
+ | 200 | OK | No Content |
915
+ | 401 | Unauthorized | No Content |
916
+ | 403 | Forbidden | No Content |
917
+ | 404 | Not Found | No Content |
918
+
919
+ **Example**
920
+
921
+ Request:
922
+
923
+ ```http
924
+ DELETE /open/v1/project/{{projectId}} HTTP/1.1
925
+ Host: api.dida365.com
926
+ Authorization: Bearer {{token}}
927
+ ```
928
+
929
+ ## Definitions
930
+
931
+ ### ChecklistItem
932
+
933
+ | Name | Description | Schema |
934
+ |------|-------------|--------|
935
+ | **id** | Subtask identifier | string |
936
+ | **title** | Subtask title | string |
937
+ | **status** | The completion status of subtask. Normal: `0`, Completed: `1` | integer (int32) |
938
+ | **completedTime** | Subtask completed time in `"yyyy-MM-dd'T'HH:mm:ssZ"` format. **Example**: `"2019-11-13T03:00:00+0000"` | string (date-time) |
939
+ | **isAllDay** | All day | boolean |
940
+ | **sortOrder** | Subtask sort order. **Example**: `234444` | integer (int64) |
941
+ | **startDate** | Subtask start date time in `"yyyy-MM-dd'T'HH:mm:ssZ"` format. **Example**: `"2019-11-13T03:00:00+0000"` | string (date-time) |
942
+ | **timeZone** | Subtask timezone. **Example**: `"America/Los_Angeles"` | string |
943
+
944
+ ### Task
945
+
946
+ | Name | Description | Schema |
947
+ |------|-------------|--------|
948
+ | **id** | Task identifier | string |
949
+ | **projectId** | Task project id | string |
950
+ | **title** | Task title | string |
951
+ | **isAllDay** | All day | boolean |
952
+ | **completedTime** | Task completed time in `"yyyy-MM-dd'T'HH:mm:ssZ"` format. **Example**: `"2019-11-13T03:00:00+0000"` | string (date-time) |
953
+ | **content** | Task content | string |
954
+ | **desc** | Task description of checklist | string |
955
+ | **dueDate** | Task due date time in `"yyyy-MM-dd'T'HH:mm:ssZ"` format. **Example**: `"2019-11-13T03:00:00+0000"` | string (date-time) |
956
+ | **items** | Subtasks of Task | < [ChecklistItem](#checklistitem) > array |
957
+ | **priority** | Task priority. None: `0`, Low: `1`, Medium: `3`, High: `5` | integer (int32) |
958
+ | **reminders** | List of reminder triggers. **Example**: `["TRIGGER:P0DT9H0M0S", "TRIGGER:PT0S"]` | < string > array |
959
+ | **repeatFlag** | Recurring rules of task. **Example**: `"RRULE:FREQ=DAILY;INTERVAL=1"` | string |
960
+ | **sortOrder** | Task sort order. **Example**: `12345` | integer (int64) |
961
+ | **startDate** | Start date time in `"yyyy-MM-dd'T'HH:mm:ssZ"` format. **Example**: `"2019-11-13T03:00:00+0000"` | string (date-time) |
962
+ | **status** | Task completion status. Normal: `0`, Completed: `2` | integer (int32) |
963
+ | **timeZone** | Task timezone. **Example**: `"America/Los_Angeles"` | string |
964
+ | **kind** | `"TEXT"`, `"NOTE"`, `"CHECKLIST"` | string |
965
+
966
+ ### Project
967
+
968
+ | Name | Description | Schema |
969
+ |------|-------------|--------|
970
+ | **id** | Project identifier | string |
971
+ | **name** | Project name | string |
972
+ | **color** | Project color | string |
973
+ | **sortOrder** | Order value | integer (int64) |
974
+ | **closed** | Project closed | boolean |
975
+ | **groupId** | Project group identifier | string |
976
+ | **viewMode** | View mode: `"list"`, `"kanban"`, `"timeline"` | string |
977
+ | **permission** | `"read"`, `"write"` or `"comment"` | string |
978
+ | **kind** | `"TASK"` or `"NOTE"` | string |
979
+
980
+ ### Column
981
+
982
+ | Name | Description | Schema |
983
+ |------|-------------|--------|
984
+ | id | Column identifier | string |
985
+ | projectId | Project identifier | string |
986
+ | name | Column name | string |
987
+ | sortOrder | Order value | integer (int64) |
988
+
989
+ ### ProjectData
990
+
991
+ | Name | Description | Schema |
992
+ |------|-------------|--------|
993
+ | project | Project info | [Project](#project) |
994
+ | tasks | Undone tasks under project | < [Task](#task) > array |
995
+ | columns | Columns under project | < [Column](#column) > array |
996
+
997
+ ## Feedback and Support
998
+
999
+ If you have any questions or feedback regarding the Dida365 Open API documentation, please contact us at [support@dida365.com](mailto:support@dida365.com). We appreciate your input and will work to address any concerns or issues as quickly as possible. Thank you for choosing Dida!