@ticktick/ticktick-cli
v0.1.8
Published
Command-line interface for TickTick
Readme
TickTick CLI
Command-line tool for TickTick, written in TypeScript. It wraps TickTick Open API v1 with a convenient CLI.
Install
npm install -g @ticktick/ticktick-cliFrom source (build and link globally):
git clone https://github.com/TickTeam/ticktick-cli.git
cd ticktick-cli
npm install
npm run build
npm linkAfter that, the ticktick command is available in your terminal.
Authentication
The CLI supports two authentication methods: OAuth PKCE (recommended) and manual Token.
OAuth PKCE (Recommended)
OAuth (PKCE) is the recommended way—no client secret required. It opens a browser for TickTick authorization.
ticktick auth loginToken (Headless Environments)
If the environment is headless (no browser available) or you cannot use browser-based OAuth, you can log in via an access token directly.
Getting a Token: Log in to the TickTick web app, click your avatar in the top-left corner, and go to Settings > Account > API Token to create and copy a token.
ticktick auth token <token>Auth subcommands
ticktick auth login # OAuth browser login (recommended)
ticktick auth token <token> # set access token directly (for headless environments)
ticktick auth status # see if you are logged in
ticktick auth logout # clear the stored tokenCommands
Tasks
# Fetch a task
ticktick task get <projectId> <taskId>
# Create a task
ticktick task create --title "Buy milk" --project <projectId>
ticktick task create --title "Meeting" --project <projectId> --priority 5 --due-date "2026-03-10T09:00:00+0000"
ticktick task create --title "Review" --project <projectId> --tags work,urgent
# Update a task
ticktick task update <taskId> --id <taskId> --project <projectId> --title "Updated title"
ticktick task update <taskId> --id <taskId> --project <projectId> --tags work,urgent
# Complete a task
ticktick task complete <projectId> <taskId>
# Delete a task
ticktick task delete <projectId> <taskId>
# Move tasks between projects
ticktick task move --from <sourceProjectId> --to <destProjectId> --task <taskId>
# List completed tasks
ticktick task completed --projects <projectId> --start-date "2026-03-01T00:00:00+0000" --end-date "2026-03-09T23:59:59+0000"
# Filter tasks
ticktick task filter --projects <projectId> --priority 3,5 --status 0Projects
ticktick project list # list all projects
ticktick project get <projectId> # project details
ticktick project data <projectId> # project with tasks and columns
ticktick project create --name "Work" --color "#F18181" --view-mode list --kind TASK
ticktick project update <projectId> --name "New Name" --color "#4AB8A9"
ticktick project delete <projectId>Habit
# Get a habit
ticktick habit get <habitId>
# List habits
ticktick habit list
# Create a habit
ticktick habit create --name "Drink water" --goal 8 --unit cups --repeat "RRULE:FREQ=DAILY;INTERVAL=1"
# Update a habit
ticktick habit update <habitId> --name "Drink more water" --goal 10
# Create or update a check-in
ticktick habit checkin <habitId> --stamp 20260407 --value 1 --goal 8
# Query check-ins in a date range
ticktick habit checkins --habits <habitId1>,<habitId2> --from 20260401 --to 20260430Focus
# Get one focus record
ticktick focus get <focusId> --type pomodoro
# List focus records in a time range (max 30 days)
ticktick focus list --from "2026-04-01T00:00:00+0000" --to "2026-04-30T23:59:59+0000" --type 0
# Delete one focus record
ticktick focus delete <focusId> --type timingJSON output
Add --json to any command to get raw API JSON:
ticktick project list --json
ticktick task get <projectId> <taskId> --jsonFor all options: ticktick --help and ticktick <command> --help.
API mapping
| Command | Endpoint |
| ---------------- | -------------------------------------------------- |
| task get | GET /project/{projectId}/task/{taskId} |
| task create | POST /task |
| task update | POST /task/{taskId} |
| task complete | POST /project/{projectId}/task/{taskId}/complete |
| task delete | DELETE /project/{projectId}/task/{taskId} |
| task move | POST /task/move |
| task completed | POST /task/completed |
| task filter | POST /task/filter |
| project list | GET /project |
| project get | GET /project/{projectId} |
| project data | GET /project/{projectId}/data |
| project create | POST /project |
| project update | POST /project/{projectId} |
| project delete | DELETE /project/{projectId} |
| habit get | GET /habit/{habitId} |
| habit list | GET /habit |
| habit create | POST /habit |
| habit update | POST /habit/{habitId} |
| habit checkin | POST /habit/{habitId}/checkin |
| habit checkins | GET /habit/checkins |
| focus get | GET /focus/{focusId}?type={type} |
| focus list | GET /focus?from={from}&to={to}&type={type} |
| focus delete | DELETE /focus/{focusId}?type={type} |
JSON fields and CLI mapping
The API mapping table shows which HTTP calls each command uses. With --json (see JSON output), the CLI prints the same objects the API returns—field names are camelCase. task create / task update send the same field names in the request body, aligned with their long options below.
Task
Appears in task get … --json, task create / task update with --json, each line of task completed / task filter with --json, and under tasks in project data … --json.
| Field | Meaning | CLI (create / update) |
| ------------------------- | ----------------------------------------------------------------- | ----------------------------------------------- |
| id | Task id (hex ObjectId string) | update only: positional <taskId> and --id |
| projectId | Owning project | --project |
| sortOrder | Order in the list | --sort-order |
| title | Short title; use content for longer text | --title |
| content | Main body for normal/note-style tasks | --content |
| desc | Description for checklist-style tasks | --desc |
| startDate / dueDate | Schedule; if dueDate ≠ startDate, the API treats it as a span | --start-date, --due-date |
| timeZone | Time zone | --time-zone |
| isAllDay | All-day task | --all-day |
| priority | 0 none, 1 low, 3 medium, 5 high | --priority |
| reminders | Reminder trigger strings (format below) | --reminders |
| repeatFlag | Recurrence rule: RRULE or ERULE (format below) | --repeat |
| completedTime | When completed | — |
| status | 0 open, -1 abandoned, 2 completed | — |
| items | Checklist items | --items (see Checklist item) |
| tags | Tags | --tags (comma-separated) |
| columnId / columnName | Kanban column | — |
| parentId / childIds | Subtask links | — |
| assignor | Assignor metadata | — |
| etag | Optimistic locking on the server | — |
| kind | e.g. TASK, NOTE, or CHECKLIST | — |
reminders format
Each element must match this pattern:
TRIGGER(;RELATED=START|END)?:(-)?P[nY][nM][nW][nD][T[nH][nM][nS]]
- TRIGGER — required prefix.
;RELATED=STARTor;RELATED=END— optional; whether the trigger is relative to the task start or end time.-after the colon — optional; the trigger fires before the reference time. If omitted, it fires after.P… — duration designator;nYnMnWnDyears, months, weeks, days;Tseparates date and time parts;nHnMnShours, minutes, seconds (similar in spirit to ISO-8601 duration, with direction and reference semantics).
Examples:
| String | Meaning |
| ------ | ------- |
| TRIGGER:-PT60M | 60 minutes before the reference time |
| TRIGGER:-P1DT2H | 1 day and 2 hours before |
| TRIGGER;RELATED=END:-PT15M | 15 minutes before the end time |
| TRIGGER:PT0S | “On time” (at the reference instant) |
repeatFlag format
Must be a single valid recurrence string. Use:
RRULE— standard recurrence (RFC-style).ERULE— custom or advanced recurrence.
Do not mix RRULE and ERULE in one value.
Examples:
RRULE:FREQ=DAILYRRULE:FREQ=WEEKLY;BYDAY=MO,WEERULE:NAME=CUSTOM;BYDATE=20260325,20260330
Checklist item (items[])
For checklist-style tasks, each entry in items is one checklist item:
| Field | Meaning |
| ---------------------------------------------------- | -------------------------------- |
| id | Checklist item id (hex ObjectId) |
| status | 0 not done, 1 done |
| title | Checklist item text |
| sortOrder | Order among checklist items |
| startDate, isAllDay, timeZone, completedTime | Optional time metadata |
Project
Returned by project list / project get --json and as project inside project data --json. project create / project update set the same kind of fields.
| Field | Meaning | CLI |
| ------------ | ------------------------------- | ------------------------------------------ |
| id | Project id (hex ObjectId) | get, update, data, delete argument |
| name | Display name | --name |
| color | Color | --color |
| sortOrder | Sidebar order | — |
| closed | Closed/archived | — |
| groupId | Group/folder id | — |
| viewMode | list, kanban, or timeline | --view-mode |
| permission | read, comment, or write | — |
| kind | TASK or NOTE | --kind |
Kanban column (columns[])
Inside project data … --json, array columns:
| Field | Meaning |
| ----------- | ------------------------ |
| id | Column id (hex ObjectId) |
| projectId | Owning project |
| name | Column title |
| sortOrder | Order on the board |
project data root
| Field | Meaning |
| --------- | ------------------------------------------- |
| project | One Project object |
| tasks | Incomplete Task objects in that project |
| columns | Kanban columns for that project |
task completed body
Maps to task completed options (see API mapping → POST /task/completed):
| JSON field | Flag |
| ----------------------- | --------------------------------------- |
| projectIds | --projects (comma-separated) |
| startDate / endDate | --start-date, --end-date (ISO 8601) |
task filter body
Maps to task filter options (POST /task/filter):
| JSON field | Flag |
| ----------------------- | ---------------------------------------------------------- |
| projectIds | --projects |
| startDate / endDate | --start-date, --end-date |
| priority | --priority (comma-separated: 0, 1, 3, 5) |
| tag | --tag (comma-separated) |
| status | --status (comma-separated; e.g. 0 open, 2 completed) |
task move body
Each repetition of --from, --to, and --task (same count) becomes one object with fromProjectId, toProjectId, and taskId. The API allows an optional sortOrder in the destination list; the CLI does not set it.
For AI Agents
Instructions and skill definitions for AI agents using this CLI can be found in skills/SKILL.md.
Development
npm install
npm run build # compile
npm run dev # watch mode
npm run type-check # type check
npm test # run testsLicense
MIT
