Overview
This is the official documentation for Todoist Sync API. A reference to the functionality our public API provides with detailed description of each API endpoint, parameters, and examples.
Summary of contents
In the Getting started section we will try to present the Sync API in the simplest possible way, by using real examples based on common tasks.
After reading this section you should continue with the Authorization section in order to learn the best way to authenticate to our server.
The most important section is the Sync section, and you should read it next, where the way that the API works is explained.
The other sections are the reference documentation of the different Todoist objects and endpoints, and you can continue reading them in the order you need them.
Getting started
In this tutorial, we'll show you how to leverage the Sync API for common tasks you'll likely encounter when developing on top of Todoist.
Get all projects
The example of how we get all projects:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d sync_token=* \
-d resource_types='["projects"]'
Example sync response:
{
"projects": [
{
"is_archived": false,
"color": "lime_green",
"shared": false,
"inbox_project": true,
"id": "220474322",
"collapsed": false,
"child_order": 0,
"name": "Inbox",
"is_deleted": false,
"parent_id": null,
"view_style": "list"
}
],
"full_sync": true,
"temp_id_mapping": {},
"sync_token": "kMiTgSIk6QGD83xqMJ9ILknYyEsOoLXyFCnnXvkb4mb0oCK0-IwpKfdGvrcf"
}
First, let's see how we can get all projects a user has.
We send a request to the sync
endpoint, and then specify the following
arguments:
- An authorization header containing the user's API token, which here is set to
Bearer 0123456789abcdef0123456789abcdef01234567
. You can find your token from the Todoist Web app, atTodoist Settings -> Integrations -> API token
. This token remains valid until a new one is generated. - A special sync token, which denotes that we want a full sync, in contrast to
an incremental sync.
This is denoted with the
*
symbol, so we setsync_token=*
. - We want to receive only the
projects
, and not any other data. So we setresource_types='["projects"]'
.
In the results, we see the following data:
- All the user's projects, which in this case is only the
Inbox
project. - A special flag
full_sync
which is set totrue
here, and denotes we performed a full sync. - A new
sync_token
which we can use later to perform an incremental sync. - An empty
temp_id_mapping
object which we'll detail further later.
Excluding resource types
An example of how to exclude projects from our query:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d sync_token=* \
-d resource_types='["all", "-projects"]'
Example sync response (projects are not included):
{
"filters": [],
"temp_id_mapping": {},
"labels": [],
"locations": [],
"project_notes": [],
"user": {},
"full_sync": true,
"sync_token": "kMiTgSIk6QGD83xqMJ9ILknYyEsOoLXyFCnnXvkb4mb0oCK0-IwpKfdGvrcf",
"day_orders": {},
"collaborators": [],
"day_orders_timestamp": "1523557037.93",
"live_notifications_last_read_id": "1192062233",
"items": [],
"notes": [],
"reminders": [],
"live_notifications": [],
"collaborator_states": []
}
We've seen how we can get items by selecting them with resource_types
, but at the same time we can also exclude items.
This can be done by adding a -
before the name of the resource type you want to exclude.
For example, if we were making a request for everything but notes
and labels
, it'd look like this: resource_types=["all", "-notes", "-labels"]
.
Similar to our previous example, we're sending a request to the sync
endpoint with the following arguments:
- An authorization header containing the user's API token, which here is set to
Bearer 0123456789abcdef0123456789abcdef01234567
. You can find out your token from the Todoist Web app, atTodoist Settings -> Account -> API token
. - We set
sync_token=*
, which denotes that we want a full sync. This is in contrast to an incremental sync, where we would use the sync token returned by the previous request. - The use of
resource_types='["all", "-projects"]'
allows us to specify that we want everything except projects.
In the results, we see the following data:
- All the resource items except
projects
. - A special flag
full_sync
which is set totrue
here, and denotes we did a full sync. - A new
sync_token
which we can use later on, in order to do incremental syncs. - An empty
temp_id_mapping
object which we'll look at later on.
Add a new project
The example of how we create a new project:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d sync_token="kMiTgSIk6QGD83xqMJ9ILknYyEsOoLXyFCnnXvkb4mb0oCK0-IwpKfdGvrcf" \
-d resource_types='["projects"]' \
-d commands='[
{
"type": "project_add",
"temp_id": "24a193a7-46f7-4314-b984-27b707bd2331",
"uuid": "e23db5ec-2f73-478a-a008-1cb4178d2fd1",
"args": { "name": "Shopping List" }
}]'
Example sync response
{
"projects": [
{
"is_deleted": false,
"parent_id": null,
"child_order": 1,
"name": "Shopping List",
"collapsed": false,
"shared": false,
"id": "2203306141",
"is_archived": false,
"color": "lime_green",
"view_style": "list"
}
],
"temp_id_mapping": {
"24a193a7-46f7-4314-b984-27b707bd2331" : "2203306141"
},
"sync_status": {
"e23db5ec-2f73-478a-a008-1cb4178d2fd1" : "ok"
},
"sync_token": "apgvJaHcQP3_gB_koBMAbfzXBHn2TL9PJKBcNUFDpra-9C1i8V-jwS3Uez6I",
"full_sync": false
]
}
Let's create a new project, and observe the result of our action.
We use the sync
call, and then specify the following arguments:
- An authorization header containing the user's API token, which here is set to
Bearer 0123456789abcdef0123456789abcdef01234567
. - The sync token that we received on the reply of our previous request, and
which denotes that we want an incremental sync, so we set
sync_token="kMiTgSIk6QGD83xqMJ9ILknYyEsOoLXyFCnnXvkb4mb0oCK0-IwpKfdGvrcf"
. - That we want to get back only the
projects
and not any other data, so we setresource_types='["projects"]'
. - We send a single
project_add
command that will create a new project, and we specify as the only argument to that command thename
of the project which is set toShopping List
. - We also need to specify 2 UUIDs: the
uuid
that will uniquely identify our command, and thetemp_id
which is a temporary ID we set to our new project. We can use this later on to identify it to the server, without a need to know its real ID, which is assigned at the time of creation on the server. Note that in these examples we're using UUID values, but you could also use a shorter string containing letters and/or numbers, but you need to make sure they will be random and unique.
In the results, we see the following data:
- The new project we added is returned as part of the user's
projects
. - The
temp_id_mapping
object which tells us that the new object with UUID24a193a7-46f7-4314-b984-27b707bd2331
has a real ID2203306141
. Notice that we can use both of these IDs to refer to that project, and while the latter should be used whenever possible, the former can be also utilized on a temporary basis. - The
sync_status
object which tells us whether our command with UUIDe23db5ec-2f73-478a-a008-1cb4178d2fd1
was successful, or in case of error what exactly was the problem. - The special flag
full_sync
which is set tofalse
here, and denotes we did an incremental sync. - A new
sync_token
which we can use later on to perform further incremental syncs.
Add two new tasks
The example of how we create two new tasks:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d sync_token="apgvJaHcQP3_gB_koBMAbfzXBHn2TL9PJKBcNUFDpra-9C1i8V-jwS3Uez6I" \
-d resource_types='["projects", "items"]' \
-d commands='[
{
"type": "item_add",
"temp_id": "fdef5d16-a40a-475e-bd4a-0ccbd6fd8c3f",
"uuid": "a3aa2f44-23b4-4986-b513-ef7663bbb752",
"args": {
"project_id": "24a193a7-46f7-4314-b984-27b707bd2331",
"content": "Buy Milk"
}
},
{
"type": "item_add",
"temp_id": "6f5e0b50-af7a-4133-bfc0-e8c041b819d2",
"uuid": "d16ad84a-e10b-4894-af7d-93ba6adf7a1e",
"args": {
"project_id": "2203306141",
"content": "Buy Coffee"
}
}]'
Example sync response
{
"projects": [],
"items": [
{
"collapsed": false,
"added_at": "2016-08-01T13:19:45.000000Z",
"child_order": 2,
"parent_id": null,
"day_order": 1,
"added_by_uid": "1",
"assigned_by_uid": "1",
"responsible_uid": null,
"sync_id": null,
"checked": false,
"user_id": "1",
"labels": [],
"is_deleted": false,
"due": null,
"deadline": null,
"project_id": "2203306141",
"content": "Buy Milk",
"description": "",
"id": "2995104339",
"priority": 1
},
{
"priority": 1,
"id": "2995104340",
"content": "Buy Coffee",
"description": "",
"is_deleted": false,
"due": null,
"deadline": null,
"project_id": "2203306141",
"checked": false,
"labels": [],
"user_id": "1",
"responsible_uid": null,
"sync_id": null,
"added_by_uid": "1",
"assigned_by_uid": "1",
"day_order": -1,
"parent_id": null,
"child_order": 1,
"collapsed": false,
"added_at": "2016-08-01T13:19:45.000000Z"
}
],
"temp_id_mapping": {
"6f5e0b50-af7a-4133-bfc0-e8c041b819d2": "2995104340",
"fdef5d16-a40a-475e-bd4a-0ccbd6fd8c3f": "2995104339"
},
"sync_status": {
"a3aa2f44-23b4-4986-b513-ef7663bbb752": "ok",
"d16ad84a-e10b-4894-af7d-93ba6adf7a1e": "ok"
},
"sync_token": "n8KPDzcwqjFfODLS5pjLjllWSz-pNplNV0ivRFGbASu1ciwNzNJ3p66v_eWy",
"full_sync": false
}
Let's create two new tasks in one go, and observe the result of our action.
We use the sync
call, and then specify the following arguments:
- The user's API token, same as on the previous requests.
- The sync token we received as reply on our previous request.
- For this example we get back both projects and items changed since last sync,
so we set
resource_types='["projects", "items"]'
. - We send two
item_add
commands that will each create a new task, and we also specify theproject_id
and thecontent
of each new task. For one of the tasks we use thetemp_id
of the previously created project, while for the other task we use the project's real ID, and we do that just to show that it has the same result. - We also need to specify the
uuid
andtemp_id
for the two commands, and the two new tasks respectively.
In the results, we see the following data:
- An empty
projects
array, which is expected as no new projects were added by our commands. - The new tasks we added are returned as part of the user's
items
array. - The
temp_id_mapping
object which tells us the real IDs of the new tasks, for each of thetemp_id
s we sent. - The
sync_status
object which tells us whether each command was successful. - The special flag
full_sync
which is set tofalse
here, and denotes we did an incremental sync. - A new
sync_token
which we can use later on to do more incremental syncs.
Update the content and due date of a task
The example of how we update the content and due date of a task:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d sync_token="n8KPDzcwqjFfODLS5pjLjllWSz-pNplNV0ivRFGbASu1ciwNzNJ3p66v_eWy" \
-d resource_types='["items"]' \
-d commands='[
{
"type": "item_update",
"uuid": "aca17834-da6f-4605-bde0-bd10be228878",
"args": {
"id": "2995104339",
"content": "Buy Coffee",
"due": {"string": "tomorrow at 10:00" }
}
}]'
Example sync response
{
"items": [
{
"sync_id": null,
"project_id": "2203306141",
"labels": [],
"is_deleted": false,
"child_order": 1,
"checked": false,
"priority": 1,
"id": "2995104339",
"added_by_uid": "1",
"assigned_by_uid": "1",
"day_order": -1,
"collapsed": false,
"due": {
"date": "2016-08-05T07:00:00.000000Z",
"timezone": null,
"is_recurring": false,
"string": "tomorrow at 10:00",
"lang": "en"
},
"deadline": null,
"responsible_uid": null,
"content": "Buy Coffee",
"description": "",
"user_id": "1",
"parent_id": null,
"added_at": "2016-08-01T13:19:45.000000Z"
}
],
"sync_status": {
"aca17834-da6f-4605-bde0-bd10be228878" : "ok"
},
"temp_id_mapping": {}
"sync_token": "0ZBXkkKdTFGzoj5ji0M9N-tBPAISYlnSjQw5jvV4FFIOss69cJ5QNZx3ESG7",
"full_sync": false,
}
Let's update the content and due date of the first task we created in the previous step.
We use the sync
call, and then specify the following arguments:
- The user's API token same as on the previous requests.
- The sync token we received as reply on our previous request.
- For this example lets get back only items changed since our last sync, so we
set
resource_types='["items"]'
. - We send an
item_update
command that will update the task we created earlier, so we specify theid
of the task, its newcontent
, and its new due date by setting thedue
property with a new due date instance. - We also need to specify the
uuid
for this command.
In the results, we see the following data:
- The updates to all items since our last sync are returned as part of the
user's
items
array. - The updated item which contains a fully populated due object.
- The
temp_id_mapping
here is empty since no new object was created. - The
sync_status
object which tells us whether our command was successful. - The special flag
full_sync
which is set tofalse
here, and denotes we did an incremental sync. - A new
sync_token
which we can use later on to do more incremental syncs.
Complete a task and delete another task
The example of how we complete a task and delete another task:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d sync_token="n8KPDzcwqjFfODLS5pjLjllWSz-pNplNV0ivRFGbASu1ciwNzNJ3p66v_eWy" \
-d resource_types='["items"]' \
-d commands='[
{
"type": "item_complete",
"uuid": "7d9355c5-bd28-4d39-8b8b-0b7a7682eaa2",
"args": { "ids": ["2995104339"] } },
{
"type": "item_delete",
"uuid": "c27ee0dd-71b8-4725-af5c-3f6327bacdb4",
"args": { "ids": ["2995104340"] }
}]'
Example sync response
{
"items": [
{
"added_at": "2016-08-01T13:19:45.000000Z",
"added_by_uid": "1",
"assigned_by_uid": "1",
"priority": 1,
"user_id": "1",
"responsible_uid" : null,
"labels": [],
"checked": false,
"day_order": -1,
"project_id": "2203306141",
"due": null,
"deadline": null,
"child_order": 2,
"collapsed": false,
"parent_id": null,
"content": "Buy Milk",
"description": "",
"sync_id": null,
"id": "2995104339",
"is_deleted": true
},
{
"added_at": "2016-08-01T13:19:45.000000Z"
"labels": [],
"responsible_uid": null,
"added_by_uid": "1",
"assigned_by_uid": "1",
"priority": 1,
"user_id": "1",
"parent_id": null,
"collapsed": false,
"child_order": 32,
"due": {
"date": "2016-08-05T07:00:00.000000Z",
"timezone": null,
"is_recurring": false,
"string": "tomorrow at 10:00",
"lang": "en"
},
"deadline": null,
"project_id": "2203306141",
"day_order": 0,
"checked": true,
"is_deleted": false,
"id": "2995104340",
"content": "Buy Coffee",
"description": "",
"sync_id": null
}
],
"sync_status": {
"7d9355c5-bd28-4d39-8b8b-0b7a7682eaa2": "ok"
"c27ee0dd-71b8-4725-af5c-3f6327bacdb4": "ok"
},
"temp_id_mapping": {}
"sync_token": "0ssnDPZcdFC23iIPhmOIwrCEq6iyux6wTC26gCyTp7IsO_eOTf-Tbg7peROA",
"full_sync": false,
}
Let's complete the task we updated in the previous step, and delete the task we created earlier.
We use the sync
call, and then specify the following arguments:
- The user's API token same as on the previous requests.
- The sync token we received as reply on our previous request.
- For this example lets get back only items changed since last sync, so we set
resource_types='["items"]'
. - We send an
item_complete
command that will completed the task, and we specify only theids
parameter with the ID of the task. We also send anitem_delete
command that will delete the other task, and this command also expects anids
parameter. - We also need to specify the
uuid
s for these commands.
In the results, we see the following data:
- The updates to all items since our last sync are returned as part of the
user's
items
array, where we can observe that the task we completed has achecked=true
property which denotes it's now completed, while the other task has ais_deleted=true
property which denotes it's now deleted. - The
temp_id_mapping
here is empty since no new object was created. - The
sync_status
object which tells us whether our command was successful. - The special flag
full_sync
which is set tofalse
here, and denotes we did an incremental sync. - A new
sync_token
which we can use later on to do more incremental syncs.
Add a new task with a note and a reminder
The example of how we create a new task with a note and a reminder:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d sync_token="apgvJaHcQP3_gB_koBMAbfzXBHn2TL9PJKBcNUFDpra-9C1i8V-jwS3Uez6I" \
-d resource_types='["projects", "items"]' \
-d commands='[
{
"type": "item_add",
"temp_id": "160070ed-79a9-4e6b-988b-169052e9ef22",
"uuid": "cf6c3ef7-5579-40c2-87e1-b30a1f3cbefe",
"args": {
"project_id": "2203306141",
"content": "Buy Sugar",
"date": {"string": "monday 11am"}
}
},
{
"type": "note_add",
"temp_id": "7f4de51a-3b12-4364-a98b-26f041293eba",
"uuid": "0d9a0925-067e-47fb-9a86-c0cf359afd9f",
"args": {
"item_id": "160070ed-79a9-4e6b-988b-169052e9ef22",
"content": "Remember this!"
}
},
{
"type": "reminder_add",
"temp_id": "cda5ffcd-5035-47d9-a683-5dddce096811",
"uuid": "843a5719-b204-4f6e-9ff3-f55cb9140ba1",
"args": {
"item_id": "160070ed-79a9-4e6b-988b-169052e9ef22",
"due": {"string": "monday 10:45am"}
}
}]'
Example sync response
{
"items": [
{
"added_at": "2016-08-05T11:47:58.000000Z",
"day_order": 2,
"user_id": "1",
"project_id": "2203306141",
"sync_id": null,
"responsible_uid": null,
"parent_id": null,
"content": "Buy Sugar",
"description": "",
"collapsed": false,
"labels": [],
"child_order" : 1,
"due": {
"date": "2016-08-08T11:00:00.000000Z",
"timezone": null,
"is_recurring": false,
"string": "8 Aug 11:00 AM",
"lang": "en"
},
"deadline": null,
"id": "2995104340",
"checked": false,
"added_by_uid": "1",
"assigned_by_uid" : "1",
"priority": 1,
"is_deleted": false
}
],
"notes": [
{
"project_id": "2203306141",
"content": "Don't forget!",
"posted_uid": "1",
"file_attachment": null,
"is_deleted": false,
"id": "2992679862",
"posted_at": "2016-08-05T11:47:58.000000Z",
"uids_to_notify": null,
"item_id": "2995104340"
}
],
"reminders": [
{
"minute_offset": 180,
"notify_uid": "1",
"is_deleted": false,
"type": "absolute",
"id": "2992683215",
"due": {
"date": "2016-08-08T10:45:00.000000Z",
"timezone": null,
"is_recurring": false,
"string": "8 Aug 10:45 AM",
"lang": "en"
},
"item_id": "2995104340"
}
],
"temp_id_mapping": {
"160070ed-79a9-4e6b-988b-169052e9ef22": "2995104340",
"cda5ffcd-5035-47d9-a683-5dddce096811": "2992683215",
"7f4de51a-3b12-4364-a98b-26f041293eba": "2992679862",
},
"sync_status": {
"cf6c3ef7-5579-40c2-87e1-b30a1f3cbefe": "ok",
"0d9a0925-067e-47fb-9a86-c0cf359afd9f": "ok",
"843a5719-b204-4f6e-9ff3-f55cb9140ba1": "ok"
},
"full_sync": false,
"sync_token": "seMM_nP7SK3oiSbCbDGziTIQkJ8BQMAVptiXMo1AbqWghwz8o_9icGNXGq7c",
}
Let's create a new task, add a new comment, and set a reminder based on its due date.
We use the sync
call, and then specify the following arguments:
- The user's API token same as on the previous requests.
- The sync token we received as reply on our previous request.
- For this example lets get back items, notes and reminders, changed since last
sync, so we set
resource_types='["items", "notes", "reminders"]'
. - We send an
item_add
command that will add the new task. - We send a
note_add
command that will add a note to the new task by specifying thetemp_id
of the new task as theitem_id
for thenote_add
command. - We send a
reminder_add
command that will create a reminder for our task, again using thetemp_id
of the task as theitem_id
of thereminder_add
command. - We also need to specify the
uuid
for all commands.
In the results, we see the following data:
- The updates to all items, notes and reminders since our last sync are returned as the equivalent arrays, and we can observe all three new objects created.
- The
temp_id_mapping
here contains the real IDs of the task, note and reminder. - The
sync_status
object which tells us whether our commands were successful. - The special flag
full_sync
which is set tofalse
here, and denotes we did an incremental sync. - A new
sync_token
which we can use later on to do more incremental syncs.
Authorization
An authenticated request with authorization header:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d sync_token='*' \
-d resource_types='["all"]'
In order to make authorized calls to the Sync API, your application must provide
an authorization header
with the appropriate Bearer $token
. For working through the examples, you can obtain your personal API token
from the integrations settings for your account.
To authenticate other users, your application will need to obtain a token from them using the OAuth protocol. For information on how to obtain a token from our service using OAuth, please see the authorization guide.
For the sake of simplicity the token is not listed on every parameter table but please note that the token parameter is required for every resource.
Revoke Access Tokens
Example revoke token request:
curl -X POST https://api.todoist.com/sync/v9/access_tokens/revoke \
-H "Content-Type: application/json" \
-d '{"client_id":"xyz", "client_secret":"xyz", "access_token":"xyz"}'
Access tokens obtained via OAuth can be revoked by making a JSON request (HTTP POST) to the following endpoint:
https://api.todoist.com/sync/v9/access_tokens/revoke
A successful response has 204 No Content
status and an empty body.
Parameters
Name | Required | Description |
---|---|---|
client_id String | Yes | The unique Client ID of the Todoist application that you registered. |
client_secret String | Yes | The unique Client Secret of the Todoist application that you registered. |
access_token String | Yes | Access token obtained from OAuth authentication |
Migrate Personal Tokens to OAuth Tokens
Example migrate token request:
curl -X POST https://api.todoist.com/sync/v9/access_tokens/migrate_personal_token \
-H "Content-Type: application/json" \
-d '{"client_id":"xyz", "client_secret":"xyz", "personal_token":"xyz", "scope": "data:read"}'
Example response:
{
"access_token": "....",
"token_type": "Bearer"
}
Tokens obtained via the old email/password authentication method can be migrated to the new OAuth access token. Migrating your users' personal tokens will allow users to see your app in their Todoist Settings page and give them the ability to manage their app authorization.
Here is the migration API endpoint (HTTP POST, with JSON request parameters):
https://api.todoist.com/sync/v9/access_tokens/migrate_personal_token
A successful response has 200 OK
status and application/json
Content-Type.
{"access_token": "....", "token_type": "Bearer"}
Parameters
Name | Required | Description |
---|---|---|
client_id String | Yes | The unique Client ID of the Todoist application that you registered. |
client_secret String | Yes | The unique Client Secret of the Todoist application that you registered. |
personal_token String | Yes | Token obtained from the email/password authentication |
scope String | Yes | Scopes of the OAuth token. Please refer to the Authorization guide for the detailed list of available scopes. |
Cross Origin Resource Sharing
CORS headers example:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-H "Origin: http://example.com"
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: false
Access-Control-Allow-Origin: *
All API endpoints not related to the initial OAuth flow support Cross Origin Resource
Sharing (CORS) for requests from any origin. The header
Access-Control-Allow-Origin: *
is set for successfully authenticated requests.
Sync
The Todoist Sync API is specially designed for efficient data sync between clients (e.g. our mobile apps) and Todoist.
All Sync API requests share the same endpoint URL:
https://api.todoist.com/sync/v9/sync
Sync API requests should be made in HTTP POST (application/x-www-form-urlencoded). Sync API responses, including errors, will be returned in JSON.
The Sync API supports the following features:
- Batching: reading and writing of multiple resources can be done in a single HTTP request. Batch requests help clients reduce the number of network calls needed to sync resources.
- Incremental sync: You only retrieve data that is updated since the last time you performed a sync request.
Refer to Request Limits to learn more about the number of requests/commands you have for the Sync API
Read resources
Example read resources request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d sync_token='*' \
-d resource_types='["all"]'
Example response:
{
"completed_info": [ ... ],
"collaborators": [ ... ],
"collaborator_states": [ ... ],
"day_orders": { ... },
"filters": [ ... ],
"full_sync": true,
"items": [ ... ],
"labels": [ ... ],
"live_notifications": [ ... ],
"live_notifications_last_read_id": "0",
"locations": [ ... ],
"notes": [ ... ],
"project_notes": [ ... ],
"projects": [ ... ],
"reminders": [ ... ],
"sections": [ ... ],
"stats": { ... },
"settings_notifications": { ... },
"sync_token": "TnYUZEpuzf2FMA9qzyY3j4xky6dXiYejmSO85S5paZ_a9y1FI85mBbIWZGpW",
"temp_id_mapping": { ... },
"user": { ... },
"user_plan_limits": { ... },
"user_settings": { ... }
}
To retrieve your user resources, make a Sync API request with the following parameters:
Parameters
Parameter | Required | Description |
---|---|---|
sync_token String | Yes | A special string, used to allow the client to perform incremental sync. Pass * to retrieve all active resource data. More details about this below. |
resource_types JSON array of strings | Yes | Used to specify what resources to fetch from the server. It should be a JSON-encoded array of strings. Here is a list of available resource types: labels , projects , items , notes , sections , filters , reminders , reminders_location , locations , user , live_notifications , collaborators , user_settings , notification_settings , user_plan_limits , completed_info , stats . You may use all to include all the resource types. Resources can also be excluded by prefixing a - prior to the name, for example, -projects |
In order to fetch both types of reminders you must include both resource types in your request, for example: resource_types=["reminders", "reminders_location"]
.
Incremental sync
The Sync API allows clients to retrieve only updated resources, and this is done
by using the sync_token
in your Sync API request.
On your initial sync request, specify sync_token=*
in your request, and all
the user's active resource data will be returned. The server will also
return a new sync_token
in the Sync API response.
In your subsequent Sync request, use the sync_token
that you received from
your previous sync response, and the Todoist API server will return only the
updated resource data.
Response
When the request succeeds, an HTTP 200 response will be returned with a JSON
object containing the requested resources and a new sync_token
.
Field | Description |
---|---|
sync_token | A new synchronization token. Used by the client in the next sync request to perform an incremental sync. |
full_sync | Whether the response contains all data (a full synchronization) or just the incremental updates since the last sync. |
user | A user object. |
projects | An array of project objects. |
items | An array of item objects. |
notes | An array of item note objects. |
project_notes | An array of project note objects. |
sections | An array of section objects. |
labels | An array of personal label objects. |
filters | An array of filter objects. |
day_orders | A JSON object specifying the order of items in daily agenda. |
reminders | An array of reminder objects. |
collaborators | A JSON object containing all collaborators for all shared projects. The projects field contains the list of all shared projects, where the user acts as one of collaborators. |
collaborators_states | An array specifying the state of each collaborator in each project. The state can be invited, active, inactive, deleted. |
completed_info | An array of completed info objects indicating the number of completed items within an active project, section, or parent item. Projects will also include the number of archived sections. Endpoints for accessing archived objects are described in the Items and sections archive section. |
live_notifications | An array of live_notification objects. |
live_notifications_last_read | What is the last live notification the user has seen? This is used to implement unread notifications. |
user_settings | A JSON object containing user settings. |
user_plan_limits | A JSON object containing user plan limits. |
Write resources
Example create project request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "project_add",
"temp_id": "381e601f-0ef3-4ed6-bf95-58f896d1a314",
"uuid": "ed1ce597-e4c7-4a88-ba48-e048d827c067",
"args": {
"name": "Shopping List",
"color": "berry_red"
}
}]'
Example response:
{
"sync_token": "cdTUEvJoChiaMysD7vJ14UnhN-FRdP-IS3aisOUpl3aGlIQA9qosBgvMmhbn",
"sync_status": {"ed1ce597-e4c7-4a88-ba48-e048d827c067": "ok"},
"temp_id_mapping": {"381e601f-0ef3-4ed6-bf95-58f896d1a314": "2203306141"}
}
To write to your user's Todoist resources, make a Sync API request with the following parameters:
Parameters
Parameter | Required | Description |
---|---|---|
commands JSON | Yes | A JSON array of Command objects. Each command will be processed in the specified order. |
Command object
Field | Description |
---|---|
type String | The type of the command. |
args Object | The parameters of the command. |
uuid String | Command UUID. More details about this below. |
temp_id String | Temporary resource ID, Optional. Only specified for commands that create a new resource (e.g. item_add command). More details about this below. |
Command UUID
Clients should generate a unique string ID for each command and specify it
in the uuid
field. The Command UUID will be used for two purposes:
- Command result mapping: Each command's result will be stored in the
sync_status
field of the response JSON object. Thesync_status
object has its key mapped to a command'suuid
and its value containing the result of a command. - Command idempotency: Todoist will not execute a command that has same UUID as a previously executed command. This will allow clients to safely retry each command without accidentally performing the action twice.
Temporary resource id
An example that shows how temporary IDs can be used and referenced:
[
{
"type": "project_add",
"temp_id": "c7beb07f-b226-4eb1-bf63-30d782b07b1a",
"args": {
"name": "Shopping List"
},
"uuid": "ac417051-1cdc-4dc3-b4f8-14526d5bfd16"
},
{
"type": "item_add",
"temp_id": "43f7ed23-a038-46b5-b2c9-4abda9097ffa",
"args": {
"content": "Buy Milk",
"project_id": "c7beb07f-b226-4eb1-bf63-30d782b07b1a"
},
"uuid": "849fff4e-8551-4abb-bd2a-838d092775d7"
}
]
You can see that the
project_add
command specified atemp_id
property (c7beb07f-b226-4eb1-bf63-30d782b07b1a
) as placeholder of the actualproject_id
. Theitem_add
command can reference to this temporary project ID. The API will automatically resolve these IDs.
Some commands depend on the result of previous command. For instance, you have a
command sequence: "project_add"
and "item_add"
which first creates a project
and then add a new task to the newly created project. In order to run the later
item_add
command, we need to obtain the project ID returned from the previous
command. Therefore, the normal approach would be to run these two commands in
two separate HTTP requests.
The temporary resource ID feature allows you to run two or more dependent
commands in a single HTTP request. For commands that are related to creation of
resources (i.e. item_add
, project_add
), you can specify an extra temp_id
as a placeholder for the actual ID of the resource. The other commands in the
same sequence could directly refer to temp_id
if needed.
Response / Error
An example of a single request sync return value:
{
"sync_status": {"863aca2c-65b4-480a-90ae-af160129abbd": "ok"}
}
An example of a multiple requests sync return value:
{
"sync_status": {
"32eaa699-e9d7-47ed-91ea-e58d475791f1": "ok",
"bec5b356-3cc1-462a-9887-fe145e3e1ebf": {"error_code": 15, "error": "Invalid temporary id"}
}
}
The result of command executions will be stored in the following response JSON object field:
Data | Description |
---|---|
temp_id_mapping Object | A dictionary object that maps temporary resource IDs to real resource IDs. |
sync_status Object | A dictionary object containing result of each command execution. The key will be the command's uuid field and the value will be the result status of the command execution. |
The status result of each command execution is in the sync_status
dictionary
object. The key is a command uuid
and the value will be the result status of
the command execution.
There are two possible values for each command status:
- An "ok" string which signals success of the command
- An error object containing error information of a command.
Please see the adjacent code examples for the possible format of the
sync_status
.
Response status codes
The server uses the HTTP status codes to indicate the success or failure of a request. As is customary in web servers, a 2xx code indicates - success, a 4xx code - an error due to incorrect user provided information, and a 5xx code - an internal, possibly temporary, error.
Status code | Description |
---|---|
200 OK | The request was processed successfully. |
400 Bad Request | The request was incorrect. |
401 Unauthorized | Authentication is required, and has failed, or has not yet been provided. |
403 Forbidden | The request was valid, but for something that is forbidden. |
404 Not Found | The requested resource could not be found. |
429 Too Many Requests | The user has sent too many requests in a given amount of time. |
500 Internal Server Error | The request failed due to a server error. |
503 Service Unavailable | The server is currently unable to handle the request. |
Response error codes
Error objects containing error information will be included in responses when there is a command execution failure. The error codes that are provided will indicate the cause of the failure and serve as guidance on how to proceed.
Error code | Description |
---|---|
21 Project not found | The project has been deleted or does not exist (the command should not be retried). |
22 Item not found | The task has been deleted or does not exist (the command should not be retried). |
411 User deleted | The user account has been deleted (the command should not be retried). |
Batching commands
Example of batching multiple commands:
curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "project_add",
"temp_id": "0a57a3db-2ff1-4d2d-adf6-12490c13c712",
"uuid": "2c0f6e03-c372-46ba-8e85-d94af56abcf3",
"args": { "name": "Shopping List" }
},
{
"type": "item_add",
"temp_id": "ef3d840e-84c9-4433-9a32-86ae9a1e7d42",
"uuid": "49ede211-12f3-42e9-8345-4c0d2b29c08d",
"args": { "content": "Buy Milk", "project_id": "0a57a3db-2ff1-4d2d-adf6-12490c13c712" }
},
{
"type": "item_add",
"temp_id": "8a23c8cb-1d76-469d-a2c0-80a28b3ea6f6",
"uuid": "46619250-ae02-4ab0-bd31-3c9ab0307e53",
"args": { "content": "Buy Coffee", "project_id": "0a57a3db-2ff1-4d2d-adf6-12490c13c712" }
},
{
"type": "item_add",
"temp_id": "bf087eaf-aea9-4cb1-ab57-85188a2d428f",
"uuid": "d0a1666b-d615-4250-aac5-65c7ea89091a",
"args": { "content": "Buy Sugar", "project_id": "0a57a3db-2ff1-4d2d-adf6-12490c13c712" }
}]'
Example response:
{
"sync_status": {
"2c0f6e03-c372-46ba-8e85-d94af56abcf3": "ok",
"49ede211-12f3-42e9-8345-4c0d2b29c08d": "ok",
"d0a1666b-d615-4250-aac5-65c7ea89091a": "ok",
"46619250-ae02-4ab0-bd31-3c9ab0307e53": "ok"
},
"temp_id_mapping": {
"8a23c8cb-1d76-469d-a2c0-80a28b3ea6f6": "2995104340",
"0a57a3db-2ff1-4d2d-adf6-12490c13c712": "2203306141",
"bf087eaf-aea9-4cb1-ab57-85188a2d428f": "2995104341",
"ef3d840e-84c9-4433-9a32-86ae9a1e7d42": "2995104339"
},
"full_sync": true,
"sync_token": "GSg4kDBAKWU7TZA_a-gcuSpxmO1lXT5bhLqUGd1F-AH69_qKEdkN_fJoBq3c"
}
When working with the Sync API, changes can be batched into one commit. In our example, we're batching the creation of a 'Shopping List' project with three different items.
As we've committed the changes all at once, we’re significantly reducing the amount of network calls that have to be made, as well as ensuring we’re not running into any rate limiting issues.
Workspace
An example workspace object:
{
"id": "1234",
"name": "Workspace name",
"description": "Workspace description",
"plan": "STARTER",
"is_link_sharing_enabled": true,
"is_guest_allowed": true,
"invite_code": "ptoh4SICUu4",
"role": "MEMBER",
"logo_big": "https://...",
"logo_medium": "https://...",
"logo_small": "https://...",
"logo_s640": "https://...",
"creator_id": "123",
"created_at": "2021-10-19T10:00:00.123456Z",
"limits": {
"current": {
"admin_tools": false,
"advanced_permissions": false,
"automatic_backups": false,
"max_collaborators": 250,
"max_guests_per_workspace": 1000,
"max_projects": 5,
"max_workspace_users": 1000,
"plan_name": "teams_workspaces_starter",
"reminders": false,
"security_controls": false,
"upload_limit_mb": 5
},
"next": {
"admin_tools": true,
"advanced_permissions": true,
"automatic_backups": true,
"max_collaborators": 250,
"max_guests_per_workspace": 1000,
"max_projects": 1000,
"max_workspace_users": 1000,
"plan_name": "teams_workspaces_business",
"reminders": true,
"security_controls": true,
"upload_limit_mb": 100
}
},
"is_deleted": false,
"is_collapsed": false,
}
Properties
Property | Description |
---|---|
id String | The ID of the workspace. |
name String | The name of the workspace (up to 255 characters). Special characters (`#"() |
description String | The description of the workspace. |
plan String | The subscription plan this workspace is currently on, either STARTER or BUSINESS . |
is_link_sharing_enabled Boolean | True if users are allowed to join the workspace using an invitation link. Default value is True. For guests, this field will be set to null as guests are not allowed to have access to this field. |
is_guest_allowed Boolean | True if users from outside the workspace are allowed to join or be invited to workspace projects. Default value is True. |
invite_code String | The invitation code used to generate an invitation link. If is_link_sharing_enabled is True, anyone can join the workspace using this code. For guests, this field will be set to null as guests are not allowed to have access to this field. |
role String | The role of the requesting user in this workspace. Possible values are: ADMIN , MEMBER or GUEST . A guest is someone who is a collaborator of a workspace project, without being an actual member of the workspace. This field can be null if the requesting user is not part of the workspace. For example, when receiving the workspace deletion related sync update when a user leaves or is removed from a workspace. |
logo_big String | The URL for the big workspace logo image. |
logo_medium String | The URL for the medium workspace logo image. |
logo_small String | The URL for the small workspace logo image. |
logo_s640 String | The URL for the square 640px workspace logo image. |
limits Object | A list of restrictions for the workspace based on it's current plan, denoting what features are enabled and limits are imposed. |
creator_id String | The ID of the user who created the workspace. |
created_at String | The date when the workspace was created. |
is_deleted Boolean | True if it is a deleted workspace. |
is_collapsed Boolean | True if the workspace is collapsed. This is a user-specific attribute and will reflect the requesting user’s is_collapsed state. |
domain_name String | The domain name of the workspace. |
domain_discovery Boolean | True if users with e-mail addresses in the workspace domain can join the workspace without an invitation. |
restrict_email_domains Boolean | True if only users with e-mail addresses in the workspace domain can join the workspace. |
Add a workspace
Example add workspace request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "workspace_add",
"temp_id": "4ff1e388-5ca6-453a-b0e8-662ebf373b6b",
"uuid": "32774db9-a1da-4550-8d9d-910372124fa4",
"args": {
"name": "Fellowship Workspace"
}
}]'
Example response:
{
...
"sync_status": {"32774db9-a1da-4550-8d9d-910372124fa4": "ok"},
"temp_id_mapping": {"4ff1e388-5ca6-453a-b0e8-662ebf373b6b": "2203306140"},
...
}
Add a new workspace.
Command arguments
Argument | Required | Description |
---|---|---|
name String | Yes | The name of the workspace. |
description String | No | The description of the workspace (up to 1024 characters). |
is_link_sharing_enabled Boolean | No | Indicates if users are allowed to join the workspace using an invitation link. Default value is True. |
is_guest_allowed Boolean | No | Indicates if users from outside the workspace are allowed to join or be invited to workspace projects. Default value is True. |
domain_name String | No | The domain name of the workspace. |
domain_discovery Boolean | No | True if users with e-mail addresses in the workspace domain can join the workspace without an invitation. |
restrict_email_domains Boolean | No | True if only users with e-mail addresses in the workspace domain can join the workspace. |
Update a workspace
Example update workspace request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "workspace_update",
"temp_id": "4ff1e388-5ca6-453a-b0e8-662ebf373b6b",
"uuid": "32774db9-a1da-4550-8d9d-910372124fa4",
"args": {
"id": "12345",
"description": "Where magic happens"
}
}]'
Example response:
{
...
"sync_status": {"32774db9-a1da-4550-8d9d-910372124fa4": "ok"},
"temp_id_mapping": {"4ff1e388-5ca6-453a-b0e8-662ebf373b6b": "2203306140"},
...
}
Update an existing workspace.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | Real or temp ID of the workspace |
name String | No | The name of the workspace. |
description String | No | The description of the workspace (up to 1024 characters). |
is_collapsed Boolean | No | The collapsed state of the workspace for the current user |
is_link_sharing_enabled Boolean | No | Indicates if users are allowed to join the workspace using an invitation link. |
is_guest_allowed Boolean | No | Indicates if users from outside the workspace are allowed to join or be invited to workspace projects. Default value is True. |
invite_code String | No | Regenerate the invite_code for the workspace. Any non-empty string value will regenerate a new code, the provided value with this argument is not significant, only an indication to regenerate the code. |
domain_name String | No | The domain name of the workspace. |
domain_discovery Boolean | No | True if users with e-mail addresses in the workspace domain can join the workspace without an invitation. |
restrict_email_domains Boolean | No | True if only users with e-mail addresses in the workspace domain can join the workspace. |
Leave a workspace
Example leave workspace request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "workspace_leave",
"temp_id": "4ff1e388-5ca6-453a-b0e8-662ebf373b6b",
"uuid": "32774db9-a1da-4550-8d9d-910372124fa4",
"args": {
"id": "12345",
}
}]'
Example response:
{
...
"sync_status": {"32774db9-a1da-4550-8d9d-910372124fa4": "ok"},
...
}
Remove self from a workspace. The user is also removed from any workspace project previously joined.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | Real or temp ID of the workspace |
All workspace_users can leave a workspace by themselves.
Delete a workspace
Example delete workspace request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "workspace_delete",
"temp_id": "4ff1e388-5ca6-453a-b0e8-662ebf373b6b",
"uuid": "32774db9-a1da-4550-8d9d-910372124fa4",
"args": {
"id": "12345"
}
}]'
Example response:
{
...
"sync_status": {"32774db9-a1da-4550-8d9d-910372124fa4": "ok"},
...
}
Delete an existing workspace.
This command is only usable by workspace admins. Other users will get a “forbidden” error.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the workspace |
List all active workspace projects
Example request to list all active workspace projects:
$ curl https://api.todoist.com/sync/v9/workspaces/projects/active?workspace_id=424876 \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567"
Example response:
{
"workspace_projects": [
{
"id": "301946961",
"v2_id": "GTYbJyAUHnKo41sxp1kH27fgiF",
"name": "Project1",
"color": "lime_green",
"description": "A workspace project",
"status": "IN_PROGRESS",
"total_tasks_count": 456,
"uncompleted_tasks_count": 123,
"role": "READ_WRITE",
"is_invite_only": false
}, ...
],
"next_cursor": "XXX",
"has_more": true
}
Returns all active workspace projects, including those visible but not joined by the user.
For guests, returns all joined workspace projects only.
Command arguments
Argument | Required | Description |
---|---|---|
workspace_id String | No | ID of the workspace, provided to fetch users of a single workspace. |
limit Integer | No | Maximum number of workspace users to return (100 by default, 500 maximum) |
cursor String | No | Value to iterate over the list of workspace users. Returned in API responses as the next_cursor attribute. |
Workspace projects properties
The workspace project is different from a normal project returned by a sync request
Property | Description |
---|---|
id String | The ID of the project. |
v2_id String | The project’s common v2 id for all workspace users. This ID is to be used with the preview endpoint. |
name String | The project's name. |
color String | The project’s color, according to the list of colors. |
description String | A nullable string with the project’s description. |
is_invite_only Boolean | Whether or not the project is private - "invite only". |
view_style String | The project’s view style (list or board). |
role String | The role of the current user in the project. Possible values are: CREATOR , ADMIN , READ_WRITE . For not joined projects the value will be null. |
status String | The status of the project. Possible values: PLANNED , IN_PROGRESS , PAUSED , COMPLETED , CANCELED . |
total_tasks_count Integer | Number of total tasks for the project |
uncompleted_tasks_count Integer | Number of active tasks for the project. |
List all archived workspace projects
Example request to list all archived workspace projects:
$ curl https://api.todoist.com/sync/v9/workspaces/projects/archived?workspace_id=424876 \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567"
Example response:
{
"workspace_projects": [
{
"id": "301946961",
"v2_id": "GTYbJyAUHnKo41sxp1kH27fgiF",
"name": "Project1",
"color": "lime_green",
"description": "A workspace project",
"status": "IN_PROGRESS",
"total_tasks_count": 456,
"uncompleted_tasks_count": 123,
"role": "MEMBER",
"is_invite_only": false
}, ...
],
"next_cursor": "XXX",
"has_more": true
}
Returns all archived workspace projects, including those visible but not joined by the user.
Not accessible by guests. This will return a 403 Forbidden error for guests.
Command arguments
Argument | Required | Description |
---|---|---|
workspace_id String | No | ID of the workspace. |
limit Integer | No | Maximum number of workspace projects to return (100 by default, 500 maximum) |
cursor String | No | Value to iterate over the list of workspace users. Returned in API responses as the next_cursor attribute. |
Update the workspace logo
Example request to update the workspace logo:
$ curl -X POST https://api.todoist.com/sync/v9/workspaces/update_logo \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-F workspace_id=12345 \
-F file=@/path/to/logo.jpg
Example response:
{
"id": "1234",
"name": "Workspace name",
"description": "Workspace description",
"logo_big": "data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwc...",
"logo_medium": "data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwc...",
"logo_small": "data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwc...",
"logo_s640": "data:image/jpeg;base64,/9j/2wCEAAgGBgcGBQgHBwc...",
"is_invite_only_default": false,
"collaborator_role_default": "READ_WRITE",
"creator_id": "123",
"created_at": "2021-10-19T10:00:00.123456Z",
"is_deleted": false,
"is_collapsed": false,
}
Upload an image to be used as the workspace logo. Similar to a user’s avatar.
If delete
is set to true, it removes the logo completely and does not return any logo_*
attribute.
Command arguments
Argument | Required | Description |
---|---|---|
workspace_id String | Yes | ID of the workspace for the logo. |
delete Boolean | No | When true, it deletes the logo instead of updating it. |
Workspace Invitations
An example workspace invitation object:
{
"id": "234",
"workspace_id": "12345",
"inviter_id": "444",
"user_email": "foo@example.com",
"role": "MEMBER",
"is_existing_user": true
}
Properties
Property | Description |
---|---|
id String | The ID of the invitation. |
workspace_id String | ID of the workspace. |
inviter_id String | ID of the inviting user. |
user_email String | The invited person's email. |
role String | The role the user will be given if they accept the invite. Valid values are MEMBER and ADMIN . |
is_existing_user Boolean | Indicates whether the invited user is a todoist user or not. |
Invite Users to workspace
Example request to invite users to a workspace:
$ curl -X POST https://api.todoist.com/sync/v9/workspaces/invitations/create \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d workspace_id=12345 \
-d email_list=["foo@example.com", "bar@example.com"]\
-d role="MEMBER"
Example response:
{
"workspace_invitations": [
{
"id": "234",
"workspace_id": "12345",
"inviter_id": "444",
"user_email": "foo@example.com",
"role": "MEMBER",
"is_existing_user": true
},
{
"id": "235",
"workspace_id": "12345",
"inviter_id": "444",
"user_email": "bar@example.com",
"role": "MEMBER",
"is_existing_user": true
},
]
}
Create workspace invitations for a list of email addresses. Usable by all workspace members and admins.
Command arguments
Argument | Required | Description |
---|---|---|
workspace_id String | Yes | ID of the workspace. |
email_list List of String | Yes | A list of emails to be invited to the workspace. |
role String | No | The role the user will be given if they accept the invite. Possible values are 'ADMIN' and 'MEMBER'. If not provided, the default value according to the plan will be used. For Starter plans, the default is ADMIN and for Business plans, the default is MEMBER. |
Accept a workspace invitation
Example request to accept an invitation to a workspace:
$ curl -X POST https://api.todoist.com/sync/v9/workspaces/invitations/accept \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d invite_code="kwbMiLFmcmFua2llQGRvaXN0LmNvbQ"
Example response:
{
"id": "234",
"workspace_id": "12345",
"inviter_id": "444",
"user_email": "foo@example.com",
"role": "MEMBER",
"is_existing_user": true
}
Accept a workspace invitation. Usable by authenticated users only. The accepted invitation object is returned on success.
Command arguments
Argument | Required | Description |
---|---|---|
invite_code String | Yes | An opaque string representing an invite code. This invitation code is sent to a user via email and is exclusive for the user. |
Reject a workspace invitation
Example request to reject an invitation to a workspace:
$ curl -X POST https://api.todoist.com/sync/v9/workspaces/invitations/reject \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d invite_code="kwbMiLFmcmFua2llQGRvaXN0LmNvbQ"
Example response:
{
"id": "234",
"workspace_id": "12345",
"inviter_id": "444",
"user_email": "foo@example.com",
"role": "MEMBER",
"is_existing_user": true
}
Reject a workspace invitation. Usable by authenticated users only. The rejected invitation object is returned on success.
Command arguments
Argument | Required | Description |
---|---|---|
invite_code String | Yes | An opaque string representing an invite code. |
Delete a workspace invitation
Example request to delete an invitation to a workspace:
$ curl -X POST https://api.todoist.com/sync/v9/workspaces/invitations/reject \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d workspace_id=12345 \
-d user_email="foo@example.com"
Example response:
{
"id": "234",
"workspace_id": "12345",
"inviter_id": "444",
"user_email": "foo@example.com",
"role": "MEMBER",
"is_existing_user": true
}
Delete a workspace invitation. Only workspace admins can delete invitations. The deleted invitation object is returned on success.
Command arguments
Argument | Required | Description |
---|---|---|
workspace_id String | Yes | ID of the workspace. |
user_email String | Yes | Email of the invited user. |
List all pending invitations in a workspace
Example request to list all pending invitations in a workspace:
$ curl https://api.todoist.com/sync/v9/workspaces/invitations?workspace_id=12345 \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567"
Example response:
[
"foo@example.com",
"bar@example.com",
]
Return a list of user emails who have a pending invitation to a workspace. This list is not paginated.
All workspace members can access this list.
Command arguments
Argument | Required | Description |
---|---|---|
workspace_id String | Yes | ID of the workspace. |
List details of all pending invitations in a workspace
Example request to list all details of pending invitations in a workspace:
$ curl https://api.todoist.com/sync/v9/workspaces/invitations/all?workspace_id=12345 \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567"
Example response:
[
{
"id": "234",
"workspace_id": "12345",
"inviter_id": 100,
"user_email": invited_user@example.com,
"role": "ADMIN",
"is_existing_user": false,
}
]
Return a list containing details of all pending invitation to a workspace. This list is not paginated.
All workspace members can access this list.
Command arguments
Argument | Required | Description |
---|---|---|
workspace_id String | Yes | ID of the workspace. |
Invitation Properties
Property | Description |
---|---|
id String | The ID of the invitation. |
workspace_id String | ID of the workspace. |
inviter_id String | ID of the inviting user. |
user_email String | The invited person's email. |
role String | The role the user will be given if they accept the invite. Valid values are MEMBER , GUEST and ADMIN . |
is_existing_user Boolean | Indicates whether the invited user is a todoist user or not. |
Join a workspace via invite link
Example request to join a workspace via link:
$ curl -X POST https://api.todoist.com/sync/v9/workspaces/join \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d invite_code="iLFmcmFua2ll"
Example response:
{
"user_id": "555",
"workspace_id": "12345",
"role": "MEMBER",
}
Join a workspace via invite link. This only works if joining via link is enabled by the workspace admins.
Command arguments
Argument | Required | Description |
---|---|---|
invite_code String | Yes | An opaque string representing an invite code. It can be a workspace invitation code open to anyone for joining via link. The workspace must allow join via link for this to work. |
Join a workspace by domain
Example request to join a workspace by domain
$ curl -X POST https://api.todoist.com/sync/v9/workspaces/join \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d workspace_id=12345
Example response:
{
"user_id": "555",
"workspace_id": "12345",
"role": "MEMBER",
}
Join a workspace via its domain address. In order for this to work, the user issuing the command must have an account with an email address that matches the workspace domain, the account must be verified, and the workspace must allow users to join by domain.
Command arguments
Argument | Required | Description |
---|---|---|
workspace_id String | Yes | ID of the workspace. |
List a workspace's Plan Details
Example request
$ curl -X GET https://api.todoist.com/sync/v9/workspaces/plan_details?workspace_id=1234 \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
Example response:
{
"cancel_at_period_end": false,
"current_active_projects": 100,
"current_member_count": 10,
"current_plan": "Business",
"current_plan_status": "Active",
"downgrade_at": null,
"has_billing_portal": true,
"has_billing_portal_switch_to_annual": false,
"has_trialed": false,
"is_trialing": false,
"maximum_active_projects": 500,
"plan_price":
{
"amount": "2300",
"billing_cycle": "yearly",
"currency": "eur",
"tax_behavior": "exclusive"
},
"price_list":
[
{
"billing_cycle": "monthly",
"prices":
[
{
"currency": "aud",
"tax_behavior": "exclusive",
"unit_amount": 1200
},
{
"currency": "cad",
"tax_behavior": "exclusive",
"unit_amount": 1000
}
]
},
{
"billing_cycle": "yearly",
"prices":
[
{
"currency": "aud",
"tax_behavior": "exclusive",
"unit_amount": 10800
},
{
"currency": "cad",
"tax_behavior": "exclusive",
"unit_amount": 9600
}
]
}
],
"trial_ends_at": null,
"workspace_id": 1234
}
Lists details of the workspace's current plan and usage
Command arguments
Argument | Required | Description |
---|---|---|
workspace_id String | Yes | ID of the workspace. |
Plan Details Properties
Property | Description |
---|---|
cancel_at_period_end Boolean | Whether the plan will be canceled at the end of the cycle. |
current_active_projects Integer | The number of active projects in the workspace. |
current_member_count Integer | The number of members in the workspace. |
current_plan String | The name of the current plan. For example, 'Starter'. |
current_plan_status String | The status of the current plan. |
downgrade_at String | The date when the workspace will be downgraded. |
has_billing_portal Boolean | Whether a customer (and thus portal) exists for this workspace. |
has_billing_portal_switch_to_annual Boolean | Whether the plan is eligible to switch to annual billing. |
has_trialed Boolean | Whether the workspace has ever begun a teams trial. |
is_trialing Boolean | Whether the workspace is currently on a teams trial. |
maximum_active_projects Integer | The maximum number of active projects allowed in the workspace. |
plan_price Object | An object with details about the currently-active price for the plan. |
price_list List of Object | The list of all available prices for the plan. |
trial_ends_at String | The end date of the teams trial, if any. |
workspace_id String | The ID of the workspace. |
Workspace users
An example workspace_users object:
{
"user_id": "1855581",
"workspace_id": "424876",
"user_email": "you@example.com",
"full_name": "Example User",
"timezone": "GMT +3:00",
"avatar_big" : "https://*.cloudfront.net/*_big.jpg",
"avatar_medium" : "https://*.cloudfront.net/*_medium.jpg",
"avatar_s640" : "https://*.cloudfront.net/*_s640.jpg",
"avatar_small" : "https://*.cloudfront.net/*_small.jpg",
"image_id": "d160009dfd52b991030d55227003450f",
"role": "MEMBER"
}
Properties
Property | Description |
---|---|
user_id String | The user ID. |
workspace_id String | The workspace ID for this user. |
user_email String | The user email. |
full_name String | The full name of the user. |
timezone String | The timezone of the user. |
image_id String | The ID of the user's avatar. |
role String | The role of the user in this workspace. Possible values are: ADMIN, MEMBER, GUEST. A guest is someone who is a collaborator of a workspace project, without being an actual member of the workspace. |
avatar_big String | The link to a 195x195 pixels image of the user's avatar. |
avatar_medium String | The link to a 60x60 pixels image of the user's avatar. |
avatar_s640 String | The link to a 640x640 pixels image of the user's avatar. |
avatar_small String | The link to a 35x35 pixels image of the user's avatar. |
Avatar URLs are only available if the user has an avatar, in other words, when the image_id
is not null
.
workspace_users
are not the same as collaborators. Two users can be members of a common workspace without having a common shared project, so they will both “see” each other in workspace_users
but not in collaborators.
workspace_users
are not returned in full sync responses, only in incremental sync. To keep a list of workspace users up-to-date, clients should first list all workspace users, then use incremental sync to update that initial list as needed.
Guests will not receive workspace_users
sync events or resources.
List all workspace users
Example request to list all workspace users:
$ curl https://api.todoist.com/sync/v9/workspaces/users \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567"
Example response:
{
"workspace_users": [
{
"user_id": "1855581",
"workspace_id": "424876",
"user_email": "you@example.com",
"full_name": "Example User",
"timezone": "GMT +3:00",
"avatar_big" : "https://*.cloudfront.net/*_big.jpg",
"avatar_medium" : "https://*.cloudfront.net/*_medium.jpg",
"avatar_s640" : "https://*.cloudfront.net/*_s640.jpg",
"avatar_small" : "https://*.cloudfront.net/*_small.jpg",
"image_id": "d160009dfd52b991030d55227003450f",
"role": "MEMBER"
}, ...
],
"next_cursor": "XXX",
"has_more": true
}
Returns all workspace_users
for a given workspace if workspace_id
is
provided. Otherwise, returns all workspace_users
for all workspaces
that the
requesting user is part of.
Not accessible by guests.
Command arguments
Argument | Required | Description |
---|---|---|
workspace_id String | No | ID of the workspace, provided to fetch users of a single workspace. |
limit Integer | No | Maximum number of workspace users to return (100 by default, 500 maximum) |
cursor String | No | Value to iterate over the list of workspace users. Returned in API responses as the next_cursor attribute. |
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | Real or temp ID of the workspace |
user_email String | Yes | The new member's email |
role String | No | The role to be assigned to the new member. Valid values are MEMBER (default) and ADMIN . |
Change user role
Example role change for a workspace user request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "workspace_update_user",
"temp_id": "4ff1e388-5ca6-453a-b0e8-662ebf373b6b",
"uuid": "32774db9-a1da-4550-8d9d-910372124fa4",
"args": {
"workspace_id": "12345,
"user_email": "user@acme.com",
"role": "ADMIN"
}
}]'
Example response:
{
...
"sync_status": {"32774db9-a1da-4550-8d9d-910372124fa4": "ok"},
"temp_id_mapping": {"4ff1e388-5ca6-453a-b0e8-662ebf373b6b": "2203306140"},
...
}
Change the role of a workspace user.
Admins or members can not be downgraded to guests.
This command is only usable by workspace admins. Other users will get a “forbidden” error.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | Real or temp ID of the workspace |
user_email String | Yes | The new member's email |
role String | Yes | The role to be assigned to the new member. Valid values are MEMBER and ADMIN . |
Delete workspace user
Example delete workspace user request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "workspace_delete_user",
"temp_id": "4ff1e388-5ca6-453a-b0e8-662ebf373b6b",
"uuid": "32774db9-a1da-4550-8d9d-910372124fa4",
"args": {
"workspace_id": "12345",
"user_email": "user@acme.com"
}
}]'
Example response:
{
...
"sync_status": {"32774db9-a1da-4550-8d9d-910372124fa4": "ok"},
...
}
Remove a user from a workspace. That user is also removed from any workspace project they joined.
This command is only usable by workspace admins. Other users will get a “forbidden” error.
Admins can use this command to remove themselves from a workspace, unless they are the last admin in the workspace. In that case, a “forbidden” error will be returned.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | Real or temp ID of the workspace |
user_email String | Yes | The email of the member to be deleted |
Projects
An example project object:
{
"id": "2203306141",
"name": "Shopping List",
"color": "lime_green",
"parent_id": null,
"child_order": 1,
"collapsed": false,
"shared": false,
"parent_id": null,
"sync_id": null,
"is_deleted": false,
"is_archived": false,
"is_favorite": false,
"view_style": "list"
}
Properties
Property | Description |
---|---|
id String | The ID of the project. |
name String | The name of the project. |
color String | The color of the project icon. Refer to the name column in the Colors guide for more info. |
parent_id String | The ID of the parent project. Set to null for root projects. |
child_order Integer | The order of the project. Defines the position of the project among all the projects with the same parent_id |
collapsed Boolean | Whether the project's sub-projects are collapsed (a true or false value). |
shared Boolean | Whether the project is shared (a true or false value). |
can_assign_tasks Boolean | Whether tasks in the project can be assigned to users (a true or false value). |
is_deleted Boolean | Whether the project is marked as deleted (a true or false value). |
is_archived Boolean | Whether the project is marked as archived (a true or false value). |
is_favorite Boolean | Whether the project is a favorite (a true or false value). |
sync_id String | Identifier to find the match between different copies of shared projects. When you share a project, its copy has a different ID for your collaborators. To find a project in a different account that matches yours, you can use the "sync_id" attribute. For non-shared projects the attribute is set to null . |
inbox_project Boolean | Whether the project is Inbox (true or otherwise this property is not sent). |
team_inbox Boolean | Whether the project is TeamInbox (true or otherwise this property is not sent). |
view_style String | A string value (either list or board ). This determines the way the project is displayed within the Todoist clients. |
Add a project
Example add project request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "project_add",
"temp_id": "4ff1e388-5ca6-453a-b0e8-662ebf373b6b",
"uuid": "32774db9-a1da-4550-8d9d-910372124fa4",
"args": {
"name": "Shopping List"
}
}]'
Example response:
{
...
"sync_status": {"32774db9-a1da-4550-8d9d-910372124fa4": "ok"},
"temp_id_mapping": {"4ff1e388-5ca6-453a-b0e8-662ebf373b6b": "2203306141"},
...
}
Add a new project.
Command arguments
Argument | Required | Description |
---|---|---|
name String | Yes | The name of the project (a string value). |
color String | No | The color of the project icon. Refer to the name column in the Colors guide for more info. |
parent_id String | No | The ID of the parent project. Set to null for root projects |
child_order Integer | No | The order of the project. Defines the position of the project among all the projects with the same parent_id |
is_favorite Boolean | No | Whether the project is a favorite (a true or false value). |
view_style String | No | A string value (either list or board , default is list ). This determines the way the project is displayed within the Todoist clients. |
Update a project
Example update project request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands=[
{
"type": "project_update",
"uuid": "1ca42128-d12f-4a66-8413-4d6ff2838fde",
"args": {
"id": "2203306141",
"name": "Shopping"
}
}]'
Example response:
{
...
"sync_status": {"1ca42128-d12f-4a66-8413-4d6ff2838fde": "ok"},
...
}
Update an existing project.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the project (could be temp id). |
name String | No | The name of the project (a string value). |
color String | No | The color of the project icon. Refer to the name column in the Colors guide for more info. |
collapsed Boolean | No | Whether the project's sub-projects are collapsed (a true or false value). |
is_favorite Boolean | No | Whether the project is a favorite (a true or false value). |
view_style String | No | A string value (either list or board ). This determines the way the project is displayed within the Todoist clients. |
Move a project
Example move project request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands=[
{
"type": "project_move",
"uuid": "1ca42128-d12f-4a66-8413-4d6ff2838fde",
"args": {
"id": "2203306141",
"parent_id": "220325187"
}
}]'
Example response:
{
...
"sync_status": {"1ca42128-d12f-4a66-8413-4d6ff2838fde": "ok"},
...
}
Update parent project relationships of the project.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the project (could be temp id). |
parent_id String | Yes | The ID of the parent project (could be temp id). If set to null, the project will be moved to the root |
Delete a project
Example delete project request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands=[
{
"type": "project_delete",
"uuid": "367182ba-125f-4dbb-bff6-c1343fd751e4",
"args": {
"id": "2203306141"
}
}]'
Example response:
{
...
"sync_status": {"367182ba-125f-4dbb-bff6-c1343fd751e4": "ok"},
...
}
Delete an existing project and all its descendants.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | ID of the project to delete (could be a temp id). |
Archive a project
Example archive project request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands=[
{
"type": "project_archive",
"uuid": "bbec1a60-2bdd-48ac-a623-c8eb968e1697",
"args": {
"id": "2203306141"
}
}]'
Example response:
{
...
"sync_status": {"bbec1a60-2bdd-48ac-a623-c8eb968e1697": "ok"},
...
}
Archive a project and its descendants.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | ID of the project to archive (could be a temp id). |
Unarchive a project
Example unarchive project request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands=[
{
"type": "project_unarchive",
"uuid": "7d86f042-e098-4fa6-9c1f-a61fe8c39d74",
"args": {
"id": "2203306141"
}
}]'
Example response:
{
...
"sync_status": {"7d86f042-e098-4fa6-9c1f-a61fe8c39d74": "ok"},
...
}
Unarchive a project. No ancestors will be unarchived along with the unarchived project. Instead, the project is unarchived alone, loses any parent relationship (becomes a root project), and is placed at the end of the list of other root projects.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | ID of the project to unarchive (could be a temp id). |
Reorder projects
Example reorder projects request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands=[
{
"type": "project_reorder",
"uuid": "bf0855a3-0138-4b76-b895-88cad8db9edc",
"args": {
"projects": [
{
"id": "2203306141",
"child_order": 1
},
{
"id": "2203306142",
"child_order": 2
}
]
}
}]'
Example response:
{
...
"sync_status": {"bf0855a3-0138-4b76-b895-88cad8db9edc": "ok"},
...
}
The command updates child_order
properties of projects in bulk.
Command arguments
Argument | Required | Description |
---|---|---|
projects Array of Objects | Yes | An array of objects to update. Each object contains two attributes: id of the project to update and child_order , the new order. |
Get project info
Example get project info request:
$ curl https://api.todoist.com/sync/v9/projects/get \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d project_id=2203306141
Example response:
{
"project" : {
"id": "2203306141",
"name": "Shopping List",
"color": "lime_green",
"parent_id" : null,
"child_order": 3,
"collapsed": false,
"shared": false,
"is_deleted": false,
"is_archived": false,
"view_style": "list"
},
"notes" : [
{
"is_deleted": false,
"file_attachment": null,
"content": "Things I need to buy",
"posted_uid": "2671355",
"uids_to_notify": null,
"project_id": "2203306141",
"id": "2992679862",
"posted_at": "2016-05-18T16:45:00.000000Z"
},
]
}
This function is used to extract detailed information about the project, including all the notes.
It is especially important, because a full sync only returns up to 10 notes for each project. If a client requires more, they can be downloaded using this endpoint.
It returns a JSON object with the project
, and optionally the notes
attributes.
Parameters
Parameter | Required | Description |
---|---|---|
project_id String | Yes | The project's unique ID. |
all_data Boolean | No | Whether to return the notes of the project (a true or false value, while the default is true ). |
Get project data
Example get project data request:
$ curl https://api.todoist.com/sync/v9/projects/get_data \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d project_id=128501682
Example response:
{
"project": {
"child_order": 4,
"user_id": "2671355",
"is_archived": false,
"is_deleted": false,
"id": "2203306141",
"collapsed": false,
"parent_id": null,
"archived_timestamp": 0,
"color": "lime_green",
"name": "Shopping List",
"view_style": "list"
},
"items": [
{
"is_deleted": false,
"added_at": "2016-07-19T12:50:49.000000Z",
"child_order": 1,
"responsible_uid": null,
"content": "Buy Milk",
"description": "",
"id": "2995104339",
"user_id": "2671355",
"assigned_by_uid": "2671355",
"project_id": "2203306141",
"section_id": "7025",
"sync_id": null,
"collapsed": false,
"due": null,
"deadline": null,
"parent_id": null,
"labels": [],
"checked": false,
"priority": 1,
"notes_count": 1
}
],
"sections": [
{
"user_id": "2671355",
"name": "Groceries",
"is_deleted": false,
"is_archived": false,
"sync_id": null,
"section_order": 1,
"archived_at": null,
"added_at": "2019-11-06T09:37:08.000000Z",
"project_id": "2203306141",
"id": "7025",
"collapsed": false
}
],
"project_notes": [
{
"reactions": null,
"is_deleted": false,
"file_attachment": null,
"content": "Things I need to buy",
"posted_uid": "2671355",
"uids_to_notify": [],
"project_id": "2203306141",
"id": "2992679862",
"posted_at" : "2019-11-06T09:37:28.000000Z"
}
]
}
Gets a JSON object with the project
, its notes
, sections
and any uncompleted items
.
Parameters
Parameter | Required | Description |
---|---|---|
project_id String | Yes | The project's unique ID. |
Get archived projects
Example get archived projects request:
$ curl https://api.todoist.com/sync/v9/projects/get_archived \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567"
Example response:
[
{
"id": "2203306141",
"name": "Shopping List",
"child_order": 1,
"parent_id": null,
"color": "lime_green",
"collapsed": false,
"is_archived": true,
"is_deleted": false,
"view_style": "list"
}
]
Get the user's archived projects.
Parameters
Parameter | Required | Description |
---|---|---|
limit Integer | No | The maximum number of archived projects to return (between 1 and 500, default is 500). |
offset Integer | No | The offset of the first archived project to return, for pagination purposes (first page is 0). |
Templates
Templates allow exporting of a project's tasks to a file or URL, and then importing of the task list to a new or existing project.
Availability of project templates functionality is dependent
on the current user plan. This values is indicated by the templates
property of the user plan limits object.
Import a template file
Import a template in an existing project:
$ curl https://api.todoist.com/sync/v9/templates/import_into_project_from_file \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-F project_id=2203306141 \
-F file=@example.csv
Import a template in a new project, creating it:
$ curl https://api.todoist.com/sync/v9/templates/create_project_from_file \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-F name=New_project \
-F file=@example.csv
On success, HTTP 200 status is returned
A template can be imported in an existing project, or in a newly created one.
Upload a file suitable to be passed as a template to be imported into a project.
Export a template file
Example export project template request:
$ curl https://api.todoist.com/sync/v9/templates/export_as_file \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d project_id=2203306141
On success, HTTP 200 status and a CSV template is returned:
TYPE,CONTENT,DESCRIPTION,PRIORITY,INDENT,AUTHOR,RESPONSIBLE,DATE,DATE_LANG,TIMEZONE
task,Buy Milk,A description,4,1,Bob (2671362),,,en,Europe/London
,,,,,,,,
Get a template for a project as a CSV file.
Export as shareable URL
Example share project template request:
$ curl https://api.todoist.com/sync/v9/templates/export_as_url \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d project_id=2203306141
On success, a URL for the file is returned:
{
"file_name": "ShoppingList.csv",
"file_url": "https://*.cloudfront.net/ShoppingList.csv"
}
Get a template for a project as a shareable URL.
The URL can then be passed to
https://todoist.com/sync/v9/import/project_from_url?t_url=<url>
to make a shareable
template.
Sections
An example section object
{
"id" : "7025",
"name" : "Groceries",
"project_id" : "2203306141",
"section_order" : 1,
"collapsed" : false,
"user_id" : "2671355",
"sync_id" : null,
"is_deleted" : false,
"is_archived" : false,
"archived_at" : null,
"added_at" : "2019-10-07T07:09:27.000000Z"
}
Properties
Property | Description |
---|---|
id String | The ID of the section. |
name String | The name of the section. |
project_id String | Project that the section resides in |
section_order Integer | The order of the section. Defines the position of the section among all the sections in the project. |
collapsed Boolean | Whether the section's tasks are collapsed (a true or false value). |
sync_id String | A special ID for shared sections (a number or null if not set). Used internally and can be ignored. |
is_deleted Boolean | Whether the section is marked as deleted (a true or false value). |
is_archived Boolean | Whether the section is marked as archived (a true or false value). |
archived_at String | The date when the section was archived (or null if not archived). |
added_at String | The date when the section was created. |
Add a section
Example add section request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[{
"type": "section_add",
"temp_id": "69ca86df-5ffe-4be4-9c3a-ad14fe98a58a",
"uuid": "97b68ab2-f524-48da-8288-476a42cccf28",
"args": {"name": "Groceries", "project_id": "2203306141"}
}]'
Example response:
{
...
"sync_status": {"97b68ab2-f524-48da-8288-476a42cccf28": "ok"},
"temp_id_mapping": {"69ca86df-5ffe-4be4-9c3a-ad14fe98a58a": "7025"},
...
}
Add a new section to a project.
Command arguments
Argument | Required | Description |
---|---|---|
name String | Yes | The name of the section. |
project_id String | Yes | The ID of the parent project. |
section_order Integer | No | The order of the section. Defines the position of the section among all the sections in the project. |
Update a section
Example update section request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[{
"type": "section_update",
"uuid": "afda2f29-319c-4d09-8162-f2975bed3124",
"args": {"id": "7025", "name": "Supermarket"}
}]'
Example response:
{
...
"sync_status": {"afda2f29-319c-4d09-8162-f2975bed3124": "ok"},
...
}
Updates section attributes.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the section. |
name String | No | The name of the section. |
collapsed Boolean | No | Whether the section's tasks are collapsed (a true or false value). |
Move a section
Example move section request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[{
"type": "section_move",
"uuid": "a8583f66-5885-4729-9e55-462e72d685ff",
"args": {"id": "7025", "project_id": "2203306141"}
}]'
Example response:
{
...
"sync_status": {"a8583f66-5885-4729-9e55-462e72d685ff": "ok"},
...
}
Move section to a different location.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the section. |
project_id String | No | ID of the destination project. |
Reorder sections
Example reorder sections request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[{
"type": "section_reorder",
"uuid": "109af205-6ff7-47fa-a5f8-1f13e59744ef",
"args": {
"sections": [
{"id": "7025", "section_order": 1},
{"id": "7026", "section_order": 2}
]
}
}]'
Example response:
{
...
"sync_status": {"109af205-6ff7-47fa-a5f8-1f13e59744ef": "ok"},
...
}
The command updates section_order
properties of sections in bulk.
Command arguments
Argument | Required | Description |
---|---|---|
sections Array of Objects | Yes | An array of objects to update. Each object contains two attributes: id of the section to update and section_order , the new order. |
Delete a section
Example delete section request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[{
"type": "section_delete",
"uuid": "cebb5267-3e3c-40da-af44-500649281936",
"args": {"id": "7025"}
}]'
Example response:
{
...
"sync_status": {"cebb5267-3e3c-40da-af44-500649281936": "ok"},
...
}
Delete a section and all its child tasks.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | ID of the section to delete. |
Archive a section
Example archive section request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[{
"type": "section_archive",
"uuid": "2451f267-46ab-4f0e-8db7-82a9cd576f72",
"args": {"id": "7025"}
}]'
Example response:
{
...
"sync_status": {"2451f267-46ab-4f0e-8db7-82a9cd576f72": "ok"},
...
}
Archive a section and all its child tasks.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | Section ID to archive. |
Unarchive a section
Example unarchive section request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[{
"type": "section_unarchive",
"uuid": "cd3a4b4b-182e-4733-b6b5-20a621ba98b8",
"args": {"id": "7025"}
}]'
Example response:
{
...
"sync_status": {"cd3a4b4b-182e-4733-b6b5-20a621ba98b8": "ok"},
...
}
This command is used to unarchive a section.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | Section ID to unarchive |
Items
An example item object:
{
"id": "2995104339",
"user_id": "2671355",
"project_id": "2203306141",
"content": "Buy Milk",
"description": "",
"priority": 1,
"due": null,
"deadline": null,
"parent_id": null,
"child_order": 1,
"section_id": null,
"day_order": -1,
"collapsed": false,
"labels": ["Food", "Shopping"],
"added_by_uid": "2671355",
"assigned_by_uid": "2671355",
"responsible_uid": null,
"checked": false,
"is_deleted": false,
"sync_id": null,
"added_at": "2014-09-26T08:25:05.000000Z",
"duration": {
"amount": 15,
"unit": "minute"
},
}
Properties
Property | Description |
---|---|
id String | The ID of the task. |
user_id String | The owner of the task. |
project_id String | The ID of the parent project. |
content String | The text of the task. This value may contain markdown-formatted text and hyperlinks. Details on markdown support can be found in the Text Formatting article in the Help Center. |
description String | A description for the task. This value may contain markdown-formatted text and hyperlinks. Details on markdown support can be found in the Text Formatting article in the Help Center. |
due Object | The due date of the task. See the Due dates section for more details. |
deadline Object | The deadline of the task. See the Deadlines section for more details. |
priority Integer | The priority of the task (a number between 1 and 4 , 4 for very urgent and 1 for natural). Note: Keep in mind that very urgent is the priority 1 on clients. So, p1 will return 4 in the API. |
parent_id String | The ID of the parent task. Set to null for root tasks. |
child_order Integer | The order of the task. Defines the position of the task among all the tasks with the same parent. |
section_id String | The ID of the parent section. Set to null for tasks not belonging to a section. |
day_order Integer | The order of the task inside the Today or Next 7 days view (a number, where the smallest value would place the task at the top). |
collapsed Boolean | Whether the task's sub-tasks are collapsed (a true or false value). |
labels Array of String | The task's labels (a list of names that may represent either personal or shared labels). |
added_by_uid String | The ID of the user who created the task. This makes sense for shared projects only. For tasks created before 31 Oct 2019 the value is set to null. Cannot be set explicitly or changed via API. |
assigned_by_uid String | The ID of the user who assigned the task. This makes sense for shared projects only. Accepts any user ID from the list of project collaborators. If this value is unset or invalid, it will automatically be set up to your uid. |
responsible_uid String | The ID of user who is responsible for accomplishing the current task. This makes sense for shared projects only. Accepts any user ID from the list of project collaborators or null or an empty string to unset. |
checked Boolean | Whether the task is marked as completed (a true or false value). |
is_deleted Boolean | Whether the task is marked as deleted (a true or false value). |
sync_id String | Identifier to find the match between tasks in shared projects of different collaborators. When you share a task, its copy has a different ID in the projects of your collaborators. To find a task in another account that matches yours, you can use the "sync_id" attribute. For non-shared tasks, the attribute is null . |
completed_at String | The date when the task was completed (or null if not completed). |
added_at String | The date when the task was created. |
duration Object | Object representing a task's duration. Includes a positive integer (greater than zero) for the amount of time the task will take, and the unit of time that the amount represents which must be either minute or day . Both the amount and unit must be defined. The object will be null if the task has no duration. |
Add an item
Example add item request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "item_add",
"temp_id": "43f7ed23-a038-46b5-b2c9-4abda9097ffa",
"uuid": "997d4b43-55f1-48a9-9e66-de5785dfd69b",
"args": {
"content": "Buy Milk",
"project_id": "2203306141",
"labels": ["Food", "Shopping"]
}
}]'
Example response:
{
...
"sync_status": {"997d4b43-55f1-48a9-9e66-de5785dfd69b": "ok"},
"temp_id_mapping": {"43f7ed23-a038-46b5-b2c9-4abda9097ffa": "2995104339"},
...
}
Add a new task to a project.
Command arguments
Argument | Required | Description |
---|---|---|
content String | Yes | The text of the task. This value may contain markdown-formatted text and hyperlinks. Details on markdown support can be found in the Text Formatting article in the Help Center. |
description String | No | A description for the task. This value may contain markdown-formatted text and hyperlinks. Details on markdown support can be found in the Text Formatting article in the Help Center. |
project_id String | No | The ID of the project to add the task to (a number or a temp id). By default the task is added to the user’s Inbox project. |
due Object | No | The due date of the task. See the Due dates section for more details. |
deadline Object | No | The deadline of the task. See the Deadlines section for more details. |
priority Integer | No | The priority of the task (a number between 1 and 4 , 4 for very urgent and 1 for natural). Note: Keep in mind that very urgent is the priority 1 on clients. So, p1 will return 4 in the API. |
parent_id String | No | The ID of the parent task. Set to null for root tasks. |
child_order Integer | No | The order of task. Defines the position of the task among all the tasks with the same parent. |
section_id String | No | The ID of the section. Set to null for tasks not belonging to a section. |
day_order Integer | No | The order of the task inside the Today or Next 7 days view (a number, where the smallest value would place the task at the top). |
collapsed Boolean | No | Whether the task's sub-tasks are collapsed (a true or false value). |
labels Array of String | No | The task's labels (a list of names that may represent either personal or shared labels). |
assigned_by_uid String | No | The ID of user who assigns the current task. This makes sense for shared projects only. Accepts 0 or any user ID from the list of project collaborators. If this value is unset or invalid, it will be automatically setup to your uid. |
responsible_uid String | No | The ID of user who is responsible for accomplishing the current task. This makes sense for shared projects only. Accepts any user ID from the list of project collaborators or null or an empty string to unset. |
auto_reminder Boolean | No | When this option is enabled, the default reminder will be added to the new item if it has a due date with time set. See also the auto_reminder user option for more info about the default reminder. |
auto_parse_labels Boolean | No | When this option is enabled, the labels will be parsed from the task content and added to the task. In case the label doesn't exist, a new one will be created. |
duration Object | No | The task's duration. Includes a positive integer (greater than zero) for the amount of time the task will take, and the unit of time that the amount represents which must be either minute or day . Both the amount and unit must be defined. |
Update an item
Example update item request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "item_update",
"uuid": "318d16a7-0c88-46e0-9eb5-cde6c72477c8",
"args": {
"id": "2995104339",
"priority": 2
}
}]'
Example response:
{
...
"sync_status": {"318d16a7-0c88-46e0-9eb5-cde6c72477c8": "ok"},
...
}
Updates task attributes. Please note that updating the parent, moving,
completing or uncompleting tasks is not supported by item_update
, more
specific commands have to be used instead.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the task. |
content String | No | The text of the task. This value may contain markdown-formatted text and hyperlinks. Details on markdown support can be found in the Text Formatting article in the Help Center. |
description String | No | A description for the task. This value may contain markdown-formatted text and hyperlinks. Details on markdown support can be found in the Text Formatting article in the Help Center. |
due Object | No | The due date of the task. See the Due dates section for more details. |
deadline Object | No | The deadline of the task. See the Deadlines section for more details. |
priority Integer | No | The priority of the task (a number between 1 and 4 , 4 for very urgent and 1 for natural). Note: Keep in mind that very urgent is the priority 1 on clients. So, p1 will return 4 in the API. |
collapsed Boolean | No | Whether the task's sub-tasks are collapsed (a true or false value). |
labels Array of String | No | The task's labels (a list of names that may represent either personal or shared labels). |
assigned_by_uid String | No | The ID of the user who assigned the task. This makes sense for shared projects only. Accepts 0 or any user ID from the list of project collaborators. If this value is unset or invalid, it will be automatically setup to your uid. |
responsible_uid String | No | The ID of the user who is responsible for accomplishing the task. This makes sense for shared projects only. Accepts any user ID from the list of project collaborators or null or an empty string to unset. |
day_order Integer | No | The order of the task inside the Today or Next 7 days view (a number, where the smallest value would place the task at the top). |
duration Object | No | The task's duration. Must a positive integer (greater than zero) for the amount of time the task will take, and the unit of time that the amount represents which must be either minute or day . Both the amount and unit must be defined. The object should be set to null to remove the task's duration. |
Move an item
Example move item request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "item_move",
"uuid": "318d16a7-0c88-46e0-9eb5-cde6c72477c8",
"args": {
"id": "2995104339",
"parent_id": "2995104340"
}
}]'
Example response:
{
...
"sync_status": {"318d16a7-0c88-46e0-9eb5-cde6c72477c8": "ok"},
...
}
Move task to a different location. Only one of parent_id
, section_id
or
project_id
must be set.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the task. |
parent_id String | No | ID of the destination parent task. The task becomes the last child task of the parent task. |
section_id String | No | ID of the destination section. The task becomes the last root task of the section. |
project_id String | No | ID of the destination project. The task becomes the last root task of the project. |
Note, to move an item from a section to no section, just use the
project_id
parameter, with the project it currently belongs to as a value.
Reorder items
Example reorder items request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands=[
{
"type": "item_reorder",
"uuid": "bf0855a3-0138-4b76-b895-88cad8db9edc",
"args": {
"items": [
{"id": "2995104339", "child_order": 1},
{"id": "2995104340", "child_order": 2}
]
}
}]'
Example response:
{
...
"sync_status": {"bf0855a3-0138-4b76-b895-88cad8db9edc": "ok"},
...
}
The command updates child_order
properties of items in bulk.
Command arguments
Argument | Required | Description |
---|---|---|
items Array of Objects | Yes | An array of objects to update. Each object contains two attributes: id of the item to update and child_order , the new order. |
Delete item
Example delete item request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "item_delete",
"uuid": "f8539c77-7fd7-4846-afad-3b201f0be8a5",
"args": {"id": "2995104339"}
}]'
Example response:
{
...
"sync_status": {"f8539c77-7fd7-4846-afad-3b201f0be8a5": "ok"},
...
}
Delete a task and all its sub-tasks.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | ID of the task to delete. |
Complete item
Example complete item request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "item_complete",
"uuid": "a74bfb5c-5f1d-4d14-baea-b7415446a871",
"args": {
"id": "2995104339",
"date_completed": "2017-01-02T01:00:00.000000Z"
}
}]'
Example response:
{
...
"sync_status": {"a74bfb5c-5f1d-4d14-baea-b7415446a871": "ok"},
...
}
Completes a task and its sub-tasks and moves them to the archive. See also item_close
for a
simplified version of the command.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | Task ID to complete. |
date_completed Date | No | RFC3339-formatted date of completion of the task (in UTC). If not set, the server will set the value to the current timestamp. |
Uncomplete item
Example uncomplete item request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "item_uncomplete",
"uuid": "710a60e1-174a-4313-bb9f-4df01e0349fd",
"args": {"id": "2995104339"}
}]'
Example response:
{
...
"sync_status": {"710a60e1-174a-4313-bb9f-4df01e0349fd": "ok"},
...
}
This command is used to uncomplete and restore an archived item.
Any ancestor items or sections will also be reinstated. Items will have the checked
value reset.
The reinstated items and sections will appear at the end of the list within their parent, after any previously active items.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | Task ID to uncomplete |
Complete a recurring task
Example complete recurring item request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "item_update_date_complete",
"uuid": "c5888360-96b1-46be-aaac-b49b1135feab",
"args": {
"id": "2995104339",
"due": {"date": "2014-10-30", "string": "every day"},
"is_forward": 1,
"reset_subtasks": 0
}
}]
Example response:
{
...
"sync_status": {"c5888360-96b1-46be-aaac-b49b1135feab": "ok"},
...
}
Complete a recurring task. The reason why this is a special case is because
we need to mark a recurring completion (and using item_update
won't do
this). See also item_close
for a simplified version of the command.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the item to update (a number or a temp id). |
due Object | No | The due date of the task. See the Due dates section for more details. |
is_forward Boolean | No | Set this argument to 1 for completion, or 0 for uncompletion (e.g., via undo). By default, this argument is set to 1 (completion). |
reset_subtasks Boolean | No | Set this property to 1 to reset subtasks when a recurring task is completed. By default, this property is not set (0), and subtasks will retain their existing status when the parent task recurs. |
Close item
Example close item request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "item_close",
"uuid": "c5888360-96b1-46be-aaac-b49b1135feab",
"args": {"id": "2995104339"}
}]'
Example response:
{
...
"sync_status": {"c5888360-96b1-46be-aaac-b49b1135feab": "ok"},
...
}
A simplified version of item_complete
/ item_update_date_complete
. The command
does exactly what official clients do when you close a task: regular tasks are
completed and moved to the archive, recurring tasks are scheduled to their next occurrence.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the item to close (a number or a temp id). |
Update day orders
Example update day orders request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "item_update_day_orders",
"uuid": "dbeb40fc-905f-4d8a-8bae-547d3bbd6e91",
"args": {"ids_to_orders": {"2995104339": 1}}
}]'
Example response:
{
...
"sync_status": {"dbeb40fc-905f-4d8a-8bae-547d3bbd6e91": "ok"},
...
}
Update the day orders of multiple items at once.
Command arguments
Argument | Required | Description |
---|---|---|
ids_to_orders Object | Yes | A dictionary, where an item id is the key, and the day_order value: item_id: day_order . |
Get item info
Example get item info request:
$ curl https://api.todoist.com/sync/v9/items/get \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d item_id=2995104339
Example response:
{
"ancestors": [
{
"added_by_uid": "2671355",
"assigned_by_uid": null,
"checked": false,
"child_order": 0,
"collapsed": false,
"content": "A parent task",
"description": "",
"added_at": "2021-03-18T13:23:17.000000Z",
"completed_at": null,
"due": null,
"deadline": null,
"id": "2995104589",
"is_deleted": false,
"labels": [],
"parent_id": null,
"priority": 1,
"project_id": "2203306141",
"responsible_uid": null,
"section_id": "7025",
"sync_id": null,
"user_id": "2671355"
}
],
"item": {
"added_by_uid": "2671355",
"assigned_by_uid": null,
"checked": false,
"child_order": 1,
"collapsed": false,
"content": "Buy Milk",
"description": "",
"added_at": "2021-03-18T13:21:33.000000Z",
"completed_at": null,
"due": null,
"deadline": null,
"id": "2995104339",
"is_deleted": false,
"labels": ["Food", "Shopping"],
"parent_id": "2995104589",
"priority": 1,
"project_id": "2203306141",
"responsible_uid": null,
"section_id": "7025",
"sync_id": null,
"user_id": "2671355"
},
"notes": [
{
"content": "Remember this!",
"file_attachment": null,
"id": "2992679862",
"is_deleted": false,
"item_id": "2995104339",
"posted_at": "2021-03-18T13:21:46.000000Z",
"posted_uid": "2671355",
"reactions": null,
"uids_to_notify": []
}
],
"project": {
"child_order": 6,
"collapsed": false,
"color": "lime_green",
"id": "2203306141",
"is_archived": false,
"is_deleted": false,
"is_favorite": true,
"name": "Shopping List",
"parent_id": null,
"shared": false,
"sync_id": null,
"view_style": "list"
},
"section": {
"collapsed": false,
"added_at": "2021-03-18T13:21:15.000000Z",
"archived_at": null,
"id": "7025",
"is_archived": false,
"is_deleted": false,
"name": "Groceries",
"project_id": "2203306141",
"section_order": 1,
"sync_id": null,
"user_id": "2671355"
}
}
This endpoint returns detailed information about an item and any related entities.
It is especially important, because a full sync only returns up to 10 notes for each item. If a client requires more, they can be downloaded with this endpoint.
It returns a JSON object with the item
, and details of any ancestors
,
the parent project
, parent section
if assigned, and any notes
.
If all_data
is set to false
, only the data for the item will be returned.
Parameters
Parameter | Required | Description |
---|---|---|
item_id String | Yes | The item's unique ID. |
all_data Boolean | No | Whether to return ancestors , project , section and notes of the item (the default is true ). |
Get all completed items
Example get completed items request:
$ curl https://api.todoist.com/sync/v9/completed/get_all \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567"
Example response:
{
"items": [
{
"content": "Buy Milk",
"meta_data": null,
"user_id": "2671355",
"task_id": "2995104339",
"note_count": 0,
"project_id": "2203306141",
"section_id": "7025",
"completed_at": "2015-02-17T15:40:41.000000Z",
"id": "1899066186"
}
],
"projects": {
"2203306141": {
"color": "lime_green",
"collapsed": false,
"parent_id": null,
"is_deleted": false,
"id": "2203306141",
"user_id": "2671355",
"name": "Shopping List",
"child_order": 36,
"is_archived": false,
"view_style": "list"
}
},
"sections": {
"7025": {
"collapsed": false,
"added_at": "2021-03-18T13:21:15.000000Z",
"archived_at": null,
"id": "7025",
"is_archived": false,
"is_deleted": false,
"name": "Groceries",
"project_id": "2203306141",
"section_order": 1,
"sync_id": null,
"user_id": "2671355"
}
}
}
Availability of the completed tasks archive is dependent on the current user plan.
This value is indicated by the completed_tasks
property of the
user plan limits object.
Get all the user's completed items (tasks).
Parameters
Parameter | Required | Description |
---|---|---|
project_id String | No | Filter the tasks by project ID. |
limit Integer | No | The number of items to return (where the default is 30 , and the maximum is 200 ). |
offset Integer | No | Can be used for pagination, when more than the limit number of tasks are returned. |
until String | No | Return items with a completed date same or older than until (a string value formatted as 2021-4-29T10:13:00 ). |
since String | No | Return items with a completed date newer than since (a string value formatted as 2021-4-29T10:13:00 ). |
annotate_notes Boolean | No | Return notes together with the completed items (a true or false value). |
annotate_items Boolean | No | Returns the full user item within the payload |
Return values
Property | Description |
---|---|
id String | The ID of the completed task entry. |
task_id String | The ID of the task. |
user_id String | The owner of the task. |
project_id String | ID of the parent project. |
section_id String | ID of the parent section. |
content String | The text of the task. This value may contain markdown-formatted text and hyperlinks. Details on markdown support can be found in the Text Formatting article in the Help Center. |
completed_at String | The date when the task was completed. |
note_count Integer | The number of notes of the task. |
meta_data String | Optional extra details. |
item_object Item | If annotate_items is set to true, will contain the full item object |
Quick add an item
Example quick add item request:
$ curl https://api.todoist.com/sync/v9/quick/add \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d text='Buy Milk @Drinks #ShoppingList +Bob'
Example response:
{
"added_by_uid": "2671355",
"assigned_by_uid": "2671355",
"labels": [ "Food", "Shopping" ],
"sync_id": null,
"added_at": "2015-02-18T11:09:11.000000Z",
"parent_id": null,
"content": "Buy Milk",
"description": "",
"is_deleted": false,
"user_id": "2671355",
"due": null,
"deadline": null,
"id": "2995104339",
"priority": 4,
"child_order": 1,
"responsible_uid": "2671355",
"project_id": "2203306141",
"collapsed": false,
"checked": false,
"duration": null,
}
Add a new item using the Quick Add implementation similar to that used in the official clients.
Parameters
Parameter | Required | Description |
---|---|---|
text String | Yes | The text of the task that is parsed. It can include a due date in free form text, a project name starting with the # character (without spaces), a label starting with the @ character, an assignee starting with the + character, a priority (e.g., p1 ), a deadline between {} (e.g. {in 3 days}), or a description starting from // until the end of the text. |
note String | No | The content of the note. |
reminder String | No | The date of the reminder, added in free form text. |
auto_reminder Boolean | No | When this option is enabled, the default reminder will be added to the new item if it has a due date with time set. See also the auto_reminder user option for more info about the default reminder. |
Labels
An example personal label object:
{
"id": "2156154810",
"name": "Food",
"color": "lime_green",
"item_order": 0,
"is_deleted": false,
"is_favorite": false
}
There are two types of labels that can be added to Todoist tasks. We refer to these as 'personal' and 'shared' labels.
Personal labels
Labels created by the current user will show up in their personal label list. These labels can be customized and will stay in their account unless deleted.
A personal label can be converted to a shared label by the user if they no longer require them to be stored against their account, but they still appear on shared tasks.
Shared labels
A label created by a collaborator that doesn't share a name with an existing personal label will appear in our clients as a shared label. These labels are gray by default and will only stay in the shared labels list if there are any active tasks with this label.
A user can convert a shared label to a personal label at any time. The label will then become customizable and will remain in the account even if not assigned to any active tasks.
Shared labels do not appear in the sync response for a user's account. They only appear
within the labels
list of the items that they are assigned to.
You can find more information on the differences between personal and shared labels in our Help Center.
Properties (only applicable to personal labels)
Property | Description |
---|---|
id String | The ID of the label. |
name String | The name of the label. |
color String | The color of the label icon. Refer to the name column in the Colors guide for more info. |
item_order Integer | Label’s order in the label list (a number, where the smallest value should place the label at the top). |
is_deleted Boolean | Whether the label is marked as deleted (a true or false value). |
is_favorite Boolean | Whether the label is a favorite (a true or false value). |
Add a personal label
Example add label request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "label_add",
"temp_id": "f2f182ed-89fa-4bbb-8a42-ec6f7aa47fd0",
"uuid": "ba204343-03a4-41ff-b964-95a102d12b35",
"args": {"name": "Food"}
}]'
Example response:
{
...
"sync_status": {"ba204343-03a4-41ff-b964-95a102d12b35": "ok"},
"temp_id_mapping": {"f2f182ed-89fa-4bbb-8a42-ec6f7aa47fd0": "2156154810"},
...
}
Command arguments
Argument | Required | Description |
---|---|---|
name String | Yes | The name of the label |
color String | No | The color of the label icon. Refer to the name column in the Colors guide for more info. |
item_order Integer | No | Label’s order in the label list (a number, where the smallest value should place the label at the top). |
is_favorite Boolean | No | Whether the label is a favorite (a true or false value). |
Update a personal label
Example update label request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "label_update",
"uuid": "9c9a6e34-2382-4f43-a217-9ab017a83523",
"args": {"id": "2156154810", "color": "berry_red"}
}]'
Example response:
{
...
"sync_status": {"9c9a6e34-2382-4f43-a217-9ab017a83523": "ok"},
...
}
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the label. |
name String | No | The name of the label. |
color String | No | The color of the label icon. Refer to the name column in the Colors guide for more info. |
item_order Integer | No | Label’s order in the label list. |
is_favorite Boolean | No | Whether the label is a favorite (a true or false value). |
Delete a personal label
Example delete label request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "label_delete",
"uuid": "aabaa5e0-b91b-439c-aa83-d1b35a5e9fb3",
"args": {
"id": "2156154810",
"cascade": "all"
}
}]'
Example response:
{
...
"sync_status": {"aabaa5e0-b91b-439c-aa83-d1b35a5e9fb3": "ok"},
...
}
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the label. |
cascade String | No | A string value, either all (default) or none . If no value or all is passed, the personal label will be removed and any instances of the label will also be removed from tasks (including tasks in shared projects). If none is passed, the personal label will be removed from the user's account but it will continue to appear on tasks as a shared label. |
Rename a shared label
Example rename shared label request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "label_rename",
"uuid": "b863b0e5-2541-4a5a-a462-ce265ae2ff2d",
"args": {
"name_old": "Food",
"name_new": "Drink"
}
}]'
Example response:
{
...
"sync_status": {"b863b0e5-2541-4a5a-a462-ce265ae2ff2d": "ok"},
...
}
This command enables renaming of shared labels. Any tasks containing a label matching the
value of name_old
will be updated with the new label name.
Command arguments
Argument | Required | Description |
---|---|---|
name_old String | Yes | The current name of the label to modify. |
name_new String | Yes | The new name for the label. |
Delete shared label occurrences
Example delete shared label request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "label_delete_occurrences",
"uuid": "6174264a-2842-410c-a8ff-603ec4d4736b",
"args": {
"name": "Shopping"
}
}]'
Example response:
{
...
"sync_status": {"6174264a-2842-410c-a8ff-603ec4d4736b": "ok"},
...
}
Deletes all occurrences of a shared label from any active tasks.
Command arguments
Argument | Required | Description |
---|---|---|
name String | Yes | The name of the label to remove. |
Update multiple label orders
Example update label orders request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands=[
{
"type": "label_update_orders",
"uuid": "1402a911-5b7a-4beb-bb1f-fb9e1ed798fb",
"args": {
"id_order_mapping": {"2156154810": 1, "2156154820": 2}
}
}]'
Example response:
{
...
"sync_status": {
"517560cc-f165-4ff6-947b-3adda8aef744": "ok"},
...
},
...
}
Command arguments
Argument | Required | Description |
---|---|---|
id_order_mapping Object | Yes | A dictionary, where a label id is the key, and the item_order value. |
Notes
Item Notes
An example task note:
{
"id": "2992679862",
"posted_uid": "2671355",
"item_id": "2995104339",
"content": "Note",
"file_attachment": {
"file_type": "text/plain",
"file_name": "File1.txt",
"file_size": 1234,
"file_url": "https://example.com/File1.txt",
"upload_state": "completed"
},
"uids_to_notify": null,
"is_deleted": false,
"posted_at": "2014-10-01T14:54:55.000000Z",
"reactions": {"❤️": ["2671362"], "👍": ["2671362", "2671366"]}
}
Availability of comments functionality is dependent on the current user plan.
This value is indicated by the comments
property of the
user plan limits object.
Properties
Property | Description |
---|---|
id String | The ID of the note. |
posted_uid String | The ID of the user that posted the note. |
item_id String | The item which the note is part of. |
content String | The content of the note. This value may contain markdown-formatted text and hyperlinks. Details on markdown support can be found in the Text Formatting article in the Help Center. |
file_attachment Object | A file attached to the note (see the File Attachments section for details). |
uids_to_notify Array of String | A list of user IDs to notify. |
is_deleted Boolean | Whether the note is marked as deleted (a true or false value). |
posted_at String | The date when the note was posted. |
reactions Object | List of emoji reactions and corresponding user IDs. |
Add an item note
Example add note request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "note_add",
"temp_id": "59fe4461-287b-4b00-bacc-ee771137a732",
"uuid": "e1005f08-acd6-4172-bab1-4338f8616e49",
"args": {
"item_id": "2995104339",
"content": "Note1"
}
}]'
# or adding a note with a file attached:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "note_add",
"temp_id": "6149e689-1a54-48d6-a8c2-0ee5425554a9",
"uuid": "554a65e9-56d9-478e-b35b-520c419e37d9",
"args": {
"item_id": "2995104339",
"content": "Note1",
"file_attachment": {
"file_type": "image\/gif",
"file_name": "image.gif",
"image": "https:\/\/domain\/image.gif",
"file_url": "https:\/\/domain\/image.gif",
"image_width":90,
"image_height":76,
"file_size":7962
}
}
}]'
Example response:
{
...
"sync_status": {"e1005f08-acd6-4172-bab1-4338f8616e49": "ok"},
"temp_id_mapping": {"59fe4461-287b-4b00-bacc-ee771137a732": "2992679862"},
...
}
Command arguments
Argument | Required | Description |
---|---|---|
item_id String | Yes | The item which the note is part of (a unique number or temp id). |
content String | Yes | The content of the note. This value may contain markdown-formatted text and hyperlinks. Details on markdown support can be found in the Text Formatting article in the Help Center. |
file_attachment Object | No | A file attached to the note (see the File Attachments section for details, and learn how to upload a file in the Uploads section). |
uids_to_notify Array of String | No | A list of user IDs to notify. |
Update an item note
Example update note request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "note_update",
"uuid": "8a38f9c5-2cd0-4da5-87c1-26d617b354e0",
"args": {
"id": "2992679862",
"content": "UpdatedNote1"
}
}]'
Example response:
{
...
"sync_status": {"8a38f9c5-2cd0-4da5-87c1-26d617b354e0": "ok"},
...
}
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the note. |
content String | Yes | The content of the note. This value may contain markdown-formatted text and hyperlinks. Details on markdown support can be found in the Text Formatting article in the Help Center. |
file_attachment Object | No | A file attached to the note (see the File Attachments section for details, and learn how to upload a file in the Uploads section). |
Delete an item note
Example delete note request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "note_delete",
"uuid": "8d666fda-73c3-4677-8b04-5d223632c24f",
"args": {"id": "2992679862"}
}]'
Example response:
{ ...
"sync_status": {"8d666fda-73c3-4677-8b04-5d223632c24f": "ok"},
...
}
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the note. |
Project Notes
An example project note:
{
"content": "Hello 2",
"id": "2992679862",
"is_deleted": false,
"posted_at": "2018-08-14T10:56:50.000000Z",
"posted_uid": "2671355",
"project_id": "2203306141",
"reactions": null,
"uids_to_notify": ["2671362"],
"reactions": {"❤️": ["2671362"], "👍": ["2671362", "2671366"]},
"file_attachment": {
"file_type": "text/plain",
"file_name": "File1.txt",
"file_size": 1234,
"file_url": "https://example.com/File1.txt",
"upload_state": "completed"
}
}
Availability of comments functionality is dependent on the current user plan.
This value is indicated by the comments
property of the
user plan limits object.
Properties
Property | Description |
---|---|
id String | The ID of the note. |
posted_uid String | The ID of the user that posted the note. |
project_id String | The project which the note is part of. |
content String | The content of the note. This value may contain markdown-formatted text and hyperlinks. Details on markdown support can be found in the Text Formatting article in the Help Center. |
file_attachment Object | A file attached to the note (see the File Attachments section for details). |
uids_to_notify Array of String | A list of user IDs to notify. |
is_deleted Boolean | Whether the note is marked as deleted (a true or false value). |
posted_at String | The date when the note was posted. |
reactions Object | List of emoji reactions and corresponding user IDs. |
Add a project note
Example add note request:
curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "note_add",
"temp_id": "59fe4461-287b-4b00-bacc-ee771137a732",
"uuid": "e1005f08-acd6-4172-bab1-4338f8616e49",
"args": {
"project_id": "2203306141",
"content": "Note1"
}
}]'
# or adding a note with a file attached:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "note_add",
"temp_id": "6149e689-1a54-48d6-a8c2-0ee5425554a9",
"uuid": "554a65e9-56d9-478e-b35b-520c419e37d9",
"args": {
"project_id": "2203306141",
"content": "Note1",
"file_attachment": {
"file_type": "image\/gif",
"file_name": "image.gif",
"image": "https:\/\/domain\/image.gif",
"file_url": "https:\/\/domain\/image.gif",
"image_width":90,
"image_height":76,
"file_size":7962
}
}
}]'
Example response:
{
...
"sync_status": {"e1005f08-acd6-4172-bab1-4338f8616e49": "ok"},
"temp_id_mapping": {"59fe4461-287b-4b00-bacc-ee771137a732": "2992679862"},
...
}
Argument | Required | Description |
---|---|---|
project_id String | Yes | The project which the note is part of. |
content String | Yes | The content of the note. This value may contain markdown-formatted text and hyperlinks. Details on markdown support can be found in the Text Formatting article in the Help Center. |
file_attachment Object | No | A file attached to the note (see the File Attachments section for details, and learn how to upload a file in the Uploads section). |
Update a project note
Example update note request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "note_update",
"uuid": "8a38f9c5-2cd0-4da5-87c1-26d617b354e0",
"args": {"id": "2992679862", "content": "UpdatedNote1"}
}]'
Example response:
{
...
"sync_status": {"8a38f9c5-2cd0-4da5-87c1-26d617b354e0": "ok"},
...
}
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the note. |
content String | Yes | The content of the note. This value may contain markdown-formatted text and hyperlinks. Details on markdown support can be found in the Text Formatting article in the Help Center. |
file_attachment Object | No | A file attached to the note (see the File Attachments section for details, and learn how to upload a file in the Uploads section). |
Delete a project note
Example delete note request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "note_delete",
"uuid": "8a38f9c5-2cd0-4da5-87c1-26d617b354e0",
"args": {"id": "2992679862"}
}]'
Example response:
{
...
"sync_status": {"8d666fda-73c3-4677-8b04-5d223632c24f": "ok"},
...
}
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the note. |
File Attachments
A file attachment is represented as a JSON object. The file attachment may point
to a document previously uploaded by the uploads/add
API call, or by any
external resource.
Base file properties
Attribute | Description |
---|---|
file_name String | The name of the file. |
file_size Integer | The size of the file in bytes. |
file_type String | MIME type (for example text/plain or image/png ). |
file_url String | The URL where the file is located. Note that we don't cache the remote content on our servers and stream or expose files directly from third party resources. In particular this means that you should avoid providing links to non-encrypted (plain HTTP) resources, as exposing this files in Todoist may issue a browser warning. |
upload_state String | Upload completion state (for example pending or completed ). |
Image file properties
If you upload an image, you may provide thumbnail paths to ensure Todoist
handles them appropriately. Valid thumbnail information is a JSON array with
URL, width in pixels, height in pixels. Ex.:
["https://example.com/img.jpg",400,300]. "Canonical" thumbnails (ones we create
by uploads/add
API call) have the following sizes: 96x96
, 288x288
,
528x528
.
Attribute | Description |
---|---|
tn_l List | Large thumbnail (a list that contains the URL, the width and the height of the thumbnail). |
tn_m List | Medium thumbnail (a list that contains the URL, the width and the height of the thumbnail). |
tn_s List | Small thumbnail (a list that contains the URL, the width and the height of the thumbnail). |
Audio file properties
If you upload an audio file, you may provide an extra attribute file_duration
(duration of the audio file in seconds, which takes an integer value). In the
web interface the file is rendered with a <audio>
tag, so you should make sure
it's supported in current web browsers. See
supported media formats for
the reference.
Uploads
Availability of uploads functionality and the maximum size for a file attachment are dependent
on the current user plan. These values are indicated by the uploads
and upload_limit_mb
properties of the user plan limits object.
Files can be uploaded to our servers and used as file attachments in Notes.
Upload a file
Example file upload request:
$ curl https://api.todoist.com/sync/v9/uploads/add \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-F file_name=example.jpg \
-F file=@/path/to/example.jpg
On success, HTTP 200 status and a JSON object of file data is returned:
{
"file_name": "example.jpg",
"file_size": 85665,
"file_type": "image/jpeg",
"file_url": "https://*.cloudfront.net/*/example.jpg",
"tn_l": [
"https://*.cloudfront.net/tn_l_*.jpg",
400, 309
],
"tn_m": [
"https://*.cloudfront.net/tn_m_*.jpg",
288, 222
],
"tn_s": [
"https://*.cloudfront.net/tn_s_*.jpg",
96, 74
]
}
Upload a file suitable to be passed as a file_attachment
attribute to the
note_add
or note_update
calls.
Parameters
Parameter | Required | Description |
---|---|---|
file_name String | Yes | The file name to be uploaded. |
Base file properties
Attribute | Description |
---|---|
file_name String | The name of the file. |
file_size Integer | The size of the file in bytes. |
file_type String | MIME type (i.e. text/plain , image/png ). |
file_url String | The URL where the file is located (a string value representing an HTTP URL). Note that we don't cache the remote content on our servers and stream or expose files directly from third party resources. In particular this means that you should avoid providing links to non-encrypted (plain HTTP) resources, as exposing this files in Todoist may issue a browser warning. |
upload_state String | Upload completion state (either pending or completed ). |
Image file properties
If you upload an image, you may provide thumbnail paths to ensure Todoist
handles them appropriately. Valid thumbnail information is a JSON array with
URL, width in pixels, height in pixels. Ex.:
["http://example.com/img.jpg",400,300]
. "Canonical" thumbnails (ones we create
by uploads/add
API call) have following sizes: 96x96
, 288x288
, 528x528
.
Attribute | Description |
---|---|
tn_l List | Large thumbnail (a list that contains the URL, the width and the height of the thumbnail). |
tn_m List | Medium thumbnail (a list that contains the URL, the width and the height of the thumbnail). |
tn_s List | Small thumbnail (a list that contains the URL, the width and the height of the thumbnail). |
Audio file properties
If you upload an audio file, you may provide an extra attribute file_duration
(duration of the audio file in seconds, which takes an integer value). In the
web interface the file is rendered back with a <audio>
tag, so you should make
sure it's supported in current web
browsers. See
supported media formats for
the reference.
Delete upload
Example delete upload request:
$ curl https://api.todoist.com/sync/v9/uploads/delete \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d file_url='https://*.cloudfront.net/*/example.jpg'
On success, HTTP 200 status is returned
Delete an uploaded file.
Parameters
Parameter | Required | Description |
---|---|---|
file_url String | Yes | The file URL to delete. |
Filters
Availability of filters functionality and the maximum number of saved filters are dependent
on the current user plan. These values are indicated by the filters
and max_filters
properties of the user plan limits object.
An example filter:
{
"id": "4638878",
"name": "Important",
"query": "priority 1",
"color": "lime_green",
"item_order": 3,
"is_deleted": false,
"is_favorite": false
}
Properties
Property | Description |
---|---|
id String | The ID of the filter. |
name String | The name of the filter. |
query String | The query to search for. Examples of searches can be found in the Todoist help page. |
color String | The color of the filter icon. Refer to the name column in the Colors guide for more info. |
item_order Integer | Filter’s order in the filter list (where the smallest value should place the filter at the top). |
is_deleted Boolean | Whether the filter is marked as deleted (a true or false value). |
is_favorite Boolean | Whether the filter is a favorite (a true or false value). |
Add a filter
Example add filter request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "filter_add",
"temp_id": "9204ca9f-e91c-436b-b408-ea02b3972686",
"uuid": "0b8690b8-59e6-4d5b-9c08-6b4f1e8e0eb8",
"args": {
"name": "Important",
"query": "priority 1"
}
}]'
Example response:
{
...
"sync_status": {"0b8690b8-59e6-4d5b-9c08-6b4f1e8e0eb8": "ok"},
"temp_id_mapping": {"9204ca9f-e91c-436b-b408-ea02b3972686": "4638878"},
...
}
Command arguments
Argument | Required | Description |
---|---|---|
name String | Yes | The name of the filter. |
query String | Yes | The query to search for. Examples of searches can be found in the Todoist help page. |
color String | No | The color of the filter icon. Refer to the name column in the Colors guide for more info. |
item_order Integer | No | Filter’s order in the filter list (the smallest value should place the filter at the top). |
is_favorite Boolean | No | Whether the filter is a favorite (a true or false value). |
Update a filter
Example update filter request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "filter_update",
"uuid": "a68b588a-44f7-434c-b3c5-a699949f755c",
"args": {
"id": "4638879",
"name": "Not Important"
"query": "priority 4"
}
}]'
Example response:
{
...
"sync_status": {"a68b588a-44f7-434c-b3c5-a699949f755c": "ok"},
...
}
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the filter. |
name String | No | The name of the filter |
query String | No | The query to search for. Examples of searches can be found in the Todoist help page. |
color String | No | The color of the filter icon. Refer to the name column in the Colors guide for more info. |
item_order Integer | No | Filter’s order in the filter list (where the smallest value should place the filter at the top). |
is_favorite Boolean | No | Whether the filter is a favorite (a true or false value). |
Delete a filter
Example delete filter request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[{"type": "filter_delete", "uuid": "b8186025-66d5-4eae-b0dd-befa541abbed", "args": {"id": "9"}}]'
Example response:
{
...
"sync_status": {"b8186025-66d5-4eae-b0dd-befa541abbed": "ok"},
...
}
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the filter. |
Update multiple filter orders
Example reorder filters request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands=[
{
"type": "filter_update_orders",
"uuid": "517560cc-f165-4ff6-947b-3adda8aef744",
"args": {
"id_order_mapping": {"4638878": 1, "4638879": 2}
}
}]'
Example response:
{
...
"sync_status": {"517560cc-f165-4ff6-947b-3adda8aef744": "ok"},
...
}
Update the orders of multiple filters at once.
Command arguments
Argument | Required | Description |
---|---|---|
id_order_mapping Object | Yes | A dictionary, where a filter ID is the key, and the order its value: filter_id: order . |
Reminders
An example reminder:
{
"id": "2992683215",
"notify_uid": "2671355",
"item_id": "2995104339",
"type": "absolute",
"due": {
"date": "2016-08-05T07:00:00.000000Z",
"timezone": null,
"is_recurring": false,
"string": "tomorrow at 10:00",
"lang": "en"
},
"minute_offset": 180,
"is_deleted": false
}
Availability of reminders functionality and the maximum number of stored reminders are dependent
on the current user plan. These values are indicated by the reminders
, max_reminders_time
and
max_reminders_location
properties of the user plan limits object.
Properties
Property | Description |
---|---|
id String | The ID of the reminder. |
notify_uid String | The user ID which should be notified of the reminder, typically the current user ID creating the reminder. |
item_id String | The item ID for which the reminder is about. |
type String | The type of the reminder: relative for a time-based reminder specified in minutes from now, absolute for a time-based reminder with a specific time and date in the future, and location for a location-based reminder. |
due Object | The due date of the reminder. See the Due dates section for more details. Note that reminders only support due dates with time, since full-day reminders don't make sense. |
minute_offset Integer | The relative time in minutes before the due date of the item, in which the reminder should be triggered. Note that the item should have a due date with time set in order to add a relative reminder. |
name String | An alias name for the location. |
loc_lat String | The location latitude. |
loc_long String | The location longitude. |
loc_trigger String | What should trigger the reminder: on_enter for entering the location, or on_leave for leaving the location. |
radius Integer | The radius around the location that is still considered as part of the location (in meters). |
is_deleted Boolean | Whether the reminder is marked as deleted (a true or false value). |
Add a reminder
Example of adding relative reminder:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "reminder_add",
"temp_id": "e24ad822-a0df-4b7d-840f-83a5424a484a",
"uuid": "41e59a76-3430-4e44-92b9-09d114be0d49",
"args": {
"item_id": "2995104339",
"minute_offset": 30,
"type": "relative"
}
}]'
Example response:
{
...
"sync_status": {"41e59a76-3430-4e44-92b9-09d114be0d49": "ok"},
"temp_id_mapping": {"e24ad822-a0df-4b7d-840f-83a5424a484a": "2992683215"},
...
}
Example of adding an absolute reminder:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "reminder_add",
"temp_id": "952a365e-4965-4113-b4f4-80cdfcada172u",
"uuid": "e7c8be2d-f484-4852-9422-a9984c58b1cd",
"args": {
"item_id": "2995104339",
"due": {
"date": "2014-10-15T11:00:00.000000Z"
},
"type": "absolute"
}
}]'
Example response:
{
...
"sync_status": {"e7c8be2d-f484-4852-9422-a9984c58b1cd": "ok"},
"temp_id_mapping": {"952a365e-4965-4113-b4f4-80cdfcada172": "2992683215"},
...
}
Example of adding a location reminder:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "reminder_add",
"temp_id": "7ad9609d-579f-4828-95c5-3600acdb2c81",
"uuid": "830cf409-daba-479c-a624-68eb0c07d01c",
"args": {
"item_id": "2995104339",
"type": "location",
"name": "Aliados",
"loc_lat": "41.148581",
"loc_long":"-8.610945000000015",
"loc_trigger":"on_enter",
"radius": 100
}
}]'
Example response:
{
...
"sync_status": {"830cf409-daba-479c-a624-68eb0c07d01c": "ok"},
"temp_id_mapping": {"7ad9609d-579f-4828-95c5-3600acdb2c81": "2992683215"},
...
}
Add a new reminder to the user account related to the API credentials.
Command arguments
Argument | Required | Description |
---|---|---|
item_id String | Yes | The item ID for which the reminder is about. |
type String | Yes | The type of the reminder: relative for a time-based reminder specified in minutes from now, absolute for a time-based reminder with a specific time and date in the future, and location for a location-based reminder. |
notify_uid String | No | The user ID which should be notified of the reminder, typically the current user ID creating the reminder. |
due Object | No | The due date of the reminder. See the Due dates section for more details. Note that reminders only support due dates with time, since full-day reminders don't make sense. |
minute_offset Integer | No | The relative time in minutes before the due date of the item, in which the reminder should be triggered. Note, that the item should have a due date with time set in order to add a relative reminder. |
name String | No | An alias name for the location. |
loc_lat String | No | The location latitude. |
loc_long String | No | The location longitude. |
loc_trigger String | No | What should trigger the reminder: on_enter for entering the location, or on_leave for leaving the location. |
radius Integer | No | The radius around the location that is still considered as part of the location (in meters). |
Update a reminder
Example update reminder request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "reminder_update",
"uuid": "b0e7562e-ea9f-4c84-87ee-9cbf9c103234",
"args": {
"id": "2992683215",
"due": {
"date": "2014-10-10T15:00:00.000000"
}
}
}]'
Example response:
{
...
"sync_status": {"b0e7562e-ea9f-4c84-87ee-9cbf9c103234": "ok"},
...
}
Update a reminder from the user account related to the API credentials.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the reminder. |
notify_uid String | No | The user ID which should be notified of the reminder, typically the current user ID creating the reminder. |
type String | No | The type of the reminder: relative for a time-based reminder specified in minutes from now, absolute for a time-based reminder with a specific time and date in the future, and location for a location-based reminder. |
due Object | No | The due date of the reminder. See the Due dates section for more details. Note that reminders only support due dates with time, since full-day reminders don't make sense. |
minute_offset Integer | No | The relative time in minutes before the due date of the item, in which the reminder should be triggered. Note, that the item should have a due date with time set in order to add a relative reminder. |
name String | No | An alias name for the location. |
loc_lat String | No | The location latitude. |
loc_long String | No | The location longitude. |
loc_trigger String | No | What should trigger the reminder: on_enter for entering the location, or on_leave for leaving the location. |
radius Integer | No | The radius around the location that is still considered as part of the location (in meters). |
Delete a reminder
Example delete reminder request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "reminder_delete",
"uuid": "0896d03b-eb90-49f7-9020-5ed3fd09df2d",
"args": {"id": "2992683215"}
}]'
Example response:
{
...
"sync_status": {"0896d03b-eb90-49f7-9020-5ed3fd09df2d": "ok"},
...
}
Delete a reminder from the current user account.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the filter. |
Locations
Locations are a top-level entity in the sync model. They contain a list of all locations that are used within user's current location reminders.
An example location object
[
"Shibuya-ku, Japan",
"35.6623001098633",
"139.706527709961"
]
Properties
The location object is specific, as it's not an object, but an ordered array.
Array index | Description |
---|---|
0 String | Name of the location. |
1 String | Location latitude. |
2 String | Location longitude. |
Clear locations
$ curl https://api.todoist.com/sync/v8/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[{"type": "clear_locations", "uuid": "d285ae02-80c6-477c-bfa9-45272d7bddfb", "args": {}}]'
{
...
"sync_status": {"d285ae02-80c6-477c-bfa9-45272d7bddfb": "ok"},
...
}
Clears the locations list, which is used for location reminders.
Due dates
Due dates for tasks and reminders is one of the core concepts of Todoist. It's very powerful and quite complex, because it has to embrace different use-cases of Todoist users.
Todoist supports three types of due dates.
- Full-day dates (like "1 January 2018" or "tomorrow")
- Floating due dates with time (like "1 January 2018 at 12:00" or "tomorrow at 10am")
- Due dates with time and fixed timezone (like "1 January 2018 at 12:00 America/Chicago" or "tomorrow at 10am Asia/Jakarta")
Unless specified explicitly, dates with time are created as floating.
In addition, any of these due dates can be set to recurring or not, depending on the date string, provided by the client.
Our Help Center contains an in-depth article about the difference between floating due dates and dates with fixed zones.
You can also find more information about recurring due dates in our Help Center.
Full-day dates
Example full-day date:
{
"date": "2016-12-01",
"timezone": null,
"string": "every day",
"lang": "en",
"is_recurring": true
}
Properties
Property | Description |
---|---|
date string | Due date in the format of YYYY-MM-DD (RFC 3339). For recurring dates, the date of the current iteration. |
timezone string | Always set to null . |
string string | Human-readable representation of due date. String always represents the due object in user's timezone. Look at our reference to see which formats are supported. |
lang string | Lang which has to be used to parse the content of the string attribute. Used by clients and on the server side to properly process due dates when date object is not set, and when dealing with recurring tasks. Valid languages are: en , da , pl , zh , ko , de , pt , ja , it , fr , sv , ru , es , nl , fi , nb , tw . |
is_recurring boolean | Boolean flag which is set to true if the due object represents a recurring due date. |
Floating due dates with time
Example floating due date with time:
{
"date": "2016-12-0T12:00:00.000000",
"timezone": null,
"string": "every day at 12",
"lang": "en",
"is_recurring": true
}
Property | Description |
---|---|
date string | Due date in the format of YYYY-MM-DDTHH:MM:SS . For recurring dates, the date of the current iteration. Due date always represent an event in current user's timezone. Note that it's not quite compatible with RFC 3339, because the concept of timezone is not applicable to this object. Also note that unlike fixed due dates, the date representation doesn't end with "Z". |
timezone string | Always set to null . |
string string | Human-readable representation of due date. String always represents the due object in user's timezone. Look at our reference to see which formats are supported. |
lang string | Lang which has to be used to parse the content of the string attribute. Used by clients and on the server side to properly process due dates when date object is not set, and when dealing with recurring tasks. Valid languages are: en , da , pl , zh , ko , de , pt , ja , it , fr , sv , ru , es , nl , fi , nb , tw . |
is_recurring boolean | Boolean flag which is set to true if the due object represents a recurring due date. |
Due dates with time and fixed timezone
Example due date with time and fixed timezone:
{
"date": "2016-12-06T13:00:00.000000Z",
"timezone": "Europe/Madrid",
"string": "ev day at 2pm",
"lang": "en",
"is_recurring": true
}
Properties
Property | Description |
---|---|
date string | Due date in the format of YYYY-MM-DDTHH:MM:SSZ (RFC 3339). For recurring dates, the date of the current iteration. Due date is stored in UTC. |
timezone string | Timezone of the due instance. Used to recalculate properly the next iteration for a recurring due date. |
string string | Human-readable representation of due date. String always represents the due object in user's timezone. Look at our reference to see which formats are supported. |
lang string | Lang which has to be used to parse the content of the string attribute. Used by clients and on the server side to properly process due dates when date object is not set, and when dealing with recurring tasks. Valid languages are: en , da , pl , zh , ko , de , pt , ja , it , fr , sv , ru , es , nl , fi , nb , tw . |
is_recurring boolean | Boolean flag which is set to true is due object represents a recurring due date |
Create or update due dates
Usually you create due dates when you create a new task or a reminder, or
you want to update a due date for an object. In both cases due date is provided
as a due
attribute of an object. You may provide all fields of an object in
the constructor, but it's more convenient to provide only a subset of the
fields and let the server fill the gaps.
Create or update due date from user-provided string
Input example
"due": {"string": "tomorrow"}
Output example. Full-date instance is created.
"due": {
"date": "2018-11-15",
"timezone": null,
"is_recurring": false,
"string": "tomorrow",
"lang": "en"
}
Input example
"due": {"string": "tomorrow at 12"}
Output example. Floating due date created
"due": {
"date": "2018-11-15T12:00:00.000000",
"timezone": null,
"is_recurring": false,
"string": "tomorrow at 12",
"lang": "en"
}
Input example. Timezone is set explicitly
"due": {"string": "tomorrow at 12", "timezone": "Asia/Jakarta"}
Output example. Due date with fixed timezone created
"due": {
"date": "2018-11-16T05:00:00.000000Z",
"timezone": "Asia/Jakarta",
"is_recurring": false,
"string": "tomorrow at 12",
"lang": "en"
}
You can ask the user to provide a due string and to create a new object from that.
You need to provide a timezone if you want to create a fixed due date instead
of a floating one. If you want to create a task without a due date, you
can set the due attribute to null
.
See the code section to the right for more examples. In all cases you can set
the lang
attribute of the date to set the language of the input. If the language
is not set, the language from user settings will be used.
Create or update due date from a date object
Input example for a full-day event
"due": {"date": "2018-10-14"}
For a full-day event the format of the date attribute is YYYY-MM-DD
.
Output example
"due": {
"date": "2018-10-14",
"timezone": null,
"is_recurring": false,
"string": "2018-10-14",
"lang": "en"
}
Input example for a floating due date
"due": {"date": "2018-10-14T10:00:00.000000"}
Output example
"due": {
"date": "2018-10-14T10:00:00.000000",
"timezone": null,
"is_recurring": false,
"string": "2018-10-14 10:00",
"lang": "en"
}
In some cases you have a date object and want to create a due date from it. Usually all you need to do is choose the format of the due date (floating or fixed) and format the time object properly with strftime or alternative for your programming language. The formatted string goes to a "date" attribute of the constructor.
Note that this approach does not allow you to create recurring due dates.
For a floating due date event the format of the date attribute is
YYYY-MM-DDTHH:MM:SS
and the date has to be provided in user's local
timezone.
Input example for a due date with a fixed timezone
"due": {"date": "2018-10-14T05:00:00.000000Z"}
Output example
"due": {
"date": "2018-10-14T05:00:00.000000Z",
"timezone": "Asia/Jakarta",
"is_recurring": false,
"string": "2018-10-14 12:00",
"lang": "en"
}
For a floating due date event the format of the date attribute is
YYYY-MM-DDTHH:MM:SSZ
(note the "Z" ending) and the date has to be provided
in UTC. Optionally you can provide a timezone name to overwrite the default
timezone of the user.
Deadlines
Similar to due dates, deadlines can be set on tasks, and can be used to differentiate between when a task should be started, and when it must be done by.
Unlike due dates, deadlines only support non-recurring dates with no time component.
You can find our more information about deadlines in our Help Center.
Example deadline object
{
"date": "2016-12-01"
}
Properties
Property | Description |
---|---|
date string | Deadline in the format of YYYY-MM-DD (RFC 3339). |
Create or update deadlines
Usually you create deadlines when you create a new task, or you want to update a
deadline for an object. In both cases due date is provided as a deadline
attribute of
an object.
Create or update deadline
Input example
"deadline": {"date": "2024-01-25"}
Output example
"deadline": {
"date": "2024-01-25"
}
User
An example user:
{
"auto_reminder": 0,
"avatar_big" : "https://*.cloudfront.net/*_big.jpg",
"avatar_medium" : "https://*.cloudfront.net/*_medium.jpg",
"avatar_s640" : "https://*.cloudfront.net/*_s640.jpg",
"avatar_small" : "https://*.cloudfront.net/*_small.jpg",
"business_account_id": "1",
"daily_goal": 15,
"date_format": 0,
"dateist_lang" : null,
"days_off": [6, 7],
"email": "me@example.com",
"feature_identifier": "2671355_0123456789abcdef70123456789abcdefe0123456789abcdefd0123456789abc",
"features": {
"beta": 1,
"dateist_inline_disabled" : false,
"dateist_lang" : null,
"gold_theme" : true,
"has_push_reminders": true,
"karma_disabled": false,
"karma_vacation": false,
"restriction": 3
},
"full_name": "Example User",
"has_password": true,
"id": "2671355",
"image_id": "d160009dfd52b991030d55227003450f",
"inbox_project_id": "220474322",
"is_biz_admin": false,
"is_premium": true,
"joined_at": "2015-07-31T18:32:06.000000Z",
"karma": 37504,
"karma_trend": "up",
"lang": "en",
"next_week": 1,
"premium_status": "current_personal_plan",
"premium_until": null,
"share_limit": 51,
"sort_order": 0,
"start_day": 1,
"start_page": "project?id=2203306141",
"team_inbox_id": "220474455",
"theme_id": "11",
"time_format": 0,
"token": "0123456789abcdef0123456789abcdef01234567",
"tz_info": {
"gmt_string": "-03:00",
"hours": -3,
"is_dst": 0,
"minutes": 0,
"timezone": "America/Sao_Paulo"
},
"verification_status": "legacy",
"weekend_start_day": 6,
"weekly_goal": 30
}
A Todoist user is represented by a JSON object. The dates will be in the UTC timezone. Typically, a user object will have the following properties:
Properties
Property | Description |
---|---|
auto_reminder Integer | The default time in minutes for the automatic reminders set, whenever a due date has been specified for a task. |
avatar_big String | The link to a 195x195 pixels image of the user's avatar. |
avatar_medium String | The link to a 60x60 pixels image of the user's avatar. |
avatar_s640 String | The link to a 640x640 pixels image of the user's avatar. |
avatar_small String | The link to a 35x35 pixels image of the user's avatar. |
business_account_id String | The ID of the user's business account. |
daily_goal Integer | The daily goal number of completed tasks for karma. |
date_format Integer | Whether to use the DD-MM-YYYY date format (if set to 0 ), or the MM-DD-YYYY format (if set to 1 ). |
dateist_lang String | The language expected for date recognition instead of the user's lang (null if the user's lang determines this), one of the following values: da , de , en , es , fi , fr , it , ja , ko , nl , pl , pt_BR , ru , sv , tr , zh_CN , zh_TW . |
days_off Array | Array of integers representing user's days off (between 1 and 7 , where 1 is Monday and 7 is Sunday ). |
email String | The user's email. |
feature_identifier String | An opaque id used internally to handle features for the user. |
features Object | Used internally for any special features that apply to the user. Current special features include whether the user has enabled beta , whether dateist_inline_disabled that is inline date parsing support is disabled, whether the dateist_lang is set which overrides the date parsing language, whether the gold_theme has been awarded to the user, whether the user has_push_reminders enabled, whether the user has karma_disabled , whether the user has karma_vacation mode enabled, and whether any special restriction applies to the user. |
full_name String | The user's real name formatted as Firstname Lastname . |
has_password Boolean | Whether the user has a password set on the account. It will be false if they have only authenticated without a password (e.g. using Google, Facebook, etc.) |
id String | The user's ID. |
image_id String | The ID of the user's avatar. |
inbox_project_id String | The ID of the user's Inbox project. |
is_biz_admin Boolean | Whether the user is a business account administrator (a true or false value). |
is_premium Boolean | Whether the user has a Todoist Pro subscription (a true or false value). |
joined_at String | The registration date of the user on Todoist (may be null for users from the early days). |
karma Integer | The user's karma score. |
karma_trend String | The user's karma trend (for example up ). |
lang String | The user's language, which can take one of the following values: da , de , en , es , fi , fr , it , ja , ko , nl , pl , pt_BR , ru , sv , tr , zh_CN , zh_TW . |
next_week Integer | The day of the next week, that tasks will be postponed to (between 1 and 7 , where 1 is Monday and 7 is Sunday ). |
premium_status String | Outlines why a user is premium, possible values are: not_premium , current_personal_plan , active_business_account or teams_business_member . |
premium_until String | The date when the user's Todoist Pro subscription ends (null if not a Todoist Pro user). This should be used for informational purposes only as this does not include the grace period upon expiration. As a result, avoid using this to determine whether someone has a Todoist Pro subscription and use is_premium instead. |
sort_order Integer | Whether to show projects in an oldest dates first order (if set to 0 , or a oldest dates last order (if set to 1 ). |
start_day Integer | The first day of the week (between 1 and 7 , where 1 is Monday and 7 is Sunday ). |
start_page String | The user's default view on Todoist. The start page can be one of the following: inbox , teaminbox , today , next7days , project?id=1234 to open a project, label?name=abc to open a label, or filter?id=1234 to open a filter. |
team_inbox_id String | The ID of the Team Inbox project. |
theme_id String | The currently selected Todoist theme (a number between 0 and 10 ). |
time_format Integer | Whether to use a 24h format such as 13:00 (if set to 0 ) when displaying time, or a 12h format such as 1:00pm (if set to 1 ). |
token String | The user's token that should be used to call the other API methods. |
tz_info Object | The user's timezone (a dictionary structure), which includes the following elements: the timezone as a string value, the hours and minutes difference from GMT, whether daylight saving time applies denoted by is_dst , and a string value of the time difference from GMT that is gmt_string . |
weekend_start_day Integer | The day used when a user chooses to schedule a task for the 'Weekend' (between 1 and 7, where 1 is Monday and 7 is Sunday). |
verification_status String | Describes if the user has verified their e-mail address or not. Possible values are: |
unverified
, for users that have just signed up. Those users cannot use any of Todoist's social features like sharing projects or accepting project invitations.verified
, for users that have verified themselves somehow. Clicking on the verification link inside the account confirmation e-mail is one such way alongside signing up through a social account.blocked
, for users that have failed to verify themselves in 7 days. Those users will have restricted usage of Todoist.legacy
, for users that have signed up before August, 2022 weekly_goal Integer | The target number of tasks to complete per week.
Update user's properties
Example update user request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "user_update",
"uuid": "52f83009-7e27-4b9f-9943-1c5e3d1e6889",
"args": {
"current_password": "fke4iorij",
"email": "mynewemail@example.com"
}
}]'
Example response:
{
...
"sync_status": {"52f83009-7e27-4b9f-9943-1c5e3d1e6889": "ok"},
...
}
Command arguments
Argument | Required | Description |
---|---|---|
current_password String | Yes (if modifying email or password ) |
The user's current password. This must be provided if the request is modifying the user's password or email address and the user already has a password set (indicated by has_password in the user object). For amending other properties this is not required. |
email String | No | The user's email. |
full_name String | No | The user's name. |
password String | No | The user's updated password. Must contain at least 8 characters and not be a common or easily guessed password. |
timezone String | No | The user's timezone (a string value such as UTC , Europe/Lisbon , US/Eastern , Asia/Taipei ). |
start_page String | No | The user's default view on Todoist. The start page can be one of the following: inbox , teaminbox , today , next7days , project?id=1234 to open a project, label?name=abc to open a label, or filter?id=1234 to open a filter. |
start_day Integer | No | The first day of the week (between 1 and 7 , where 1 is Monday and 7 is Sunday ). |
next_week Integer | No | The day of the next week, that tasks will be postponed to (between 1 and 7 , where 1 is Monday and 7 is Sunday ). |
time_format Integer | No | Whether to use a 24h format such as 13:00 (if set to 0 ) when displaying time, or a 12h format such as 1:00pm (if set to 1 ). |
date_format Integer | No | Whether to use the DD-MM-YYYY date format (if set to 0 ), or the MM-DD-YYYY format (if set to 1 ). |
sort_order Integer | No | Whether to show projects in an oldest dates first order (if set to 0 , or a oldest dates last order (if set to 1 ). |
auto_reminder Integer | No | The default time in minutes for the automatic reminders set, whenever a due date has been specified for a task. |
theme Integer | No | The currently selected Todoist theme (between 0 and 10 ). |
weekend_start_day Integer | No | The day used when a user chooses to schedule a task for the 'Weekend' (between 1 and 7, where 1 is Monday and 7 is Sunday). |
beta Boolean | No | Whether the user is included in the beta testing group. |
Error codes
Error Tag | Description |
---|---|
PASSWORD_REQUIRED |
The command attempted to modify password or email , but no value was provided for current_password . |
AUTHENTICATION_ERROR |
The value for current_password was incorrect. |
PASSWORD_TOO_SHORT |
The value for password was shorter than the minimum 8 characters. |
COMMON_PASSWORD |
The value for password was matched against a common password list and rejected. |
PASSWORD_CONTAINS_EMAIL |
The value for password was matched against the user's email address or a part of the address. |
INVALID_EMAIL |
The value for email was not a valid email address. |
Update karma goals
Example update karma goals request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "update_goals",
"uuid": "b9bbeaf8-9db6-452a-a843-a192f1542892",
"args": {"vacation_mode": 1}
}]'
Example response:
{
...
"sync_status": {"b9bbeaf8-9db6-452a-a843-a192f1542892": "ok"},
...
}
Update the karma goals of the user.
Command arguments
Argument | Required | Description |
---|---|---|
daily_goal Integer | No | The target number of tasks to complete per day. |
weekly_goal Integer | No | The target number of tasks to complete per week. |
ignore_days Integer | No | A list with the days of the week to ignore (1 for Monday and 7 for Sunday ). |
vacation_mode Integer | No | Marks the user as being on vacation (where 1 is true and 0 is false). |
karma_disabled Integer | No | Whether to disable the karma and goals measuring altogether (where 1 is true and 0 is false). |
Update notification settings
Example notification settings update request:
$ curl https://api.todoist.com/sync/v9/update_notification_setting \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d notification_type=item_completed \
-d service=email \
-d dont_notify=1
Example response:
{
"user_left_project": {
"notify_push": true,
"notify_email": true
},
"biz_trial_will_end": {
"notify_push": true,
"notify_email": true
},
"biz_trial_enter_cc": {
"notify_push": true,
"notify_email": true
},
"item_completed": {
"notify_push": true,
"notify_email": false
},
"share_invitation_rejected": {
"notify_push": true,
"notify_email": true
},
"note_added": {
"notify_push": true,
"notify_email": true
},
"biz_account_disabled": {
"notify_push": true,
"notify_email": true
},
"biz_invitation_rejected": {
"notify_push": true,
"notify_email": true
},
"item_uncompleted": {
"notify_push": true,
"notify_email": true
},
"item_assigned": {
"notify_push": true,
"notify_email": true
},
"share_invitation_accepted": {
"notify_push": true,
"notify_email": true
},
"user_removed_from_project": {
"notify_push": true,
"notify_email": true
},
"biz_invitation_accepted": {
"notify_push": true,
"notify_email": true
},
"biz_payment_failed": {
"notify_push": true,
"notify_email": true
}
}
Update the user's notification settings.
Parameters
Parameter | Required | Description |
---|---|---|
notification_type String | Yes | The notification type. For a list of notification types, see the Live Notifications section. |
service String | Yes | The service type, which can take the values: email or push . |
dont_notify Integer | Yes | Whether notifications of this service should be notified (1 to not notify, and 0 to notify). |
User plan limits
An example user plan limits sync response
{
"user_plan_limits": {
"current": {
"plan_name": "free",
...details of the current user plan
},
"next": {
"plan_name": "pro",
...details of a potential upgrade
}
}
}
The user_plan_limits
sync resource type describes the available features and limits applicable to the current
user plan. The user plan info object returned within the current
property shows the values
that are currently applied to the user.
If there is an upgrade available, the next
property will show the values that will apply if the user chooses
to upgrade. If there is no available upgrade, the next
value will be null.
Properties
Property | Description |
---|---|
current Object | A user plan info object representing the available functionality and limits for the user's current plan. |
next Object | A user plan info object representing the plan available for upgrade. If there is no available upgrade, this value will be null. |
User plan info
An example user plan info object
{
"plan_name": "free",
"activity_log": true,
"activity_log_limit": 7,
"automatic_backups": false,
"calendar_feeds": true,
"comments": true,
"completed_tasks": true,
"customization_color": false,
"email_forwarding": true,
"filters": true,
"labels": true,
"max_collaborators": 5,
"max_filters": 3,
"max_labels": 500,
"max_projects": 5,
"max_reminders_location": 300,
"max_reminders_time": 700,
"max_sections": 20,
"max_tasks": 300,
"reminders": false,
"templates": true,
"upload_limit_mb": 5,
"uploads": true,
"weekly_trends": true
}
The user plan info object describes the availability of features and any limitations applied for a given user plan.
Properties
Property | Description |
---|---|
plan_name String | The name of the plan. |
activity_log Boolean | Whether the user can view the activity log. |
activity_log_limit Integer | The number of days of history that will be displayed within the activity log. If there is no limit, the value will be -1 . |
automatic_backups Boolean | Whether backups will be automatically created for the user's account and available for download. |
calendar_feeds Boolean | Whether calendar feeds can be enabled for the user's projects. |
comments Boolean | Whether the user can add comments. |
completed_tasks Boolean | Whether the user can search in the completed tasks archive or access the completed tasks overview. |
customization_color Boolean | Whether the user can use special themes or other visual customization such as custom app icons. |
email_forwarding Boolean | Whether the user can add tasks or comments via email. |
filters Boolean | Whether the user can add and update filters. |
max_filters Integer | The maximum number of filters a user can have. |
labels Boolean | Whether the user can add labels. |
max_labels Integer | The maximum number of labels a user can have. |
reminders Boolean | Whether the user can add reminders. |
max_reminders_location Integer | The maximum number of location reminders a user can have. |
max_reminders_time Integer | The maximum number of time-based reminders a user can have. |
templates Boolean | Whether the user can import and export project templates. |
uploads Boolean | Whether the user can upload attachments. |
upload_limit_mb Integer | The maximum size of an individual file the user can upload. |
weekly_trends Boolean | Whether the user can view productivity stats. |
max_projects Integer | The maximum number of active projects a user can have. |
max_sections Integer | The maximum number of active sections a user can have. |
max_tasks Integer | The maximum number of active tasks a user can have. |
max_collaborators Integer | The maximum number of collaborators a user can add to a project. |
User settings
Example user settings object:
{
"reminder_push": true,
"reminder_desktop": true,
"reminder_email": true,
"completed_sound_desktop": true,
"completed_sound_mobile": true
}
Availability of reminders functionality is dependent on the current user plan.
This value is indicated by the reminders
property of the user plan limits object.
These settings will have no effect if the user is not eligible for reminders.
Properties
Property | Description |
---|---|
reminder_push Boolean | Set to true to send reminders as push notifications. |
reminder_desktop Boolean | Set to true to show reminders in desktop applications. |
reminder_email Boolean | Set to true to send reminders by email. |
completed_sound_desktop Boolean | Set to true to enable sound when a task is completed in Todoist desktop clients. |
completed_sound_mobile Boolean | Set to true to enable sound when a task is completed in Todoist mobile clients. |
Update user settings
Example update user settings request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "user_settings_update",
"temp_id": "e24ad822-a0df-4b7d-840f-83a5424a484a",
"uuid": "41e59a76-3430-4e44-92b9-09d114be0d49",
"args": {"reminder_desktop": false}
}]'
Example response:
{
...
"sync_status": {"41e59a76-3430-4e44-92b9-09d114be0d49": "ok"},
...
}
Update one or more user settings.
Command arguments
Argument | Required | Description |
---|---|---|
reminder_push Boolean | No | Set to true to send reminders as push notifications. |
reminder_desktop Boolean | No | Set to true to show reminders in desktop applications. |
reminder_email Boolean | No | Set to true to send reminders by email. |
completed_sound_desktop Boolean | No | Set to true to enable sound when a task is completed in Todoist desktop clients. |
completed_sound_mobile Boolean | No | Set to true to enable sound when a task is completed in Todoist mobile clients. |
Get productivity stats
Example get productivity stats request:
$ curl https://api.todoist.com/sync/v9/completed/get_stats \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567"
Example response:
{
"karma_last_update": 50,
"karma_trend": "up",
"days_items": [
{
"date": "2014-11-03",
"items": [
{
"completed": 7,
"id": "2203306141"
},
{
"completed": 5,
"id": "2203306142"
}
],
"total_completed": 0 },
],
"completed_count": 0,
"karma_update_reasons": [
{ "positive_karma_reasons": [4],
"new_karma": 50,
"negative_karma": 0,
"positive_karma": 50,
"negative_karma_reasons": [],
"time": "Mon 20 Oct 2014 12:06:52"}
],
"karma": 50,
"week_items": [
{
"date": "2014-11-03\/2014-11-09",
"items": [
{
"completed": 7,
"id": "2203306141"
},
{
"completed": 5,
"id": "2203306142"
}
],
"total_completed": 0 },
],
"project_colors": {
"2203306141": "red",
"2203306142": "lime"
},
"goals": {
"karma_disabled": 0,
"user_id": "4",
"max_weekly_streak": {
"count": 0,
"start": "",
"end": ""
},
"ignore_days": [6, 7],
"vacation_mode": 0,
"current_weekly_streak": {
"count": 0,
"start": "",
"end": ""
},
"current_daily_streak": {
"count": 0,
"start": "",
"end": ""
},
"weekly_goal": 25,
"max_daily_streak": {
"count": 0,
"start": "",
"end": ""
},
"daily_goal": 5
}
}
Get the user's productivity stats.
Properties
Property | Description |
---|---|
karma_last_update Float | The karma delta on the last update. |
karma_trend String | Karma trend. Possible values: up or down . |
days_items Object | Items completed in the last 7 days. The objects inside items are composed by an id (project_id ) and the number of completed tasks for it. |
completed_count Integer | Total completed tasks count. |
karma_update_reasons | Log of the last karma updates. positive_karma_reasons and negative_karma_reasons are Integer numbers regarding the action done to generate them. Please refer to the Positive and negative karma reasons below. |
karma Float | Karma score. |
week_items Object | Items completed in the last 4 weeks. The objects inside items are composed by an id (project_id ) and the number of completed tasks for it. |
project_colors Object | Projects color mapping |
goals Object | Goals definition. The same settings and stats shown in the interface. |
Positive and negative karma reasons
Number | Description |
---|---|
1 | You added tasks. |
2 | You completed tasks. |
3 | Usage of advanced features. |
4 | You are using Todoist. Thanks! |
5 | Signed up for Todoist Beta! |
6 | Used Todoist Support section! |
7 | For using Todoist Pro - thanks for supporting us! |
8 | Getting Started Guide task completed! |
9 | Daily Goal reached! |
10 | Weekly Goal reached! |
50 | You have tasks that are over x days overdue'. |
52 | Inactive for a longer period of time'. |
Items and sections archive
To reduce the size and complexity of sync requests, completed items and archived sections are not returned by the sync endpoint.
The sync endpoint returns a completed_info
resource type. This is a list of entries for any active objects that contain
archived entities. The /archive/sections
and
/archive/items
endpoints can then be used to retrieve these archived objects.
Completed info
An example sync response containing completed info:
{
...
"completed_info": [
{
"project_id": "2203306141",
"completed_items": 12,
"archived_sections": 2
},
{
"section_id": "7025",
"completed_items": 12
},
{
"item_id": "2995104339",
"completed_items": 12
}
],
"sync_token": "DukN8fI9dOoGT5G_Eu01iQZAFOLvw0p_OwVe2Ww0ILuv77NMbdAWm5RYHhzp",
...
}
The completed_info
list returned by the sync endpoint contains an entry for any active project,
section or item containing completed items. Project entries will also contain a value indicating the
number of archived sections.
Project completed info
An example project completed info object:
{
"project_id": "2203306141",
"completed_items": 12,
"archived_sections": 2
}
The project completed info object represents the number of completed items at the root of a project (children of these completed root items are not included in the count).
The object also indicates the number of archived sections within the project.
Properties
Property | Description |
---|---|
project_id String | The ID of the project containing the completed items or archived sections. |
completed_items Integer | The number of completed items within the project. |
archived_sections Integer | The number of archived sections within the project. |
Section completed info
An example section completed info object:
{
"section_id": "7025",
"completed_items": 12
}
The section completed info object represents the number of completed items at the root of a section (children of these completed root items are not included in the count).
Properties
Property | Description |
---|---|
section_id String | The ID of the section containing the completed items. |
completed_items Integer | The number of completed items within the section. |
Item completed info
An example item completed info object:
{
"item_id": "2995104339",
"completed_items": 12
}
The item completed info object represents the number of completed child items at the root of an item (children of these completed root items are not included in the count).
Properties
Property | Description |
---|---|
item_id String | The ID of the item containing the completed child items. |
completed_items Integer | The number of completed child items within the item. |
Get archived sections
Example get archived sections request:
$ curl https://api.todoist.com/sync/v9/archive/sections?project_id=2203306141 \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567"
Example response:
{
"sections": [
{
"id": "7025",
"name": "Groceries",
"project_id": "2203306141",
"section_order": 1,
"collapsed": false,
"user_id": "2671355",
"sync_id": null,
"is_deleted": false,
"is_archived": true,
"added_at": "2021-03-15T14:53:41.000000Z",
"archived_at": "2021-03-19T14:53:48.000000Z",
}
...
],
"completed_info": [
{
"section_id": "7025",
"completed_items": 12
}
],
"total": 22,
"next_cursor": "k85gVI5ZAs8AAAABFoOzAQ",
"has_more": true
}
Retrieves a list of archived sections within a project. By default, the response is limited to a page
containing a maximum of 20 sections (configurable using the limit
parameter).
Subsequent pages of results can be fetched by using the next_cursor
value from the response as
the cursor
value for the next request.
When there are no further results to display, the value of has_more
in the response will be false.
Parameters
Parameter | Required | Description |
---|---|---|
project_id String | Yes | ID of the parent project. |
last_seen_id String | No | If provided, only sections archived earlier than current one, will be. |
limit Integer | No | The maximum number of sections to return in the page (20 by default, no more than 100). |
cursor String | No | A string value used to request a specific page within the full list of results. The cursor for the next page of results will be returned as a next_cursor attribute in the response. |
Return values
Property | Description |
---|---|
sections Array of Objects | A list of archived sections within the project. |
total Integer | The total number of archived sections within the project. |
completed_info Array of Objects | A list of section completed info objects for any sections that contain completed items. |
has_more Boolean | A value indicating whether there are further pages of results to display. |
next_cursor String | A string that can be passed as the cursor value for a subsequent request to move to the next page. This value is not returned if has_more is false . |
Get completed items
Example get completed items request:
$ curl https://api.todoist.com/sync/v9/archive/items?project_id=2203306141 \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567"
Example response:
{
"items": [
{
"id": "2995104339",
"user_id": "2671355",
"project_id": "2203306141",
"content": "Buy Milk",
"description": "",
"priority": 1,
"due": null,
"deadline": null,
"parent_id": null,
"child_order": 1,
"section_id": null,
"day_order": -1,
"collapsed": false,
"labels": ["Food", "Shopping"],
"added_by_uid": "2671355",
"assigned_by_uid": "2671355",
"responsible_uid": null,
"checked": true,
"is_deleted": false,
"sync_id": null,
"added_at": "2018-09-26T08:25:05.000000Z",
"completed_at": "2021-03-19T11:43:21.000000Z"
}
...
],
"completed_info": [
{
"item_id": "2995104339",
"completed_items": 12
}
],
"total": 22,
"next_cursor": "k85gVI5ZAs8AAAABFoOzAQ",
"has_more": true
}
Retrieves a list of completed items within a project, section, or parent item. By default, the response is limited
to a page containing a maximum of 20 items (configurable using the limit
parameter).
Subsequent pages of results can be fetched by using the next_cursor
value from the response as
the cursor
value for the next request.
When there are no further results to display, the value of has_more
in the response will be false.
Note that one of the project_id
, section_id
, or task_id
parameters is required.
Parameters
Parameter | Required | Description |
---|---|---|
project_id String | Yes (or section_id , item_id ) |
ID of the parent project. |
section_id String | Yes (or project_id , item_id ) |
ID of the parent section. |
item_id String | Yes (or project_id , section_id ) |
ID of the parent item. |
last_seen_id String | No | If provided, only items archived earlier than current one, will be. |
limit Integer | No | The maximum number of items to return in the page (20 by default, no more than 100). |
cursor String | No | A string value used to request a specific page within the full list of results. The cursor for the next page of results will be returned as a next_cursor attribute in the response. |
Return values
Property | Description |
---|---|
items Array of Objects | A list of completed items within the project, section, or parent item. |
total Integer | The total number of completed items within the project, section, or parent item. |
completed_info Array of Objects | A list of item completed info objects for any items that contain completed items. |
has_more Boolean | A value indicating whether there are further pages of results to display. |
next_cursor String | A string that can be passed as the cursor value for a subsequent request to move to the next page. This value is not returned if has_more is false . |
Get completed items with a list of parent ids
Example get completed items with a list of parent ids:
$ curl https://api.todoist.com/sync/v9/archive/items_many?parent_ids=["1","2"] \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567"
Example response:
{
"1": {
"items": [
{
"id": "2995104339",
"user_id": "2671355",
"project_id": "2203306141",
"content": "Buy Milk",
"description": "",
"priority": 1,
"due": null,
"deadline": null,
"parent_id": null,
"child_order": 1,
"section_id": null,
"day_order": -1,
"collapsed": false,
"labels": ["Food", "Shopping"],
"added_by_uid": "2671355",
"assigned_by_uid": "2671355",
"responsible_uid": null,
"checked": true,
"is_deleted": false,
"sync_id": null,
"added_at": "2018-09-26T08:25:05.000000Z",
"completed_at": "2021-03-19T11:43:21.000000Z"
}
...
],
"completed_info": [
{
"item_id": "2995104339",
"completed_items": 12
}
],
"total": 22,
"next_cursor": "k85gVI5ZAs8AAAABFoOzAQ",
"has_more": true
},
"2": ...
}
Retrieves an object that maps from parent id to completed items within a parent item. By default, the response is limited
to a page containing a maximum of 20 items (configurable using the limit
parameter).
Note that the result of each parent id is the same as Get completed items. e.g., you can use a cursor
to fetch more data.
Parameters
Parameter | Required | Description |
---|---|---|
parent_ids Array of String | Yes | IDs of parent items (should be JSON encoded). |
limit Integer | No | The maximum number of items to return for each parent (20 by default, no more than 100). |
Return values
An object that maps from a parent id to an object with the following properties:
Property | Description |
---|---|
items Array of Objects | A list of completed items within the project, section, or parent item. |
total Integer | The total number of completed items within the project, section, or parent item. |
completed_info Array of Objects | A list of item completed info objects for any items that contain completed items. |
has_more Boolean | A value indicating whether there are further pages of results to display. |
next_cursor String | A string that can be passed as the cursor value for a subsequent request to move to the next page. This value is not returned if has_more is false . |
Sharing
Projects can be shared with other users, which are then referred to as collaborators. This section describes the different commands that are related to sharing.
Collaborators
An example collaborator object:
{
"id": "2671362",
"email": "you@example.com",
"full_name": "Example User",
"timezone": "GMT +3:00",
"image_id": null
}
There are two types of objects to get information about a user’s collaborators,
and their participation in shared projects: collaborators
and
collaborator_states
Every user who shares at least one project with another user, has a collaborators record in the API response. The record contains a restricted subset of user-specific properties.
Property | Description |
---|---|
id String | The user ID of the collaborator. |
email String | The email of the collaborator. |
full_name String | The full name of the collaborator. |
timezone String | The timezone of the collaborator. |
image_id String | The image ID for the collaborator's avatar, which can be used to get an avatar from a specific URL. Specifically the https://dcff1xvirvpfp.cloudfront.net/<image_id>_big.jpg can be used for a big (195x195 pixels) avatar, https://dcff1xvirvpfp.cloudfront.net/<image_id>_medium.jpg for a medium (60x60 pixels) avatar, and https://dcff1xvirvpfp.cloudfront.net/<image_id>_small.jpg for a small (35x35 pixels) avatar. |
Partial sync returns updated collaborator objects for users that have changed their attributes, such as their name or email.
Collaborator states
An example collaborator state:
{
"project_id": "2203306141",
"user_id": "2671362",
"state": "active",
"is_deleted": false
}
The list of collaborators doesn’t contain any information on how users are
connected to shared projects. To provide information about these connections,
the collaborator_states
field should be used. Every collaborator state record
is a mere "user to shared project" mapping.
Property | Description |
---|---|
project_id String | The shared project ID of the user. |
user_id String | The user ID of the collaborator. |
state String | The status of the collaborator state, either active or invited . |
is_deleted Boolean | Set to true when the collaborator leaves the shared project. |
Share a project
Example share project request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "share_project",
"temp_id": "854be9cd-965f-4ddd-a07e-6a1d4a6e6f7a",
"uuid": "fe6637e3-03ce-4236-a202-8b28de2c8372",
"args": {
"project_id": "2203306141",
"email": "you@example.com"
}
}]'
Example response:
{
...
"sync_status": {"fe6637e3-03ce-4236-a202-8b28de2c8372": "ok"},
...
}
Share a project with another user.
Command arguments
Argument | Required | Description |
---|---|---|
project_id String | Yes | The project to be shared. |
email String | Yes | The user email with whom to share the project. |
Delete a collaborator
Example delete collaborator request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "delete_collaborator",
"uuid": "0ae55ac0-3b8d-4835-b7c3-59ba30e73ae4",
"args": {
"project_id": "2203306141",
"email": "you@example.com"
}
}]'
Example response:
{
...
"sync_status": {"0ae55ac0-3b8d-4835-b7c3-59ba30e73ae4": "ok"},
...
}
Remove a user from a shared project.
Command arguments
Argument | Required | Description |
---|---|---|
project_id String | Yes | The project to be affected. |
email String | Yes | The user email with whom the project was shared. |
Accept an invitation
Example accept invitation request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "accept_invitation",
"uuid": "4b254da4-fa2b-4a88-9439-b27903a90f7f",
"args": {
"invitation_id": "1234",
"invitation_secret": "abcdefghijklmno"
}
}]'
Example response:
{
...
"sync_status": {"4b254da4-fa2b-4a88-9439-b27903a90f7f": "ok"},
...
}
Accept an invitation to join a shared project.
Command arguments
Argument | Required | Description |
---|---|---|
invitation_id String | Yes | The invitation ID. |
invitation_secret String | Yes | The secret fetched from the live notification. |
Reject an invitation
Example reject invitation request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "reject_invitation",
"uuid": "284fd900-c36f-44e5-ab92-ee93455e50e0",
"args": {
"invitation_id": "1234",
"invitation_secret": "abcdefghijklmno"
}
}]'
Example response:
{
...
"sync_status": {"284fd900-c36f-44e5-ab92-ee93455e50e0": "ok"},
...
}
Reject an invitation to join a shared project.
Command arguments
Argument | Required | Description |
---|---|---|
invitation_id String | Yes | The invitation ID. |
invitation_secret String | Yes | The secret fetched from the live notification. |
Delete an invitation
Example delete invitation request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "delete_invitation",
"uuid": "399f6a8d-ddea-4146-ae8e-b41fb8ff6945",
"args": {"invitation_id": "1234"}
}]'
Example response:
{
...
"sync_status": {"399f6a8d-ddea-4146-ae8e-b41fb8ff6945": "ok"},
...
}
Delete an invitation to join a shared project.
Command arguments
Argument | Required | Description |
---|---|---|
invitation_id String | Yes | The invitation to be deleted. |
Live notifications
Examples of live notifications:
{
"created_at": "2021-05-10T09:59:36.000000Z",
"is_unread": false,
"from_uid": "2671362",
"id": "1",
"invitation_id": "456",
"invitation_secret": "abcdefghijklmno",
"notification_key": "notification_123",
"notification_type": "share_invitation_sent",
"seq_no": 12345567890,
"state": "accepted"
}
{
"created_at": "2021-05-10T09:59:36.000000Z",
"is_unread": false,
"from_uid": "2671362",
"id": "2",
"invitation_id": "456",
"notification_key": "notification_123",
"notification_type": "share_invitation_accepted",
"project_id": "2203306141",
"seq_no": 1234567890
}
{
"created_at": "2021-05-10T09:59:36.000000Z",
"is_unread": false,
"from_uid": "2671362",
"id": "3",
"invitation_id": "456",
"notification_key": "notification_123",
"notification_type": "share_invitation_rejected",
"project_id": "2203306141",
"reject_email": "me@example.com",
"seq_no": 1234567890
}
{
"created_at": "2021-05-10T09:59:36.000000Z",
"is_unread": false,
"from_uid": "2671362",
"id": "4",
"notification_key": "notification_123",
"notification_type": "user_left_project",
"project_id": "2203306141",
"seq_no": 1234567890
}
{
"created_at": "2021-05-10T09:59:36.000000Z",
"is_unread": false,
"from_uid": "2671362",
"id": "5",
"notification_key": "notification_123",
"notification_type": "user_removed_from_project",
"project_id": "2203306141",
"removed_name": "Example User",
"removed_uid": "2671366",
"seq_no": 1234567890
}
{
"assigned_by_uid": "2671362",
"created_at": "2021-05-10T09:59:36.000000Z",
"is_unread": false,
"from_uid": "2671362",
"id": "6",
"item_content": "NewTask",
"item_id": "2995104339",
"notification_key": "notification_123",
"notification_type": "item_assigned",
"project_id": "2203306141",
"responsible_uid": "2671355",
"seq_no": 1234567890
}
{
"assigned_by_uid": "2671362",
"created_at": "2021-05-10T09:59:36.000000Z",
"is_unread": false,
"from_uid": "2671362",
"id": "7",
"item_content": "NewTask",
"item_id": "2995104339",
"notification_key": "notification_123",
"notification_type": "item_completed",
"project_id": "2203306141",
"responsible_uid": "2671355",
"seq_no": 1234567890
}
{
"assigned_by_uid": "2671362",
"created_at": "2021-05-10T09:59:36.000000Z",
"is_unread": false,
"from_uid": "2671362",
"id": "8",
"item_id": "456",
"item_content": "NewTask",
"notification_key": "notification_123",
"notification_type": "item_uncompleted",
"project_id": "2203306141",
"responsible_uid": "321",
"seq_no": 1234567890
}
{
"created_at": "2021-05-10T09:59:36.000000Z",
"is_unread": false,
"from_uid": "2671362",
"id": "9",
"item_id": "2995104339",
"note_content": "NewTask",
"note_id": "2992679862",
"notification_key": "notification_123",
"notification_type": "note_added",
"project_id": "2203306141",
"seq_no": 1234567890
}
{
"created_at": "2021-05-10T09:59:36.000000Z",
"is_unread": false,
"email": "me@example.com",
"from_uid": "2671362",
"id": "10",
"notification_key": "notification_123",
"notification_type": "biz_policy_disallowed_invitation",
"project_id": "2203306141",
"seq_no": 1234567890,
"from_user": {
"email": "you@example.com",
"full_name": "Example User",
"id": "2671362",
"image_id": "321"
}
}
{
"created_at": "2021-05-10T09:59:36.000000Z",
"is_unread": false,
"from_uid": "2671362",
"id": "11",
"inviter_id": "456",
"notification_key": "notification_123",
"notification_type": "biz_policy_rejected_invitation",
"seq_no": 1234567890,
"from_user": {
"email": "you@example.com",
"full_name": "Example User",
"id": "2671362",
"image_id": "321"
}
}
{
"active_until": 1399299727,
"created_at": "2021-05-10T09:59:36.000000Z",
"is_unread": false,
"from_uid": "2671362",
"id": "12",
"notification_key": "notification_123",
"notification_type": "biz_trial_will_end",
"plan": "business_monthly",
"quantity": 10,
"seq_no": 1234567890
}
{
"active_until": 1399299727,
"amount_due": 600,
"attempt_count": 1,
"created_at": "2021-05-10T09:59:36.000000Z",
"is_unread": false,
"currency": "usd",
"description": "2 x Subscription to Monthly ($3.00/month)",
"from_uid": "2671362",
"id": "13",
"next_payment_attempt": 1399299735,
"notification_key": "notification_123",
"notification_type": "biz_payment_failed",
"plan": "business_monthly",
"quantity": 10,
"seq_no": 1234567890
}
{
"active_until": 1399299727,
"created_at": "2021-05-10T09:59:36.000000Z",
"is_unread": false,
"from_uid": "2671362",
"id": "14",
"notification_key": "notification_123",
"notification_type": "biz_account_disabled",
"plan": "business_monthly",
"quantity": 10,
"seq_no": 1234567890
}
{
"account_name": "Example Inc.",
"created_at": "2021-05-10T09:59:36.000000Z",
"is_unread": false,
"from_uid": "2671362",
"from_user": {
"email": "you@example.com",
"full_name": "Example User",
"id": "2671362",
"image_id": "789"
},
"id": "15",
"invitation_id": "321",
"invitation_message": "Welcome to our team!",
"invitation_secret": "abcdefghijklmno",
"notification_key": "notification_123",
"notification_type": "biz_invitation_created",
"seq_no": 1234567890,
"state": "accepted"
}
{
"created_at": "2021-05-10T09:59:36.000000Z",
"is_unread": false,
"from_uid": "2671362",
"from_user": {
"account_name": "Example Inc.",
"email": "you@example.com",
"full_name": "Example User",
"id": "2671362",
"image_id": "789"
},
"id": "16",
"invitation_id": "321",
"notification_key": "notification_123",
"notification_type": "biz_invitation_accepted",
"seq_no": 1234567890
}
{
"created_at": "2021-05-10T09:59:36.000000Z",
"is_unread": false,
"from_uid": "2671362",
"from_user": {
"account_name": "Example Inc.",
"email": "you@example.com",
"full_name": "Example User",
"id": "2671362",
"image_id": "789"
},
"id": "17",
"invitation_id": "321",
"notification_key": "notification_123",
"notification_type": "biz_invitation_rejected",
"seq_no": 1234567890
}
{
"created_at": "2021-05-10T09:59:36.000000Z",
"is_unread": false,
"from_uid": "2671362",
"count": 5,
"goal": 5,
"id": "18",
"notification_key": "notification_123",
"notification_type": "daily_goal_reached",
"seq_no": 1234567890
}
{
"created_at": "2021-05-10T09:59:36.000000Z",
"is_unread": false,
"from_uid": "2671362",
"count": 50,
"goal": 50,
"id": "19",
"notification_key": "notification_123",
"notification_type": "weekly_goal_reached",
"seq_no": 1234567890
}
Types
This is the list of notifications which can be issued by the system:
Type | Description |
---|---|
share_invitation_sent | Sent to the sharing invitation receiver. |
share_invitation_accepted | Sent to the sharing invitation sender, when the receiver accepts the invitation. |
share_invitation_rejected | Sent to the sharing invitation sender, when the receiver rejects the invitation. |
user_left_project | Sent to everyone when somebody leaves the project. |
user_removed_from_project | Sent to everyone, when a person removes somebody from the project. |
item_assigned | Sent to user who is responsible for the task. Optionally it's also sent to the user who created the task initially, if the assigner and the task creator is not the same person. |
item_completed | Sent to the user who assigned the task when the task is completed. Optionally it's also sent to the user who is responsible for this task, if the responsible user and the user who completed the task is not the same person. |
item_uncompleted | Sent to the user who assigned the task when the task is uncompleted. Optionally it's also sent to the user who is responsible for this task, if the responsible user and the user who completed the task is not the same person. |
note_added | Sent to all members of the shared project, whenever someone adds a note to the task. |
biz_policy_disallowed_invitation | Sent to you when you try to share a project with someone outside of your business account, but the business account policy disallows this action. |
biz_policy_rejected_invitation | Sent to you when you try to accept the invitation to a shared project from someone outside of your business account, but the business account policy disallows this action. |
biz_trial_will_end | Sent to all business account administrators three days before the trial period of a subscription is scheduled to end. |
biz_payment_failed | Sent to all business account administrators whenever an invoice attempt payment fails. This can occur either due to a declined payment, or because the customer has no active card. A particular case of note is that if a customer with no active card reaches the end of its free trial. |
biz_account_disabled | Sent to all business account administrators when the account is disabled. |
biz_invitation_created | Sent to an invitee, when one of business account administrators invites this user to the business account. |
biz_invitation_accepted | Sent to an inviter, when the invitation is accepted. |
biz_invitation_rejected | Sent to an inviter, when the invitation is rejected. |
daily_goal_reached | Sent to user when they reach their daily goal. |
weekly_goal_reached | Sent to user when they reach their weekly goal. |
Common properties
Some properties are common for all types of notifications, whereas some others depend on the notification type.
Every live notification has the following properties:
Property | Description |
---|---|
id String | The ID of the live notification. |
created_at String | Live notification creation date. |
from_uid String | The ID of the user who initiated this live notification. |
notification_key String | Unique notification key. |
notification_type String | Type of notification. Different notification type define different extra fields which are described below. |
seq_no Integer | Notification sequence number. |
is_unread Boolean | Whether the notification is marked as unread (a true or false value). |
Specific properties
Here are the extra properties for the *_invitation_*
types of live
notifications:
Property | Description |
---|---|
from_user Object | User data, useful on share_invitation_sent . |
project_name String | The project name, useful for share_invitation_* where you may not have the project in the local model. |
invitation_id String | The invitation ID. Useful for accepting/rejecting invitations. |
invitation_secret String | The invitation secret key. Useful for accepting/rejecting invitations. |
Here are the extra properties for the share_invitation_sent
type of live notifications:
Property | Description |
---|---|
state String | Invitation state. Initially invited , can change the state to accepted or rejected . |
Here are the extra properties for the user_removed_from_project
type of live notifications:
Property | Description |
---|---|
removed_name String | The name of the user removed. |
removed_uid String | The uid of the user removed. |
Here are the extra properties for the biz_trial_will_end
type of live notifications:
Property | Description |
---|---|
quantity Integer | The number of users under the control of the business account. |
plan String | Tariff plan name. Valid values are business_monthly and business_yearly . |
active_until Integer | The timestamp when the business account will be disabled. The value may not match the business account subscription end date, as we give some extra days (up to two weeks) to pay the invoice. |
Here are the extra properties for the biz_payment_failed
type of live notifications:
Property | Description |
---|---|
quantity Integer | The number of users under the control of the business account. |
plan String | Tariff plan name. Valid values are business_monthly and business_yearly . |
active_until Integer | The timestamp when the business account will be disabled. The value may not match the business account subscription end date, as we give some extra days (up to two weeks) to pay the invoice. |
amount_due Integer | Invoice amount. Integer value in 0.01 of currency. |
attempt_count Integer | Number of automatic payment attempts made for this invoice. |
currency String | Currency value. Three-letter ISO currency code representing the currency in which the charge was made. |
description String | Invoice description. |
next_payment_attempt String | Timestamp value. |
Here are the extra properties for the biz_account_disabled
type of live notifications:
Property | Description |
---|---|
quantity Integer | The number of users under the control of the business account. |
plan String | Tariff plan name. Valid values are business_monthly and business_yearly . |
active_until Integer | The timestamp when the business account will be disabled. The value may not match the business account subscription end date, as we give some extra days (up to two weeks) to pay the invoice. |
Here are the extra properties for the biz_invitation_created
type of live
notifications:
Property | Description |
---|---|
state String | Invitation state. Initially invited , can change the state to accepted or rejected . |
invitation_secret String | Invitation secret. Should be used to accept or reject invitation. |
invitation_message String | Invitation message. |
account_name String | Business account (company) name. |
Set last known
Example set last known notification request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "live_notifications_set_last_read",
"uuid": "588b9ccf-29c0-4837-8bbc-fc858c0c6df8",
"args": {"id": "1234"}
}]'
Example response:
{
...
"sync_status": {"588b9ccf-29c0-4837-8bbc-fc858c0c6df8": "ok"},
...
}
Set the last known notification.
Command arguments
Argument | Required | Description |
---|---|---|
id String | Yes | The ID of the last known notification (a number or 0 or null to mark all read). |
Mark as read
Example mark notification read request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "live_notifications_mark_read",
"uuid": "588b9ccf-29c0-4837-8bbc-fc858c0c6df8",
"args": {"ids": ["1234"]}
}]'
Example response:
{
...
"sync_status": {"588b9ccf-29c0-4837-8bbc-fc858c0c6df8": "ok"},
...
}
Mark the notifications as read.
Command arguments
Argument | Required | Description |
---|---|---|
ids Array of String | Yes | The IDs of the notifications. |
Mark all as read
Example mark all notifications read request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "live_notifications_mark_read_all",
"uuid": "588b9ccf-29c0-4837-8bbc-fc858c0c6df8"
}]'
Example response:
{
...
"sync_status": {"588b9ccf-29c0-4837-8bbc-fc858c0c6df8": "ok"},
...
}
Mark all notifications as read.
Mark as unread
Example mark notification unread request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "live_notifications_mark_unread",
"uuid": "588b9ccf-29c0-4837-8bbc-fc858c0c6df8",
"args": {"ids": ["1234"]}
}]'
Example response:
{
...
"sync_status": {"588b9ccf-29c0-4837-8bbc-fc858c0c6df8": "ok"},
...
}
Mark the notifications as unread.
Command arguments
Argument | Required | Description |
---|---|---|
ids Array of String | Yes | The IDs of the notifications. |
Activity
Availability of the activity log and the duration of event storage are dependent
on the current user plan. These values are indicated by the activity_log
and activity_log_limit
properties of the user plan limits object.
The activity log makes it easy to see everything that is happening across projects, items and notes.
Logged events
Currently the official Todoist clients present only the most important events that most users may be interested in. There are further types of events related to projects, items and notes that are stored in our database, and can be accessed through the API.
The following events are logged for items:
- Items added
- Items updated (only changes to
content
,description
,due_date
andresponsible_uid
) - Items deleted
- Items completed
- Items uncompleted
The following events are logged for notes:
- Notes added
- Notes updated (only changes to
content
orfile_name
if the former is empty) - Notes deleted
The following events are logged for projects:
- Projects added
- Projects updated (only changes to
name
) - Projects deleted
- Projects archived
- Projects unarchived
- Projects shared
- Projects left
Event properties
An example of an activity log event:
{
"id" : "955333384",
"object_type" : "item",
"object_id" : "2995104339",
"event_type" : "added",
"event_date" : "2016-07-01T14:24:59.000000Z",
"parent_project_id" : "2203306141",
"parent_item_id" : null,
"initiator_id" : null,
"extra_data" : {
"content" : "Buy Milk",
"client" : "Mozilla/5.0; Todoist/830"
}
}
Property | Description |
---|---|
id String | The ID of the event. |
object_type String | The type of object, one of item , note or project . |
object_id String | The ID of the object. |
event_type String | The type of event, one of added , updated , deleted , completed , uncompleted , archived , unarchived , shared , left . |
event_date String | The date and time when the event took place. |
parent_project_id String | The ID of the item's or note's parent project, otherwise null . |
parent_item_id string | The ID of the note's parent item, otherwise null . |
initiator_id String | The ID of the user who is responsible for the event, which only makes sense in shared projects, items and notes, and is null for non-shared objects. |
extra_data Object | This object contains at least the name of the project, or the content of an item or note, and optionally the last_name if a project was renamed, the last_content if an item or note was renamed, the due_date and last_due_date if an item's due date changed, the responsible_uid and last_responsible_uid if an item's responsible uid changed, the description and last_description if an item's description changed, and the client that caused the logging of the event. |
Get activity logs
Example get activity logs request:
$ curl https://api.todoist.com/sync/v9/activity/get \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567"
Example response:
{
"events": [
{
"id" : "955344370",
"object_type" : "item",
"object_id" : "2995104339",
"event_type" : "updated",
"event_date" : "2016-07-01T14:28:37.000000Z",
"parent_project_id" : "2203306141",
"parent_item_id" : null,
"initiator_id" : null,
"extra_data" : {
"last_due_date" : null,
"due_date" : "2016-07-02T20:59:59.000000Z",
"content" : "Buy Milk",
"client" : "Mozilla/5.0; Todoist/830"
}
},
{
"id" : "955333751",
"object_type" : "note",
"object_id" : "2992679862",
"event_type" : "added",
"event_date" : "2016-07-01T14:25:04.000000Z",
"parent_project_id" : "2203306141",
"parent_item_id" : "2995104339",
"initiator_id" : null,
"extra_data" : {
"content" : "Remember this!",
"client": "Todoist/11.2.1"
}
},
{
"id" : "955333239",
"object_type" : "project",
"object_id" : "2203306141",
"event_type" : "added",
"event_date" : "2016-07-01T14:24:56.000000Z",
"parent_project_id" : null,
"parent_item_id" : null,
"initiator_id" : null,
"extra_data" : {
"name" : "Shopping List",
"client": "TodoistForWindows10"
}
}
],
"count": 3
}
Gets activity log events.
Properties
Parameter | Required | Description |
---|---|---|
object_type String | No | Filters events by a specific object type. |
object_id String | No | Filters events by a specific object ID, but only if the object_type has been also specified. |
event_type String | No | Filters events by a specific event type. |
object_event_types Array of Strings | No | An alternative way to filter by multiple object and event types. This takes a list of strings of the form [object_type]:[event_type] (where either object_type part or the event_type part can be omitted), such as for example ["item:", "note:added"] . When this parameter is specified the object_type , event_type and object_id parameters are ignored. |
parent_project_id String | No | Filters object events by the ID of the project they belong to, so this implicitly limits the results to items and notes. |
parent_item_id String | No | Filters object events by the ID of the item they belong, so this implicitly limits the results to notes. |
initiator_id String | No | Filters event by the ID of the initiator. |
page Integer | No | By default, if a page number is not specified, events from the current and last week are returned. The page number is used to iterate over the list of events. Events are split in pages, where currently each page corresponds to a single week. Page 0 denotes events of the current week, page 1 events of the previous week, page 2 events for 2 weeks ago, and so on. See the Pagination details section below for more info. |
limit Integer | No | The number of events to return, where the default is 30 , and the maximum is 100 . See the Pagination details section below for more info. |
offset Integer | No | The number of events to skip, which can be used for pagination in order to get more events than those returned by the previous call. See the Pagination details section below for more info. |
Return value
Value | Description |
---|---|
events Array of Objects | The activity log events. |
count Integer | The total count of events with the specified parameters, irregardless of the limit and offset parameters. |
Pagination details
There are 3 parameters that control which events are returned from the activity log. These parameters should be used in combination to get all the events one is interested in.
The page
parameter
The events in the activity log are organized by week. Each week starts at Sunday 12:00:00
(PM or noon), and ends the next Sunday at 11:59:59
, This means that one can target a specific week, and get events from that week. The page
parameter specifies from which week to fetch events, and it does so in a way that is relative to the current time.
This will be more easy to understand with the following example. Assuming it's now Wednesday, February 23
, then:
page=0
: Denotes events from the current week, that is fromSunday, February 20
, to just nowpage=1
: Denotes events from last week, fromFebruary 13
, toFebruary 20
page=2
: Denotes events from 2 weeks ago, fromFebruary 6
, toFebruary 13
page=3
: Denotes events from 3 weeks ago, fromJanuary 30
, toFebruary 6
And so on.
If the page
parameter is not specified, then events from the current and last week are returned. This is equivalent to getting events for page=0
and page=1
together. So omitting the page
parameter, and depending on which day of the week the call is made, this should return events from 7
to 14
days ago. This is useful in order to always fetch at least a week's events, even on Mondays.
In the above example, this would return events from Sunday, February 13
to Wednesday, February 23
, so around 10
days.
The limit
and offset
parameters
Each week can have a lot of events. This is where the limit
and offset
parameters come into play. Because it's not resource friendly to get hundreds of events in one call, the events returned are limited by the default value of the limit
parameter, as defined above in the Properties section. This limit can be increased, but up to a maximum value, again defined in the Properties section.
Since not all of the events of a specific week, can be returned in a single call, a subsequent call should use the offset
parameter, in order to skip the events already received.
As an example, assuming that the current week (ie. page=0
) has 78
events, and that a limit=50
is used in order to get up to 50
events in each call, one would need to do 2 calls:
- A request with parameters
page=0
,limit=50
, andoffset=0
, will return50
events and also thecount=78
value - Since the return value
count=78
is larger thanlimit=50
, an additional call is needed with the parameterspage=0
,limit=50
, andoffset=50
, which will return the rest of the28
events
If last week had 234
events, and assuming a limit=100
was used:
- A request with
page=1
,limit=100
andoffset=0
, will return100
events, andcount=234
- A second request with
page=1
,limit=100
andoffset=100
, will return additional100
events - A third request with
page=1
,limit=100
andoffset=200
, will return the remaining34
events
View Options
An example view option object:
{
"view_type": "project",
"object_id": "6Jf8VQXxpwv56VQ7",
"filtered_by": "!assigned",
"grouped_by": "priority",
"sorted_by": "added_date",
"sort_order": "asc",
"show_completed_tasks": false,
"view_mode": "calendar",
"calendar_settings": {"layout": "month"},
"is_deleted": false,
"deadline": "no deadline"
}
Properties
Property | Description |
---|---|
view_type Enum | The type of a view customization. today for the today view, upcoming for the upcoming view, project for a project, label for a label, or filter for a filter. |
object_id String | The ID of the object referred to by view_type , when view_type is project , label , or filter . |
filtered_by String | A search query for this view customization. Examples of searches can be found in the Todoist help page. |
grouped_by Enum | Grouping criteria for this view customization. One of assignee , added_date , due_date , deadline , label , priority , project , or workspace . |
sorted_by Enum | Sorting criteria for this view customization. One of alphabetically , assignee , added_date , due_date , deadline , label , priority , project , workspace , or manual . |
sort_order Enum | Sorting order for this view customization. asc for ascending, desc for descending. |
show_completed_tasks Boolean | Whether completed tasks should be shown automatically in this view customization. |
view_mode Enum | The mode in which to render tasks in this view customization. One of list , board , or calendar . Note: This setting is ignored in projects, where project.view_style is used instead. |
calendar_settings JSON | The settings for the calendar when view_mode is set to calendar . Currently, only {"layout": "week"} and {"layout": "month"} are supported. |
deadline String | A search query for this view customization. Examples of deadline searches can be found in the Todoist help page. |
is_deleted Boolean | Whether the view option is marked as deleted. |
Note: view_options.view_mode
is secondary to project.view_style
for projects in Todoist clients. The former is set per user, while the latter is set per project.
Set a view option
Argument | Required | Description |
---|---|---|
view_type Enum | Yes | Type of the view customization to be set. today for the today view, upcoming for the upcoming view, project for a project, label for a label, or filter for a filter. |
object_id String | Yes | ID of the object referred to by view_type , required when view_type is project , label , or filter . |
filtered_by String | No | Search query. Examples of searches can be found in the Todoist help page. |
grouped_by Enum | No | Grouping criteria. One of assignee , added_date , due_date , deadline , label , priority , project , or workspace . |
sorted_by Enum | No | Sorting criteria. One of alphabetically , assignee , added_date , due_date , deadline , label , priority , project , workspace , or manual . |
sort_order Enum | No | Sorting order. asc for ascending, desc for descending. |
show_completed_tasks Boolean | No | Whether completed tasks should be shown automatically in this view customization. |
view_mode Enum | No | The mode in which to render tasks. One of list , board , or calendar . |
deadline String | A search query for this view customization. Examples of deadline searches can be found in the Todoist help page. | |
calendar_settings JSON | No | The settings for the calendar when view_mode is set to calendar . Currently, only {"layout": "week"} and {"layout": "month"} are supported. |
Example set view option request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "view_options_set",
"uuid": "997d4b43-55f1-48a9-9e66-de5785dfd696",
"args": {
"view_type": "project",
"object_id": "6Jf8VQXxpwv56VQ7",
"view_mode": "board",
"grouped_by": "assignee"
}
}]'
Example response:
{
...
"sync_status": {"997d4b43-55f1-48a9-9e66-de5785dfd696": "ok"},
...
}
Delete view option
Argument | Required | Description |
---|---|---|
view_type Enum | Yes | Type of the view customization to delete. today for the today view, upcoming for the upcoming view, project for a project, label for a label, or filter for a filter. |
object_id String | Yes | ID of the object referred to by view_type , required when view_type is project , label , or filter . |
Example delete view option request:
$ curl https://api.todoist.com/sync/v9/sync \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d commands='[
{
"type": "view_options_delete",
"uuid": "f8539c77-7fd7-4846-afad-3b201f0be8a6",
"args": {
"view_type": "today"
}
}]'
Example response:
{
...
"sync_status": {"f8539c77-7fd7-4846-afad-3b201f0be8a6": "ok"},
...
}
Backups
Availability of backups functionality is dependent on the current user plan.
This value is indicated by the automatic_backups
property of the
user plan limits object.
Get backups
Example get user backups request:
$ curl https://api.todoist.com/sync/v9/backups/get \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567"
Example response:
[
{
"version": "2018-07-13 02:03",
"url": "https://api.todoist.com/sync/v9/backups/download?file=12345678901234567890123456789012.zip"
},
...
]
Todoist creates a backup archive of users' data on a daily
basis. Backup archives can also be accessed from the web app (Todoist
Settings
-> Backups
).
A successful response will return HTTP 200 OK
status, and a list of backup
archives in JSON format.
Please note that you will need a token with scopes data:read_write
and data:delete
.
Get special backups
In specific circumstances, the Todoist team may create special backups for some users. These backups have a different retention period, and may only be partial backups of the user's account.
The list of special backups can be read from the /sync/v9/backups/get_special
endpoint. The response format is the same as for regular backups, with an optional context
field containing a machine-readable reason why the backup was created.
Download the backup
Example downloading backup request:
$ curl -L -H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
https://api.todoist.com/sync/v9/backups/download?file=12345678901234567890123456789012.zip > /tmp/todoist-backup.zip
Get backups will retrieve a list of downloadable files for the user related to the token being used. To download one of the files returned, you have to use the token as a header.
Emails
Get or create an email address
Example create email address request:
$ curl https://api.todoist.com/sync/v9/emails/get_or_create \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d obj_type=project \
-d obj_id=2203306141
Example response:
{
"email": "Inbox <add.task.1855589.128501411.9a3ae36588cf36df@todoist.net>"
}
Creates a new email address for an object, or gets an existing email.
Parameters
Parameter | Required | Description |
---|---|---|
obj_type String | Yes | The object's type, one of project , project_comments or item . |
obj_id String | Yes | The object's ID. |
Disable an email address
Example disable email address request:
$ curl https://api.todoist.com/sync/v9/emails/disable \
-H "Authorization: Bearer 0123456789abcdef0123456789abcdef01234567" \
-d obj_type=project \
-d obj_id=2203306141
On success, HTTP 200 status is returned
Disables an email address for an object.
Parameters
Parameter | Required | Description |
---|---|---|
obj_type String | Yes | The object's type, one of project , project_comments or item . |
obj_id String | Yes | The object's ID. |
Webhooks
The Todoist Webhooks API allows applications to receive real-time notification (in the form of HTTP POST payload) on the subscribed user events. Notice that once you have a webhook setup, you will start receiving webhook events from all your app users immediately.
Important Considerations
Due to the nature of network requests, your application should assume webhook requests could arrive out of order or could even fail to arrive; webhooks should be used only as notifications and not as a primary Todoist data source (make sure your application could still work when webhook is not available).
Webhook Activation & Personal Use
The webhook for a specific user is activated when that user completes the OAuth flow of the app that declares the webhook.
Todoist webhooks don't fire by default for the user that has created the Todoist app, which is frequently the desired state for the personal use of webhooks.
To activate webhooks for personal use, you need to complete the OAuth process with your account. You can do this without code by manually executing the OAuth flow in two steps.
- Performing the authorization request in the browser and capturing the
code
via the browser's developer tools. - Performing the token exchange request through a tool like Postman and reading the
access_token
from the response. Note that you can't make this request via the browser as it needs to be a POST request.
Configuration
Before you can start receiving webhook event notifications, you must first have your webhook configured at the App Management Console.
Events
Here is a list of events that you could subscribe to, and they are configured at the App Management Console.
Event Name | Description | Event Data |
---|---|---|
item:added | An item was added | The new Item. |
item:updated | An item was updated | The updated Item. |
item:deleted | An item was deleted | The deleted Item. |
item:completed | An item was completed | The completed Item. |
item:uncompleted | An item was uncompleted | The uncompleted Item. |
note:added | A note was added | The new Note. |
note:updated | A note was updated | The updated Note. |
note:deleted | A note was deleted | The deleted Note. |
project:added | A project was added | The new Project. |
project:updated | A project was updated | The updated Project. |
project:deleted | A project was deleted | The deleted Project. |
project:archived | A project was archived | The archived Project. |
project:unarchived | A project was unarchived | The unarchived Project. |
section:added | A section was added | The new Section. |
section:updated | A section was updated | The updated Section. |
section:deleted | A section was deleted | The deleted Section. |
section:archived | A section was archived | The archived Section. |
section:unarchived | A section was unarchived | The unarchived Section. |
label:added | A label was added | The new Label. |
label:deleted | A label was deleted | The deleted Label. |
label:updated | A label was updated | The updated Label. |
filter:added | A filter was added | The new Filter. |
filter:deleted | A filter was deleted | The deleted Filter. |
filter:updated | A filter was updated | The updated Filter. |
reminder:fired | A reminder has fired | The Reminder that fired. |
Events Extra
Some events can include extra meta information in the event_data_extra
field. These can be useful, for example, if you need to distinguish between item updates that are postponed and initiated by the user and item updates that are task completions (initiated by completing a recurring task)
Event Name | Description | Event Data |
---|---|---|
item:updated | For events issued by the user directly these include old_item and update_intent |
old_item will be an Item, and update_intent can be item_updated , item_completed , item_uncompleted . |
Request Format
Event JSON Object
Example Webhook Request
POST /payload HTTP/1.1
Host: your_callback_url_host
Content-Type: application/json
X-Todoist-Hmac-SHA256: UEEq9si3Vf9yRSrLthbpazbb69kP9+CZQ7fXmVyjhPs=
{
"event_name": "item:added",
"user_id": "2671355",
"event_data": {
"added_by_uid": "2671355",
"assigned_by_uid": null,
"checked": false,
"child_order": 3,
"collapsed": false,
"content": "Buy Milk",
"description": "",
"added_at": "2021-02-10T10:33:38.000000Z",
"completed_at": null,
"due": null,
"deadline": null,
"id": "2995104339",
"is_deleted": false,
"labels": [],
"parent_id": null,
"priority": 1,
"project_id": "2203306141",
"responsible_uid": null,
"section_id": null,
"sync_id": null,
"url": "https://todoist.com/showTask?id=2995104339",
"user_id": "2671355"
},
"initiator": {
"email": "alice@example.com",
"full_name": "Alice",
"id": "2671355",
"image_id": "ad38375bdb094286af59f1eab36d8f20",
"is_premium": true
},
"triggered_at": "2021-02-10T10:39:38.000000Z",
"version": "9"
}
Each webhook event notification request contains a JSON object. The event JSON contains the following properties:
Property | Description |
---|---|
event_name String | The event name for the webhook, see the table in the Configuration section for the list of supported events. |
user_id String | The ID of the user that is the destination for the event. |
event_data Object | An object representing the modified entity that triggered the event, see the table in the Configuration section for details of the event_data for each event. |
version String | The version number of the webhook configured in the App Management Console. |
initiator Object | A Collaborator object representing the user that triggered the event. This may be the same user indicated in user_id or a collaborator from a shared project. |
triggered_at String | The date and time when the event was triggered. |
event_data_extra Object | Optional object that can include meta information, see the table in the Configuration section for details of the event_data_extra for each event. |
Request Header
Header Name | Description |
---|---|
User-Agent | Will be set to "Todoist-Webhooks" |
X-Todoist-Hmac-SHA256 | To verify each webhook request was indeed sent by Todoist, an X-Todoist-Hmac-SHA256 header is included; it is a SHA256 Hmac generated using your client_secret as the encryption key and the whole request payload as the message to be encrypted. The resulting Hmac would be encoded in a base64 string. |
X-Todoist-Delivery-ID | Each webhook event notification has a unique X-Todoist-Delivery-ID . When a notification request failed to be delivered to your endpoint, the request would be re-delivered with the same X-Todoist-Delivery-ID . |
Failed Delivery
When an event notification fails to be delivered to your webhook callback URL (i.e. due to server / network error, incorrect response, etc), it will be reattempted after 15 minutes. Each notification will be reattempted for at most three times.
Your callback endpoint must respond with an HTTP 200 when receiving an event notification request.
A response other than HTTP 200 will be considered as a failed delivery, and the notification will be attempted again.
Request Limits
Payload Size
There is a 1MiB HTTP request body limit on POST requests.
The maximum payload size for an attachment upload is dependent on the current user plan.
This value is indicated by the upload_limit_mb
property of the user plan limits object.
Header Size
Total size of HTTP headers cannot exceed 65 KiB.
Processing Timeouts
There are processing timeouts associated with each endpoint, and these vary depending on the type of action being performed.
Type | Limit |
---|---|
Uploads | 5 minutes |
Standard Request | 15 seconds |
Rate Limiting
Limits are applied differently for full and partial syncs. You should ideally only make a full sync on your initial request and then subsequently perform incremental syncs as this is faster and more efficient.
See the sync section for further information on incremental sync.
For each user, you can make a maximum of 1000 partial sync requests within a 15 minute period.
For each user, you can make a maximum of 100 full sync requests within a 15 minute period.
You can reduce the number of requests you make by batching up to 100 commands in each request and it will still count as one. See the Batching Commands section for further information.
Maximum Sync Commands
The maximum number of commands is 100 per request. This restriction is applied to prevent timeouts and other problems when dealing with large requests.
Migrating from v8
Version 9 of the Sync API builds upon version 8 (deprecated in Dec 2022) with a number of modifications, here we'll list the changes and provide some information on migrating to the latest version.
General
- All datetime strings returned by the API have microsecond precision
(
2021-01-01T12:00:00.123456Z
). Any sync commands or endpoints that have a datetime parameter accepts the value with or without the microseconds present (2021-01-01T12:00:00.123456Z
or2021-01-01T12:00:00Z
). - All ids are now strings, instead of numbers. Some of them may still contain only numbers, but it's not guaranteed it will continue to be that way. All string ids must be treated as opaque byte sequences.
Items
- Labels on items now appear as a list of label names. Commands for adding and updating items are amended to take an array of label names instead of IDs.
- The
id
attribute is now a string (was previously a number). - The
user_id
attribute is now a string (was previously a number). - The
section_id
attribute is now a string (was previously a number). - The
project_id
attribute is now a string (was previously a number). - The
parent_id
attribute is now a string (was previously a number). - The
added_by_uid
attribute is now a string (was previously a number). - The
assigned_by_uid
attribute is now a string (was previously a number). - The
responsible_uid
attribute is now a string (was previously a number). - The
in_history
attribute has been deprecated. An item can no longer be archived without being completed. Thechecked
attribute should be used instead. - The
item_archive
anditem_unarchive
sync commands have been deprecated. Child items are now automatically archived when their parents are modified using theitem_complete
command. To restore a child item and its parents from the archive, use theitem_uncomplete
command. - The
force_history
parameter of theitem_complete
sync command has been deprecated. Child items are now completed and moved to the archive with their parent item. - The
date_added
attribute has been renamed toadded_at
. - The
date_completed
attribute has been renamed tocompleted_at
. - The
checked
attribute is now a boolean value (was previously a0
or1
integer). - The
collapsed
attribute is now a boolean value (was previously a0
or1
integer). - The
is_deleted
attribute is now a boolean value (was previously a0
or1
integer).
Projects
- Projects have a new property
view_style
. This value determines whether the Todoist clients display the project as a list or board. This value can be set with theproject_add
orproject_update
commands. - The
id
attribute is now a string (was previously a number). - The
parent_id
attribute is now a string (was previously a number). - The
sync_id
attribute is now a string (was previously a number). - The
color
attribute is now a string representing the name of the color instead of a numeric ID. See the colors guide for details of the possible values. - The
collapsed
attribute is now a boolean value (was previously a0
or1
integer). - The
is_archived
attribute is now a boolean value (was previously a0
or1
integer). - The
is_deleted
attribute is now a boolean value (was previously a0
or1
integer). - The
is_favorite
attribute is now a boolean value (was previously a0
or1
integer).
Sections
- The
id
attribute is now a string (was previously a number). - The
project_id
attribute is now a string (was previously a number). - The
user_id
attribute is now a string (was previously a number). - The
sync_id
attribute is now a string (was previously a number). - The
date_added
attribute has been renamed toadded_at
. - The
date_archived
attribute has been renamed toarchived_at
.
Labels
- We introduced a new concept of 'shared labels' to Todoist. These are labels that are not saved to a user's account but have been created by collaborators and appear on tasks. See the labels section for details of the differences between personal and shared labels.
- New commands
label_rename
andlabel_delete_occurrences
were added to assist with management of shared labels. - The
id
attribute is now a string (was previously a number). - The
delete_label
command has a new optional parameter,cascade
. This determines whether instances of a label should be removed when a personal label is deleted. - The
color
attribute is now a string representing the name of the color instead of a numeric ID. See the colors guide for details of the possible values. - The
is_deleted
attribute is now a boolean value (was previously a0
or1
integer). - The
is_favorite
attribute is now a boolean value (was previously a0
or1
integer).
Filters
- The
id
attribute is now a string (was previously a number). - The
color
attribute is now a string representing the name of the color instead of a numeric ID. See the colors guide for details of the possible values. - The
is_deleted
attribute is now a boolean value (was previously a0
or1
integer). - The
is_favorite
attribute is now a boolean value (was previously a0
or1
integer).
Archived items and sections
- Completed items, archived sections, and their associated reminders and notes no longer appear in full or partial sync responses.
- A new
completed_info
resource type is returned by the sync endpoint, which indicates how many completed items or archived sections are present within an active project, item or section. - A new endpoint
/archive/items
has been added to allow retrieval of completed items. - A new endpoint
/archive/sections
has been added to allow retrieval of archived sections. - Full details of interacting with the archive can be found in the Items and sections archive section.
Notes
- The
id
attribute is now a string (was previously a number). - The
project_id
attribute is now a string (was previously a number). - The
posted_uid
attribute is now a string (was previously a number). - The
item_id
attribute is now a string (was previously a number). - The
project_id
is no longer returned for item notes. It is only returned when the note is attached to a project. - The
is_deleted
attribute is now a boolean value (was previously a0
or1
integer). - The
posted
attribute has been renamed toposted_at
. - The
reactions
attribute is now a list of strings (was previously a list of numbers). - The
uids_to_notify
attribute is now a list of strings (was previously a list of numbers).
User
- The format of the
start_page
value for a user has changed. The start page can be one of the following:inbox
,teaminbox
,today
,next7days
,project?id=1234
to open a project,label?name=abc
to open a label, orfilter?id=1234
to open a filter. - The
business_account_id
attribute is now a string (was previously a number). - The
join_date
attribute has been renamed tojoined_at
. - The
inbox_project
attribute has been renamed toinbox_project_id
and its content is now a string. - The
team_inbox
attribute has been renamed toteam_inbox_id
and its content is now a string. - The
theme
attribute has been renamed totheme_id
. - A new property
has_password
is added to the user object. If the user has only used a 3rd party auth provider (Google, Facebook, Apple) to register and login this value is now be false until they set a password. - A
current_password
parameter has been added to theuser_update
sync command. This is mandatory if the command is changing the user's email address or password and the userhas_password
value istrue
. - A new property
weekend_start_day
is added to the user object. This value is used by the Todoist clients when a user chooses to schedule a task for theWeekend
. Theuser_update
command can be used to change this value. - The
default_reminder
,mobile_number
andmobile_host
attributes have been removed from the user object. These values related to SMS reminder functionality that has been deprecated.
Live Notifications
- Fields changed in their respective objects are also reflected here (e.g.
project_id
,item_id
,responsible_uid
, etc.) - The
id
attribute is now a string (was previously a number). - The
ids
attribute is now a list of strings (was previously a list of numbers). - The
from_uid
attribute is now a string (was previously a number). - The
created
attribute has been renamed tocreated_at
- The
is_unread
attribute is now a boolean value (was previously a0
or1
integer).
Reminders
- The
service
attribute have been removed. - The
id
attribute is now a string (was previously a number). - The
item_id
attribute is now a string (was previously a number). - The
notify_uid
attribute is now a string (was previously a number).