ClawSkills logoClawSkills

Todoist

集成托管 OAuth 的 Todoist API。管理任务、项目、版块、标签和评论。当用户想要创建、更新、完成、

介绍

# Todoist

通过托管的 OAuth 身份验证访问 Todoist REST API v2。管理任务、项目、部分、标签和评论。

## Quick Start

```bash # List all tasks python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/todoist/rest/v2/tasks') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

## Base URL

``` https://gateway.maton.ai/todoist/rest/v2/{resource} ```

网关将请求代理到 `api.todoist.com/rest/v2` 并自动注入您的 OAuth 令牌。

## Authentication

所有请求都需要在 Authorization 请求头中提供 Maton API 密钥:

``` Authorization: Bearer $MATON_API_KEY ```

**Environment Variable:** 将您的 API 密钥设置为 `MATON_API_KEY`:

```bash export MATON_API_KEY="YOUR_API_KEY" ```

### Getting Your API Key

1. 在 [maton.ai](https://maton.ai) 登录或创建账户 2. 前往 [maton.ai/settings](https://maton.ai/settings) 3. 复制您的 API 密钥

## Connection Management

在 `https://ctrl.maton.ai` 管理您的 Todoist OAuth 连接。

### List Connections

```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections?app=todoist&status=ACTIVE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

### Create Connection

```bash python <<'EOF' import urllib.request, os, json data = json.dumps({'app': 'todoist'}).encode() req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Content-Type', 'application/json') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

### Get Connection

```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

**Response:** ```json { "connection": { "connection_id": "21fd90f9-5935-43cd-b6c8-bde9d915ca80", "status": "ACTIVE", "creation_time": "2025-12-08T07:20:53.488460Z", "last_updated_time": "2026-01-31T20:03:32.593153Z", "url": "https://connect.maton.ai/?session_token=...", "app": "todoist", "metadata": {} } } ```

在浏览器中打开返回的 `url` 以完成 OAuth 授权。

### Delete Connection

```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

### Specifying Connection

如果您有多个 Todoist 连接,请使用 `Maton-Connection` 请求头指定要使用的连接:

```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/todoist/rest/v2/tasks') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Maton-Connection', '21fd90f9-5935-43cd-b6c8-bde9d915ca80') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

如果省略,网关将使用默认(最早)的活动连接。

## API Reference

### Projects

#### List Projects

```bash GET /todoist/rest/v2/projects ```

**Response:** ```json [ { "id": "2366738772", "name": "Inbox", "color": "charcoal", "parent_id": null, "order": 0, "is_shared": false, "is_favorite": false, "is_inbox_project": true, "view_style": "list", "url": "https://app.todoist.com/app/project/..." } ] ```

#### Get Project

```bash GET /todoist/rest/v2/projects/{id} ```

#### Create Project

```bash POST /todoist/rest/v2/projects Content-Type: application/json

{ "name": "My Project", "color": "blue", "is_favorite": true, "view_style": "board" } ```

**Parameters:** - `name` (必需) - 项目名称 - `parent_id` - 用于嵌套的父项目 ID - `color` - 项目颜色 (例如 "red", "blue", "green") - `is_favorite` - 布尔值收藏状态 - `view_style` - "list" 或 "board" (默认: list)

**Example:** ```bash python <<'EOF' import urllib.request, os, json data = json.dumps({'name': 'My New Project', 'color': 'blue'}).encode() req = urllib.request.Request('https://gateway.maton.ai/todoist/rest/v2/projects', data=data, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Content-Type', 'application/json') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

#### Update Project

```bash POST /todoist/rest/v2/projects/{id} Content-Type: application/json

{ "name": "Updated Project Name", "color": "red" } ```

#### Delete Project

```bash DELETE /todoist/rest/v2/projects/{id} ```

成功时返回 204 No Content。

#### Get Project Collaborators

```bash GET /todoist/rest/v2/projects/{id}/collaborators ```

### Tasks

#### List Tasks

```bash GET /todoist/rest/v2/tasks ```

**Query Parameters:** | Parameter | Type | Description | |-----------|------|-------------| | `project_id` | string | 按项目筛选 | | `section_id` | string | 按部分筛选 | | `label` | string | 按标签名称筛选 | | `filter` | string | Todoist 筛选表达式 | | `ids` | string | 逗号分隔的任务 ID |

**Response:** ```json [ { "id": "9993408170", "content": "Buy groceries", "description": "", "project_id": "2366834771", "section_id": null, "parent_id": null, "order": 1, "priority": 2, "is_completed": false, "labels": [], "due": { "date": "2026-02-07", "string": "tomorrow", "lang": "en", "is_recurring": false }, "url": "https://app.todoist.com/app/task/9993408170", "comment_count": 0, "created_at": "2026-02-06T20:41:08.449320Z" } ] ```

#### Get Task

```bash GET /todoist/rest/v2/tasks/{id} ```

#### Create Task

```bash POST /todoist/rest/v2/tasks Content-Type: application/json

{ "content": "Buy groceries", "project_id": "2366834771", "priority": 2, "due_string": "tomorrow at 10am", "labels": ["shopping", "errands"] } ```

**Required Fields:** - `content` - 任务内容/标题

**Optional Fields:** - `description` - 任务描述 - `project_id` - 要添加任务到的项目 (默认为收件箱) - `section_id` - 项目内的部分 - `parent_id` - 子任务的父任务 ID - `labels` - 标签名称数组 - `priority` - 1 (普通) 到 4 (紧急) - `due_string` - 自然语言截止日期 ("tomorrow", "next Monday 3pm") - `due_date` - ISO 格式 YYYY-MM-DD - `due_datetime` - 带时区的 RFC3339 格式 - `assignee_id` - 被分配任务的用户 ID - `duration` - 任务持续时间 (整数) - `duration_unit` - "minute" 或 "day"

**Example:** ```bash python <<'EOF' import urllib.request, os, json data = json.dumps({ 'content': 'Complete project report', 'priority': 4, 'due_string': 'tomorrow at 5pm', 'labels': ['work', 'urgent'] }).encode() req = urllib.request.Request('https://gateway.maton.ai/todoist/rest/v2/tasks', data=data, method='POST') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Content-Type', 'application/json') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

#### Update Task

```bash POST /todoist/rest/v2/tasks/{id} Content-Type: application/json

{ "content": "Updated task content", "priority": 3 } ```

#### Close Task (Complete)

```bash POST /todoist/rest/v2/tasks/{id}/close ```

返回 204 No Content。对于循环任务,这会安排下一次的执行。

#### Reopen Task

```bash POST /todoist/rest/v2/tasks/{id}/reopen ```

返回 204 No Content。

#### Delete Task

```bash DELETE /todoist/rest/v2/tasks/{id} ```

返回 204 No Content。

### Sections

#### List Sections

```bash GET /todoist/rest/v2/sections GET /todoist/rest/v2/sections?project_id={project_id} ```

**Response:** ```json [ { "id": "214670251", "project_id": "2366834771", "order": 1, "name": "To Do" } ] ```

#### Get Section

```bash GET /todoist/rest/v2/sections/{id} ```

#### Create Section

```bash POST /todoist/rest/v2/sections Content-Type: application/json

{ "name": "In Progress", "project_id": "2366834771", "order": 2 } ```

**Required Fields:** - `name` - 部分名称 - `project_id` - 父项目 ID

#### Update Section

```bash POST /todoist/rest/v2/sections/{id} Content-Type: application/json

{ "name": "Updated Section Name" } ```

#### Delete Section

```bash DELETE /todoist/rest/v2/sections/{id} ```

返回 204 No Content。

### Labels

#### List Labels

```bash GET /todoist/rest/v2/labels ```

**Response:** ```json [ { "id": "2182980313", "name": "urgent", "color": "red", "order": 1, "is_favorite": false } ] ```

#### Get Label

```bash GET /todoist/rest/v2/labels/{id} ```

#### Create Label

```bash POST /todoist/rest/v2/labels Content-Type: application/json

{ "name": "work", "color": "blue", "is_favorite": true } ```

**Parameters:** - `name` (必需) - 标签名称 - `color` - 标签颜色 - `order` - 排序顺序 - `is_favorite` - 布尔值收藏状态

#### Update Label

```bash POST /todoist/rest/v2/labels/{id} Content-Type: application/json

{ "name": "updated-label", "color": "green" } ```

#### Delete Label

```bash DELETE /todoist/rest/v2/labels/{id} ```

返回 204 No Content。

### Comments

#### List Comments

```bash GET /todoist/rest/v2/comments?task_id={task_id} GET /todoist/rest/v2/comments?project_id={project_id} ```

**Note:** 需要 `task_id` 或 `project_id` 其中之一。

**Response:** ```json [ { "id": "3966541561", "task_id": "9993408170", "project_id": null, "content": "This is a comment", "posted_at": "2026-02-06T20:41:35.734376Z", "posted_by_id": "57402826" } ] ```

#### Get Comment

```bash GET /todoist/rest/v2/comments/{id} ```

#### Create Comment

```bash POST /todoist/rest/v2/comments Content-Type: application/json

{ "task_id": "9993408170", "content": "Don't forget to check the budget" } ```

**Required Fields:** - `content` - 评论文本 - `task_id` 或 `project_id` - 评论附加的位置

#### Update Comment

```bash POST /todoist/rest/v2/comments/{id} Content-Type: application/json

{ "content": "Updated comment text" } ```

#### Delete Comment

```bash DELETE /todoist/rest/v2/comments/{id} ```

返回 204 No Content。

## Priority Values

| Priority | Meaning | |----------|---------| | 1 | 普通 (默认) | | 2 | 中等 | | 3 | 高 | | 4 | 紧急 |

## Due Date Formats

每个请求仅使用以下格式之一:

- `due_string` - 自然语言:"tomorrow", "next Monday at 3pm", "every week" - `due_date` - 仅日期:"2026-02-15" - `due_datetime` - 完整日期时间:"2026-02-15T14:00:00Z"

## Code Examples

### JavaScript

```javascript // Create a task const response = await fetch('https://gateway.maton.ai/todoist/rest/v2/tasks', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ content: 'Review pull request', priority: 3, due_string: 'today at 5pm' }) }); const task = await response.json(); ```

### Python

```python import os import requests

# Create a task response = requests.post( 'https://gateway.maton.ai/todoist/rest/v2/tasks', headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}, json={ 'content': 'Review pull request', 'priority': 3, 'due_string': 'today at 5pm' } ) task = response.json() ```

## Notes

- 任务 ID 和项目 ID 是字符串,而不是整数 - 优先级 4 最高 (紧急),优先级 1 为普通 - 每个请求仅使用一种截止日期格式 (due_string, due_date 或 due_datetime) - 完成循环任务会安排下一次的执行 - 收件箱项目无法删除 - 重要:当将 curl 输出通过管道传递给 `jq` 或其他命令时,在某些 shell 环境中,`$MATON_API_KEY` 等环境变量可能无法正确展开

## Error Handling

| Status | Meaning | |--------|---------| | 204 | 成功 (无内容) - 针对 close, reopen, delete 操作 | | 400 | 请求无效或缺少 Todoist 连接 | | 401 | Maton API 密钥无效或缺失 | | 404 | 资源未找到 | | 429 | 速率受限 | | 4xx/5xx | 来自 Todoist API 的透传错误 |

### Troubleshooting: API Key Issues

1. 检查是否已设置 `MATON_API_KEY` 环境变量:

```bash echo $MATON_API_KEY ```

2. 通过列出连接来验证 API 密钥是否有效:

```bash python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF ```

### Troubleshooting: Invalid App Name

1. 确保您的 URL 路径以 `todoist` 开头。例如:

- 正确: `https://gateway.maton.ai/todoist/rest/v2/tasks` - 错误: `https://gateway.maton.ai/rest/v2/tasks`

## Resources

- [Todoist REST API v2 Documentation](https://developer.todoist.com/rest/v2) - [Todoist API v1 Documentation](https://developer.todoist.com/api/v1) - [Todoist Filter Syntax](https://todoist.com/help/articles/introduction-to-filters) - [Todoist OAuth Documentation](https://developer.todoist.com/guides/#oauth) - [Maton Community](https://discord.com/invite/dBfFAcefs2) - [Maton Support](mailto:[email protected])

更多产品