Everything an AI agent can do with the Todoist API.

A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.

Endpoints31
API versionv1
Last updated23 June 2026
Orientation

How the Todoist API works.

The Todoist API is how an app or AI agent works with a Todoist account: adding a task, completing one, organizing tasks into projects and sections, and tagging them with labels. Access is granted through a token, either a personal token or an OAuth grant whose scopes set whether a call can read, write, add tasks, or delete. A change in an account can be pushed to a registered endpoint, so an integration learns about activity without polling.

31Endpoints
6Capability groups
12Read
19Write
5Permissions
Authentication
Todoist authenticates every call with a Bearer token. An integration acting for other people uses OAuth 2.0 and requests a set of scopes; a personal script can use the account's own personal API token from integration settings, which carries full access to that one account. Both are sent in the Authorization header the same way.
Permissions
OAuth scopes set what a token can do. data:read is read-only, data:read_write is full read and write, task:add only adds tasks, data:delete allows deleting tasks, labels, and filters, and project:delete is a separate scope required to delete projects. A request that exceeds the token's scopes returns a 403.
Versioning
Todoist now runs one unified API under a single version that merges its former task and sync interfaces. There is no dated version string to pin, and the older REST v2 and Sync v9 interfaces are deprecated in favour of it.
Data model
Todoist is organized around tasks, which live in projects and optional sections, carry labels, and can hold comments. The unified API exposes both resource-style endpoints for these objects and a /sync endpoint that batches up to 100 read or write commands in one request. A change in an account can be pushed to a registered webhook.
Connect & authenticate

Connection & authentication methods.

How an app or AI agent connects to Todoist determines what it can reach. There is a route for making calls, a route for receiving events, and a hosted server that exposes Todoist tools to agents, and each is governed by the token behind it and the permissions that token carries.

Ways to connect

Unified REST API

The unified API takes JSON request bodies, returns JSON, and serves both the resource-style endpoints and the batched sync endpoint, at https://api.todoist.com/api/v1. A call authenticates with a Bearer token, either a personal API token or an OAuth access token. The /sync endpoint accepts up to 100 commands in one request for efficient bulk reads and writes.

Best forConnecting an app or AI agent to Todoist.
Governed byThe token and the OAuth scopes it carries.
Docs ↗

Webhooks

Todoist POSTs a JSON payload to an HTTPS endpoint registered on an OAuth app when a subscribed event happens, like a task being added or completed. The payload names the event in an event_name field and carries the changed object in event_data. The receiver verifies the X-Todoist-Hmac-SHA256 header, an HMAC of the raw body computed with the app's client secret, to confirm the request came from Todoist.

Best forReceiving Todoist events at an app or AI agent.
Governed byThe OAuth app's client secret and the events it subscribes to.
Docs ↗

MCP server

Doist, the maker of Todoist, publishes an official hosted Model Context Protocol server at https://ai.todoist.net/mcp that exposes Todoist tools to AI agents and LLM clients. It authenticates through a browser-based OAuth flow on first use, and covers tasks, projects, sections, comments, and labels. It is early-stage, with more tools planned.

Best forConnecting an AI agent to Todoist through MCP.
Governed byThe OAuth grant and the scopes it carries.
Docs ↗
Authentication

OAuth 2.0

OAuth uses the standard authorization-code flow, where a person grants an app a chosen set of scopes and the app exchanges the resulting code for an access token. The scopes set what the token can do: data:read for read-only access, data:read_write for full read and write, task:add to only add tasks, data:delete to delete tasks, labels, and filters, and project:delete to delete projects. This is the route for an integration acting on behalf of other people.

TokenOAuth access token (Bearer)
Best forApps acting for many users, with least-privilege scopes.
Docs ↗

Personal API token

Each Todoist user has a personal API token, found in the app's integration settings, that grants full access to that one account. It is sent as a Bearer token the same way an OAuth token is. It carries no scope limits, so it reaches everything the account can, which makes it best for personal scripts rather than shared integrations.

TokenPersonal API token (Bearer)
Best forPersonal scripts and single-account automation.
Docs ↗
Endpoint reference

Every Todoist API method.

Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.

MethodEndpointWhat it doesAccessPermissionVersion

Tasks

Methods for getting, listing, creating, updating, completing, and deleting tasks.10

Read-only. Returns only active tasks; completed tasks come from the completed endpoint.

Acts ontask
Permission (capability)data:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read-only.

Acts ontask
Permission (capability)data:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Granted by task:add on its own, or by data:read_write which includes it.

Acts ontask
Permission (capability)task:add
VersionAvailable since the API’s base version
Webhook eventitem:added
Rate limitStandard limits apply

Parses input the same way the Todoist quick-add box does. Needs task:add or data:read_write.

Acts ontask
Permission (capability)task:add
VersionAvailable since the API’s base version
Webhook eventitem:added
Rate limitStandard limits apply

Needs data:read_write.

Acts ontask
Permission (capability)data:read_write
VersionAvailable since the API’s base version
Webhook eventitem:updated
Rate limitStandard limits apply

Needs data:read_write.

Acts ontask
Permission (capability)data:read_write
VersionAvailable since the API’s base version
Webhook eventitem:updated
Rate limitStandard limits apply

Needs data:read_write. Completing a recurring task advances it to the next occurrence instead.

Acts ontask
Permission (capability)data:read_write
VersionAvailable since the API’s base version
Webhook eventitem:completed
Rate limitStandard limits apply

Needs data:read_write.

Acts ontask
Permission (capability)data:read_write
VersionAvailable since the API’s base version
Webhook eventitem:uncompleted
Rate limitStandard limits apply

Read-only. Returns tasks already completed, which the active list endpoint excludes.

Acts ontask
Permission (capability)data:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Irreversible, and removes sub-tasks too. Needs data:delete.

Acts ontask
Permission (capability)data:delete
VersionAvailable since the API’s base version
Webhook eventitem:deleted
Rate limitStandard limits apply

Projects

Methods for working with projects, the top-level containers for tasks.5

Read-only.

Acts onproject
Permission (capability)data:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read-only.

Acts onproject
Permission (capability)data:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Needs data:read_write.

Acts onproject
Permission (capability)data:read_write
VersionAvailable since the API’s base version
Webhook eventproject:added
Rate limitStandard limits apply

Needs data:read_write.

Acts onproject
Permission (capability)data:read_write
VersionAvailable since the API’s base version
Webhook eventproject:updated
Rate limitStandard limits apply

Irreversible, and removes every task and section in the project. Needs the dedicated project:delete scope, separate from data:delete.

Acts onproject
Permission (capability)project:delete
VersionAvailable since the API’s base version
Webhook eventproject:deleted
Rate limitStandard limits apply

Sections

Methods for working with sections, the groupings of tasks inside a project.5

Read-only.

Acts onsection
Permission (capability)data:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read-only.

Acts onsection
Permission (capability)data:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Needs data:read_write.

Acts onsection
Permission (capability)data:read_write
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Needs data:read_write.

Acts onsection
Permission (capability)data:read_write
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Needs data:delete.

Acts onsection
Permission (capability)data:delete
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Comments

Methods for working with comments attached to tasks and projects.5

Read-only. Requires a task_id or project_id.

Acts oncomment
Permission (capability)data:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read-only.

Acts oncomment
Permission (capability)data:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Needs data:read_write.

Acts oncomment
Permission (capability)data:read_write
VersionAvailable since the API’s base version
Webhook eventnote:added
Rate limitStandard limits apply

Needs data:read_write.

Acts oncomment
Permission (capability)data:read_write
VersionAvailable since the API’s base version
Webhook eventnote:updated
Rate limitStandard limits apply

Needs data:delete.

Acts oncomment
Permission (capability)data:delete
VersionAvailable since the API’s base version
Webhook eventnote:deleted
Rate limitStandard limits apply

Labels

Methods for working with labels, the reusable tags applied to tasks.5

Read-only.

Acts onlabel
Permission (capability)data:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Read-only.

Acts onlabel
Permission (capability)data:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Needs data:read_write.

Acts onlabel
Permission (capability)data:read_write
VersionAvailable since the API’s base version
Webhook eventlabel:added
Rate limitStandard limits apply

Renaming a label updates it on every task that carries it. Needs data:read_write.

Acts onlabel
Permission (capability)data:read_write
VersionAvailable since the API’s base version
Webhook eventlabel:updated
Rate limitStandard limits apply

Removes the label from all tasks. Needs data:delete.

Acts onlabel
Permission (capability)data:delete
VersionAvailable since the API’s base version
Webhook eventlabel:deleted
Rate limitStandard limits apply

Collaborators

Methods for listing the people who share a project.1

Read-only. Returns each collaborator's name and email address.

Acts oncollaborator
Permission (capability)data:read
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply
No endpoints match those filters.
Webhooks

Webhook events.

Todoist can notify an app when something happens in an account, like a task being added or completed. It sends a payload naming the event and the object that changed, so an integration learns about activity without polling.

EventWhat it signalsTriggered by
item:addedA new task was added./api/v1/tasks
/api/v1/tasks/quick_add
item:updatedA task was changed, like its content, due date, or location./api/v1/tasks/{id}
/api/v1/tasks/{id}/move
item:completedA task was completed./api/v1/tasks/{id}/close
item:uncompletedA completed task was reopened./api/v1/tasks/{id}/reopen
item:deletedA task was deleted./api/v1/tasks/{id}
note:addedA comment was added to a task or project./api/v1/comments
note:updatedA comment was changed./api/v1/comments/{id}
note:deletedA comment was deleted./api/v1/comments/{id}
project:addedA new project was created./api/v1/projects
project:updatedA project was changed./api/v1/projects/{id}
project:deletedA project was deleted./api/v1/projects/{id}
label:addedA new personal label was created./api/v1/labels
label:updatedA label was changed./api/v1/labels/{id}
label:deletedA label was deleted./api/v1/labels/{id}
No events match that search.
Rate limits & pagination

Rate limits, pagination & request size.

Todoist limits how many requests an app can make in a fifteen minute window per user, and batched sync commands count as a single request against that allowance.

Request rate

Todoist meters requests per user, not by a per-method cost. A token may make up to 1000 requests in a rolling fifteen minute window for the resource-style endpoints, and the same 1000 cap applies to partial sync requests. Full sync requests, which return the whole account, are capped far lower, at 100 per fifteen minutes, so an integration is expected to sync fully once and then read incrementally. Going over returns HTTP 429 with a retry_after value naming the seconds to wait.

Pagination

List endpoints in the unified API are cursor-based: a limit parameter sets the page size and the response returns a next_cursor when more results remain, which is passed back as cursor to fetch the following page. An empty or absent next_cursor means the last page has been reached.

Request size

A single sync request may carry up to 100 commands, and a batch of 100 commands still counts as one request against the rate limit. The default and maximum page sizes are set per endpoint by the limit parameter.

Errors

Status codes & error handling.

The status codes an agent should handle, and what to do about each.

StatusCodeMeaningWhat to do
400bad_requestThe request was malformed or a parameter is invalid. The body carries an error_tag, an error_code, and a human-readable error message.Read the error message and error_extra, fix the request, and resend.
401unauthorizedAuthentication failed or no token was sent.Send a valid Bearer token, a personal API token or an OAuth access token, in the Authorization header.
403forbiddenThe token is valid but lacks the scope or permission for this action, for example a delete without data:delete.Request the missing scope when authorizing, or use a token that carries it.
404not_foundThe requested object does not exist, or is not visible to this token.Verify the object id and confirm the token's account can see it.
429too_many_requestsThe request allowance for the fifteen minute window was exceeded. A retry_after value in error_extra says how long to wait.Back off for the retry_after period, then retry. Batch sync commands to use fewer requests.
500internal_server_errorAn error on Todoist's side, which can also appear as 503 when the service is temporarily unavailable.Retry with backoff, and contact Todoist support if it persists.
Versioning & freshness

Version history.

Todoist now runs a single unified API that merges its former task and sync interfaces under one version, so there is no dated version string to pin.

Version history

What changed, and when

Latest versionv1
v1Current version
Unified API (current)

Todoist merged its separate REST API (rest/v2) and Sync API (sync/v9) into a single unified API at api.todoist.com/api/v1, rebuilding parts of it and shipping official JavaScript and Python SDKs, clearer error messages, and standardized cursor-based pagination. The unified API is the current and recommended interface; there is no dated version string to pin.

What changed
  • Resource endpoints and the batched /sync endpoint served under one base path, /api/v1.
  • Standardized cursor-based pagination with a next_cursor field.
  • Clearer error model with error_tag, error_code, and error_extra fields.
  • Official JavaScript and Python SDKs published for the unified API.
Earlier
REST v2 and Sync v9 (deprecated)

Before unification, Todoist offered two separate interfaces: a resource-style REST API at rest/v2 for tasks, projects, sections, comments, and labels, and a Sync API at sync/v9 for batched commands, incremental sync, and webhooks. Both are deprecated in favour of the unified v1 API, though their endpoint shapes carried over.

What changed
  • REST v2 covered tasks, projects, sections, comments, and labels as individual resources.
  • Sync v9 provided batched commands, incremental sync tokens, and webhook configuration.
  • An earlier REST v1 was removed on 30 November 2022.

The unified API replaces the separate REST v2 and Sync v9 interfaces, which are deprecated.

Todoist API reference ↗
Questions

Todoist API, answered.

What's the difference between OAuth and a personal API token?+
A personal API token, found in Todoist's integration settings, grants full access to one account and suits personal scripts. OAuth 2.0 is for an app acting on behalf of many people: each person grants a chosen set of scopes, and the app receives an access token limited to those scopes. Both are sent as a Bearer token in the Authorization header.
What OAuth scopes does Todoist offer?+
The scopes are task:add (add new tasks only), data:read (read-only access to tasks, projects, labels, and filters), data:read_write (full read and write, which includes task:add and data:read), data:delete (delete tasks, labels, and filters), and project:delete (delete projects). A backups:read scope also exists for listing backups. Deleting a project needs project:delete specifically, not data:delete.
What are the API rate limits?+
Per user, a token may make up to 1000 requests in a fifteen minute window for the resource-style endpoints, and up to 1000 partial sync requests in the same window. Full sync requests are limited to 100 per fifteen minutes. Exceeding a limit returns HTTP 429 with a retry_after value. Batching up to 100 commands into one sync request counts as a single request, which is the recommended way to do bulk work.
How do I verify a webhook is really from Todoist?+
Each webhook carries an X-Todoist-Hmac-SHA256 header. The receiver computes an HMAC-SHA256 over the raw request body using the OAuth app's client secret, encodes it as base64, and compares it to the header. A mismatch is rejected. The payload also includes an X-Todoist-Delivery-ID header to deduplicate retries.
Has the Todoist API changed recently?+
Yes. Todoist merged its separate REST API (rest/v2) and Sync API (sync/v9) into a single unified API at api.todoist.com/api/v1. The older interfaces are deprecated, and new integrations should build against the unified API. The endpoint paths and object shapes are broadly similar, but the base path changed.
Does Todoist have an official MCP server for AI agents?+
Yes. Doist, the company behind Todoist, publishes an official hosted Model Context Protocol server at ai.todoist.net/mcp, with the tools maintained in the Doist/todoist-ai repository. It authenticates through a browser-based OAuth flow and exposes tools for tasks, projects, sections, comments, and labels. It is early-stage, with more tools planned.
Related

More productivity API guides for agents

What is Bollard AI?

Control what every AI agent can do in Todoist.

Bollard AI sits between a team's AI agents and Todoist. Grant each agent exactly the access it needs, read or write, resource by resource, and every call is checked and logged.

  • Set read, write, or full access per agent, never a shared Todoist token.
  • Denied by default, so an agent reaches only what has been explicitly allowed.
  • Every call recorded in plain English: who, what, where, and the decision.
Todoist
Project Assistant
Read tasks and projects ResourceOffReadFull use
Create and complete tasks ActionOffReadFull use
Delete projects ActionOffReadFull use
Per-agent access, set in Bollard AI, not in Todoist