Todoist CRUD
Wraps the Todoist REST API v1 via a bundled Python script. Token: ${CLAUDE_SKILL_DIR}/.apikey (or TODOIST_API_TOKEN env var, takes precedence).
Path conventions
${CLAUDE_SKILL_DIR} = directory holding this SKILL.md. Resolve once per shell:
export CLAUDE_SKILL_DIR=<path reported by the Skill tool's "Base directory">
The script self-locates via __file__; the env var is only for shell invocations.
Invocation
python3 "${CLAUDE_SKILL_DIR}/scripts/todoist.py" <resource> <action> [args...]
Resources: tasks, projects, sections, labels, comments, reminders. Successful calls print JSON; errors print HTTP <code> to stderr and exit non-zero.
References (load on demand)
- references/api-reference.md — endpoint matrix, body fields, date-parsing notes, Premium-only details, Sync API (filters), error codes, soft-delete semantics
- references/filter-system.md — the user's deliberate 8-filter / label system. Source of truth for "what should I do now?" / weekly review / prioritization questions
- references/reminders.md — reminders write API (Premium-gated; load when user upgrades or for read-side audit)
Common playbooks
Add a task
python3 "${CLAUDE_SKILL_DIR}/scripts/todoist.py" tasks add "買牛奶" --due "tomorrow 9am" --priority 2
--dueaccepts English natural-language orYYYY-MM-DD. Chinese relative dates fail — resolve to absolute date yourself before calling. Details inapi-reference.md§ Date parsing notes.--priority1 (lowest) → 4 (highest, p1 in UI).--labelscomma-separated.--project-idto target a project (resolve name → id withprojects list).
Today's tasks
python3 "${CLAUDE_SKILL_DIR}/scripts/todoist.py" tasks list --filter "today"
Filter strings: overdue, 7 days, p1, @label, #Project. Combine with & |.
Complete / reschedule / edit
python3 "${CLAUDE_SKILL_DIR}/scripts/todoist.py" tasks close <id>
python3 "${CLAUDE_SKILL_DIR}/scripts/todoist.py" tasks update <id> --due "friday"
python3 "${CLAUDE_SKILL_DIR}/scripts/todoist.py" tasks update <id> --content "new title" --priority 3
reopen to un-complete, delete to remove. Update only flags you pass — omitted fields untouched.
Premium-only operations
--deadline-date (tasks) and reminders add/update return HTTP 403 PREMIUM_ONLY on Free. Don't call. Free-tier substitutes:
- Day-of reminder → just
--due "YYYY-MM-DD HH:MM"(Todoist auto-creates the reminder). - T-N pre-event nudge → create a separate prep task due on the T-N date.
Full Premium-gate behavior + read-side ops (work on Free): see api-reference.md § Premium-only writes and references/reminders.md.
Project / label bookkeeping
python3 "${CLAUDE_SKILL_DIR}/scripts/todoist.py" projects list
python3 "${CLAUDE_SKILL_DIR}/scripts/todoist.py" projects add "Side project"
python3 "${CLAUDE_SKILL_DIR}/scripts/todoist.py" labels list
python3 "${CLAUDE_SKILL_DIR}/scripts/todoist.py" labels add "deep-work"
Workflow guidance
- Resolve names → IDs first. Todoist uses numeric IDs.
listthe resource, match byname/content, act on theid. close>deletefor completed tasks (preserves history). Confirm beforedelete— irreversible.- Soft-delete:
DELETEflipsis_deleted: true; subsequentGETreturns 200 with tombstone. Script exits 2 with stderr warning. Treat exit 2 as "gone". - Token errors (HTTP 401/403): regenerate at Todoist Settings → Integrations → Developer; write to
${CLAUDE_SKILL_DIR}/.apikey. - Rate limit: ~450 req / 15 min. For bulk reads, prefer
tasks list --ids "1,2,3"over loops ofget.
Token file
${CLAUDE_SKILL_DIR}/.apikey, mode 600. Rotate:
printf '%s' "<new-token>" > "${CLAUDE_SKILL_DIR}/.apikey"
chmod 600 "${CLAUDE_SKILL_DIR}/.apikey"
Or export TODOIST_API_TOKEN=... to override without touching the file.