todoist-api

This skill provides procedural guidance for working with the Todoist REST API v2 via curl and jq.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "todoist-api" with this command: npx skills add doggy8088/agent-skills/doggy8088-agent-skills-todoist-api

Todoist API Skill

This skill provides procedural guidance for working with the Todoist REST API v2 via curl and jq.

Authentication

Token Resolution

Resolve the API token in this order:

  • Check environment variable TODOIST_API_TOKEN

  • Check if the user has provided a token in the conversation context

  • If neither is available, use AskUserQuestion (or similar tool) to request the token from the user

To verify a token exists in the environment:

[ -n "$TODOIST_API_TOKEN" ] && echo "Token available" || echo "Token not set"

Making Authenticated Requests

All requests require the Authorization header with Bearer token:

curl -s -H "Authorization: Bearer $TODOIST_API_TOKEN"
"https://api.todoist.com/rest/v2/ENDPOINT"

For POST requests with JSON body, include Content-Type:

curl -s -X POST
-H "Authorization: Bearer $TODOIST_API_TOKEN"
-H "Content-Type: application/json"
-d '{"key": "value"}'
"https://api.todoist.com/rest/v2/ENDPOINT"

Base URL

All REST API v2 endpoints use: https://api.todoist.com/rest/v2/

Confirmation Requirement

Before executing any destructive action (DELETE, close, update, archive), always ask the user for confirmation using AskUserQuestion or similar tool. A single confirmation suffices for a logical group of related actions.

Destructive actions include:

  • Deleting tasks, projects, sections, labels, or comments

  • Closing (completing) tasks

  • Updating existing resources

  • Archiving projects

Read-only operations (GET requests) do not require confirmation.

Endpoints Reference

Tasks

Operation Method Endpoint

List active tasks GET /tasks

Get task GET /tasks/{id}

Create task POST /tasks

Update task POST /tasks/{id}

Close task POST /tasks/{id}/close

Reopen task POST /tasks/{id}/reopen

Delete task DELETE /tasks/{id}

Task filters (query params for GET /tasks):

  • project_id

  • Filter by project

  • section_id

  • Filter by section

  • label

  • Filter by label name

  • filter

  • Todoist filter query (e.g., "today", "overdue")

Task creation/update fields:

  • content (required for creation) - Task text

  • description

  • Additional details

  • project_id , section_id , parent_id

  • Organisation

  • priority

  • 1 (normal) to 4 (urgent)

  • due_string

  • Natural language ("tomorrow", "every monday")

  • due_date

  • YYYY-MM-DD format

  • due_datetime

  • RFC3339 format

  • labels

  • Array of label names

  • assignee_id

  • For shared projects

  • duration , duration_unit

  • Estimated time

Projects

Operation Method Endpoint

List projects GET /projects

Get project GET /projects/{id}

Create project POST /projects

Update project POST /projects/{id}

Archive project POST /projects/{id}/archive

Unarchive project POST /projects/{id}/unarchive

Delete project DELETE /projects/{id}

List collaborators GET /projects/{id}/collaborators

Project fields:

  • name (required for creation)

  • parent_id

  • For nested projects

  • color

  • Colour name (e.g., "berry_red", "blue")

  • is_favorite

  • Boolean

  • view_style

  • "list" or "board"

Sections

Operation Method Endpoint

List sections GET /sections

Get section GET /sections/{id}

Create section POST /sections

Update section POST /sections/{id}

Delete section DELETE /sections/{id}

Section filters (query params for GET):

  • project_id
  • Filter by project (recommended)

Section fields:

  • name (required)

  • project_id (required for creation)

  • order

  • Position within project

Labels

Operation Method Endpoint

List personal labels GET /labels

Get label GET /labels/{id}

Create label POST /labels

Update label POST /labels/{id}

Delete label DELETE /labels/{id}

List shared labels GET /shared_labels

Rename shared label POST /shared_labels/{name}/rename

Remove shared label DELETE /shared_labels/{name}

Label fields:

  • name (required)

  • color

  • Colour name

  • order

  • Display order

  • is_favorite

  • Boolean

Comments

Operation Method Endpoint

List comments GET /comments

Get comment GET /comments/{id}

Create comment POST /comments

Update comment POST /comments/{id}

Delete comment DELETE /comments/{id}

Comment filters (query params for GET):

  • task_id

  • Comments on a task (required if no project_id)

  • project_id

  • Comments on a project (required if no task_id)

Comment fields:

  • content (required) - Markdown supported

  • task_id or project_id (one required for creation)

Pagination

Some endpoints return paginated results. Handle pagination by checking for a next_cursor field in the response and making subsequent requests with the cursor parameter.

Pagination Pattern

Initial request

response=$(curl -s -H "Authorization: Bearer $TODOIST_API_TOKEN"
"https://api.todoist.com/rest/v2/ENDPOINT")

Check for more results

next_cursor=$(echo "$response" | jq -r '.next_cursor // empty')

If cursor exists, fetch next page

if [ -n "$next_cursor" ]; then curl -s -H "Authorization: Bearer $TODOIST_API_TOKEN"
"https://api.todoist.com/rest/v2/ENDPOINT?cursor=$next_cursor" fi

Complete Data Retrieval Loop

To retrieve all data when pagination is involved:

all_results="[]" cursor=""

while true; do if [ -z "$cursor" ]; then response=$(curl -s -H "Authorization: Bearer $TODOIST_API_TOKEN"
"https://api.todoist.com/rest/v2/ENDPOINT") else response=$(curl -s -H "Authorization: Bearer $TODOIST_API_TOKEN"
"https://api.todoist.com/rest/v2/ENDPOINT?cursor=$cursor") fi

Merge results (adjust .items or root array based on endpoint)

items=$(echo "$response" | jq '.items // .') all_results=$(echo "$all_results $items" | jq -s 'add')

Check for next page

cursor=$(echo "$response" | jq -r '.next_cursor // empty') has_more=$(echo "$response" | jq -r '.has_more // false')

if [ "$has_more" != "true" ] || [ -z "$cursor" ]; then break fi done

echo "$all_results"

Common Patterns

List All Tasks in a Project

curl -s -H "Authorization: Bearer $TODOIST_API_TOKEN"
"https://api.todoist.com/rest/v2/tasks?project_id=PROJECT_ID" | jq '.'

Create a Task with Due Date

curl -s -X POST
-H "Authorization: Bearer $TODOIST_API_TOKEN"
-H "Content-Type: application/json"
-d '{"content": "Task name", "due_string": "tomorrow", "priority": 2}'
"https://api.todoist.com/rest/v2/tasks"

Complete a Task

curl -s -X POST
-H "Authorization: Bearer $TODOIST_API_TOKEN"
"https://api.todoist.com/rest/v2/tasks/TASK_ID/close"

Get Today's Tasks

curl -s -H "Authorization: Bearer $TODOIST_API_TOKEN"
"https://api.todoist.com/rest/v2/tasks?filter=today" | jq '.'

Get Overdue Tasks

curl -s -H "Authorization: Bearer $TODOIST_API_TOKEN"
"https://api.todoist.com/rest/v2/tasks?filter=overdue" | jq '.'

Error Handling

Check HTTP status codes and handle errors appropriately:

  • 200

  • Success with response body

  • 204

  • Success, no content

  • 400

  • Bad request (check parameters)

  • 401

  • Authentication failed (check token)

  • 403

  • Forbidden (insufficient permissions)

  • 404

  • Resource not found

  • 429

  • Rate limited (wait and retry)

  • 5xx

  • Server error (safe to retry)

Example with Error Handling

response=$(curl -s -w "\n%{http_code}"
-H "Authorization: Bearer $TODOIST_API_TOKEN"
"https://api.todoist.com/rest/v2/tasks")

http_code=$(echo "$response" | tail -1) body=$(echo "$response" | sed '$d')

if [ "$http_code" -ge 200 ] && [ "$http_code" -lt 300 ]; then echo "$body" | jq '.' else echo "Error: HTTP $http_code" echo "$body" fi

Idempotency

For safe retries on write operations, include the X-Request-Id header (max 36 characters):

curl -s -X POST
-H "Authorization: Bearer $TODOIST_API_TOKEN"
-H "Content-Type: application/json"
-H "X-Request-Id: $(uuidgen)"
-d '{"content": "New task"}'
"https://api.todoist.com/rest/v2/tasks"

Duplicate requests with the same X-Request-Id are discarded by the server.

Completed Tasks

The REST API v2 /tasks endpoint returns only active tasks. For completed tasks, use the Sync API or the newer unified API v1 endpoints:

  • GET /tasks/completed/by_completion_date

  • Retrieve by completion date

  • GET /tasks/completed/by_due_date

  • Retrieve by original due date

See references/completed-tasks.md for details on retrieving completed task history.

Additional Reference

For detailed information on specific topics, consult:

  • references/completed-tasks.md

  • Retrieving completed task history

  • references/filters.md

  • Todoist filter query syntax

Workflow Summary

  • Resolve token - Environment, context, or ask user

  • Verify authentication - Test with a simple GET request

  • Read operations - Execute directly without confirmation

  • Write operations - Ask for confirmation before executing

  • Handle pagination - Loop with cursor for complete data

  • Parse responses - Use jq to extract and format data

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Automation

todoist-api

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

copilot-sdk

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

markdown-converter

No summary provided by upstream source.

Repository SourceNeeds Review
Automation

beautiful-mermaid

No summary provided by upstream source.

Repository SourceNeeds Review