Introduction

Welcome to the official Todoist API documentation! The Todoist API can be used to hook Todoist with other applications, as it makes it easy for your client to retrieve and sync your data.

The Todoist API is based on REST, so you can use it with a tool like cURL, but language bindings also exist for Python, so it is easier and faster to write your own scripts or applications interacting with Todoist.

The source code of this API documentation is also available.

Libraries

At the moment there are language bindings for Python, but we are planning on creating client libraries for other languages and platforms in the future.

Python

You can install the Todoist Python library from PyPI with:

$ pip install todoist-python

The language bindings for Python come in the form of the Todoist Python API library.

A PyPI package has been also prepared in order to easily install the Todoist Python library in your system.

There is more detailed documentation speficically for the Todoist Python API library, and this API reference documentation can be also read online.

Overview

The Todoist API is based on syncing data from and to the server, so almost all interactions with the Todoist server can be done with a single call: sync. This can be used to get the full model (projects, items, etc.), and then update it, or perform changes to it.

Then there are a few more auxiliary calls that can perform some actions that are not related to the full model, but are nonetheless useful.

Available calls

Call Description
sync Retrieves or sends data.
login Logins to the server using the user’s password.
login_with_google Logins to the server using OAuth2.
upload_file Uploads a file.
query Query after date, priority or labels.
register Registers a new account.
delete_user Deletes an existing account.
get_redirect_link Gets the redirect link.
get_productivity_stats Gets the productivity stats.
update_notification_settings Updates the notification settings.
get_all_completed_items Gets the user’s completed tasks.
add_item Adds a new item.

Changes

The Todoist API is currently in version 6, and it replaces the older Standard API and Sync API, both of which were considered as version 5.

The old APIs

Both the Standard API and the Sync API are considered deprecated since the release of the current Todoist API, which means that we are recommending everyone to migrate their clients to use our new API. For the time being, the old APIs will still be available, and while there is no plan to put an end to them anytime soon, it must be noted that we will not be extending them either.

The Standard and Sync API reference documentation will still be available, but from a different location than before, as the old URLs are now redirecting to the present documentation.

The new API

The new Todoist API is actually based on the old Sync API, but it was further simplified, while at the same time a lot of effort went into improving different aspects of it.

Some very few calls from the old Standard API are now part of the new Todoist API, and they are basically those that provide some needed functionality that is unrelated to the user’s data and objects.

Another addition is the OAuth support, which means that applications can now use the OAuth2 protocol to obtain a user authorized API access token.

Here follows a list of the most major changes from the old Sync API:

  • The get, sync and syncAndGetUpdated API calls, were combined into one call, that is called sync, and which can be used to fetch and send data.
  • All the sync call commands are sending back to client return values, including the bulk commands that operate on multiple items at once.
  • A new error reporting subsystem was added, and now each error in one of the API calls or any of the commands of the sync call, is reported back as a JSON object, and it includes details on what went wrong and why.
  • A new input validation mechanism was implemented, and missing arguments or invalid input values are reported back as JSON errors.
  • Special care has been taken to improve the consistency of each the sync call commands with each other, for a more unified experience.
  • UUIDs are now the default way for specifying temporary IDs and timestamps for each sync call and its commands, which makes it easier for clients to overcome the problem of uniqueness between requests and objects.
  • And while it is not visible, the new API had also had its internals reworked in many places, something important in order to make it faster and less error-prone to introduce new functionality.

A more detailed list of minor changes are included here, because they might be useful to those migrating from the old Sync API:

  • The sync call items_to_sync argument has been renamed to commands.
  • The sync call resource_types argument is now required, and also by default no data are returned, unless some resources have been specified with this argument.
  • The sync call has a new required argument, the seq_no_global, which should be defined in the same way as the seq_no argument.
  • The sync call include_notification_settings argument has been removed, and instead the notification_settings resource should be included in the resource_types argument.
  • The sync call resource_types argument has a new resource called user that includes the accounts’s details in the returned data.
  • The sync call resource_types argument has a new resource called all that makes it possible to fetch all types of objects, ie. all the user data.
  • The timestamp parameter of the sync call commands argument has been replaced by the uuid parameter which accepts UUIDs.
  • The temp_id parameter of the sync call commands argument is now accepting UUIDs.
  • The SyncStatus list is included in the extra data returned by the sync call, in addition to the TempIdMapping list.
  • The server now returns different HTTP status codes to indicate whether a request was successful or not and why.
  • The project_add command of the sync call now accepts project_id as a parameter for adding project notes, in addition to item_id for adding item notes.
  • The item_uncomplete_update_meta command of the sync call was removed, and it was replaced by the restore_state parameter that can be defined in the sync call item_uncomplete command.
  • The label_register command of the sync call was renamed to label_add.
  • The label_update_orders command was added in the sync call, and it can be used to update multiple label orders at once.
  • The note_id parameter of the note_update and note_delete commands of the sync call was renamed to id.
  • The update_goals command was added in the sync call, and it can be used to update the user’s karma goals.

For those calls that were kept from the old Standard API, here follows a list of the changes that took place:

  • The loginWithGoogle, uploadFile, deleteUser, getRedirectLink, getProductivityStats, updateNotificationSettings, getAllCompletedTasks and addItem calls were renamed to login_with_google, upload_file, delete_user, get_redirect_link, get_productivity_stats, update_notification_settings, get_all_completed_items and add_item respectively.
  • The renamed get_all_completed_items call, now takes two additional parameters, to_date and offset, in order to better select which completed tasks to access.

Finally, and although this affects both the new API and the older APIs, we would nonetheless like to mention here, that due to security reasons, support for callbacks (JSONP) was removed. This was used for overcoming the same-origin policy of modern browsers, and we can only suggest that a utility like cURL is used to access our APIs instead.

Authorization

In order to make authorized calls to Todoist APIs, your application must first obtain an access token from the users. This section describes the different ways of obtaining such a token.

Note that we encourage your application to use the OAuth protocol to obtain the access token from the user, as the other authentication methods (login and login_with_google) are scheduled for deprecation.

OAuth

External applications could obtain a user authorized API token via the OAuth2 protocol. Before getting started, developers need to create their applications in App Management Console and configure a valid OAuth redirect URL. A registered Todoist application is assigned a unique Client ID and Client Secret which are needed for the OAuth2 flow.

This procedure is comprised of 3 steps, which will be described below.

Step 1: The authorization request

An example of redirecting a user to the authorization URL:

$ curl https://todoist.com/oauth/authorize \
    -d client_id=0123456789abcdef \
    -d scope=data:read,data:delete \
    -d state=secretstring

Redirect users to the authorization URL at the endpoint https://todoist.com/oauth/authorize, with the specified request parameters.

Here follow the required parameters:

Name Description
client_id The unique Client ID of the Todoist application that you registered.
scope A comma separated list of permissions which you would like the users to grant to your application. See below a table with more details about this.
state A unique and unguessable string. It is used to protect you against cross-site request forgery attacks.

Here are the scope parameters mentioned before:

Name Description
task:add Grants permission to add tasks to the Inbox project (The application cannot read tasks data).
data:read Grants read-only access to application data, including tasks, projects, labels, and filters.
data:read_write Grants read and write access to application data, including tasks, projects, labels, and filters. This scope include task:add and data:read scopes.
data:delete Grants permission to delete application data, including tasks, labels, and filters.
project:delete Grants permission to delete projects.

And here are some common errors that you may encountered:

Error Description
User Rejected Authorization Request When the user denies your authorization request, Todoist will redirect the user to the configured redirect URI with error paramete: http://example.com?error=access_denied.
Redirect URI Not Configured This JSON error will be returned to the requester (your user’s browser) if redirect URI is not configured in the App Management Console.
Invalid Application Status When your application exceeds the maximum token limit or when your application is being suspended due to abuse, Todoist will redirect the user to the configured redirect URI with the error parameter: http://example.com?error=invalid_application_status.
Invalid Scope When the scope parameter is invalid, Todoist will redirect the user to the configured redirect URI with error parameter: http://example.com?error=invalid_scope.

Step 2: The redirection to your application site

When the user grants your authorization request , the user will be redirected to the redirect URL configured in your application setting. The redirect request will come with two query parameters attached: code and state.

The code parameter contains the authorization code that you will use to exchange for an access token. The state parameter should match the state parameter that you supplied in the previous step. If the state is unmatched, your request has been compromised by other parties, and the process should be aborted.

Step 3: The token exchange

An example of exchanging the token:

$ curl https://todoist.com/oauth/access_token \
    -d client_id=0123456789abcdef \
    -d client_secret=secret \
    -d code=abcdef \
    -d redirect_uri=https://example.com

On success, Todoist returns HTTP 200 with token in JSON object format:

{
  "access_token": "0123456789abcdef0123456789abcdef01234567", 
  "token_type": "Bearer"
}

Once you have the authorization code, you can exchange it for the access token at the endpoint POST https://todoist.com/oauth/access_token.

Here follow the required parameters:

Name Description
client_id The unique Client ID of the Todoist application that you registered.
client_secret The unique Client Secret of the Todoist application that you registered.
code The unique string code which you obtained in the previous step.

And here are some common errors that you may encountered (all the error response will be in JSON format):

Error Description
Bad Authorization Code Error Occurs when the code parameter does not match the code that is given in the redirect request: {"error": "bad_authorization_code"}
Incorrect Client Credentials Error Occurs when the client_id or client_secret parameters are incorrect: {"error": "incorrect_application_credentials"}

Login with password

On success, an HTTP 200 OK with a JSON object with user data is returned:

$ curl https://todoist.com/API/v6/login \
    -d email=me@example.com \
    -d password=secret
{
  "start_page": "overdue, 7 days",
  "date_format": 0,
  "last_used_ip": "10.20.30.40",
  "api_token": "0123456789abcdef0123456789abcdef01234567",
  "karma_trend": "-",
  "inbox_project": 128501411,
  "time_format": 0,
  "image_id": null,
  "beta": 0,
  "sort_order": 0,
  "business_account_id": null,
  "full_name": "Example User",
  "mobile_number": null,
  "shard_id": 2,
  "timezone": "Europe/Athens",
  "is_premium": false,
  "mobile_host": null,
  "id": 1855589,
  "has_push_reminders": false,
  "is_dummy": 0,
  "premium_until": null,
  "team_inbox": null,
  "next_week": 1,
  "token": "0123456789abcdef0123456789abcdef01234567",
  "tz_offset": ["+03:00", 3, 0, 1],
  "join_date": "Wed 30 Apr 2014 13:24:38 +0000",
  "seq_no": 2180270834,
  "karma": 684.0,
  "is_biz_admin": false,
  "default_reminder": null,
  "email": "me@example.com"
}
>>> import todoist
>>> api = todoist.TodoistAPI()
>>> api.login('me@example.com', 'secret')
{
  'api_token': '0123456789abcdef0123456789abcdef01234567',
  'beta': 0,
  'business_account_id': None,
  'date_format': 0,
  'default_reminder': None,
  'email': 'me@example.com',
  'full_name': 'Example User',
  'has_push_reminders': False,
  'id': 1855589,
  'image_id': None,
  'inbox_project': 128501411,
  'is_biz_admin': False,
  'is_dummy': 0,
  'is_premium': False,
  'join_date': 'Wed 30 Apr 2014 13:24:38 +0000',
  'karma': 684.0,
  'karma_trend': '-',
  'last_used_ip': '10.20.30.40',
  'mobile_host': None,
  'mobile_number': None,
  'next_week': 1,
  'premium_until': None,
  'seq_no': 2180270834,
  'shard_id': 2,
  'sort_order': 0,
  'start_day': 1,
  'start_page': 'overdue, 7 days',
  'team_inbox': None,
  'time_format': 0,
  'timezone': 'Europe/Athens',
  'token': '0123456789abcdef0123456789abcdef01234567',
  'tz_offset': ['+03:00', 3, 0, 1]
}

Login user into Todoist to get a token, which is necessary to do any communication with the server.

Required parameters

Parameter Description
email User’s email.
password User’s password.

Login with Google

On success, an HTTP 200 OK with a JSON object with user data is returned:

$ curl https://todoist.com/API/v6/login_with_google \
    -d email=me@example.com \
    -d oauth2_token=01234567-89ab-cdef-0123-456789abcdef

{
  "start_page": "overdue, 7 days",
  "date_format": 0,
  "last_used_ip": "10.20.30.40",
  "api_token": "0123456789abcdef0123456789abcdef01234567",
  "karma_trend": "-",
  "inbox_project": 128501411,
  "time_format": 0,
  "image_id": null,
  "beta": 0,
  "sort_order": 0,
  "business_account_id": null,
  "full_name": "Example User",
  "mobile_number": null,
  "shard_id": 2,
  "timezone": "Europe/Athens",
  "is_premium": false,
  "mobile_host": null,
  "id": 1855589,
  "has_push_reminders": false,
  "is_dummy": 0,
  "premium_until": null,
  "team_inbox": null,
  "next_week": 1,
  "token": "0123456789abcdef0123456789abcdef01234567",
  "tz_offset": ["+03:00", 3, 0, 1],
  "join_date": "Wed 30 Apr 2014 13:24:38 +0000",
  "seq_no": 2180270834,
  "karma": 684.0,
  "is_biz_admin": false,
  "default_reminder": null,
  "email": "me@example.com"
}
>>> import todoist
>>> api = todoist.TodoistAPI()
>>> api.login_with_google('me@example.com', '01234567-89ab-cdef-0123-456789abcdef')
{
  'api_token': '0123456789abcdef0123456789abcdef01234567',
  'beta': 0,
  'business_account_id': None,
  'date_format': 0,
  'default_reminder': None,
  'email': 'me@example.com',
  'full_name': 'Example User',
  'has_push_reminders': False,
  'id': 1855589,
  'image_id': None,
  'inbox_project': 128501411,
  'is_biz_admin': False,
  'is_dummy': 0,
  'is_premium': False,
  'join_date': 'Wed 30 Apr 2014 13:24:38 +0000',
  'karma': 684.0,
  'karma_trend': '-',
  'last_used_ip': '10.20.30.40',
  'mobile_host': None,
  'mobile_number': None,
  'next_week': 1,
  'premium_until': None,
  'seq_no': 2180270834,
  'shard_id': 2,
  'sort_order': 0,
  'start_day': 1,
  'start_page': 'overdue, 7 days',
  'team_inbox': None,
  'time_format': 0,
  'timezone': 'Europe/Athens',
  'token': '0123456789abcdef0123456789abcdef01234567',
  'tz_offset': ['+03:00', 3, 0, 1]
}

Login user into Todoist with Google account.

Implementation notes

While authenticating, application exchanges their users' OAuth 2.0 access tokens to tokens provided by Todoist. OAuth 2.0 access token must be issued for the scope oauth2:https://www.googleapis.com/auth/userinfo.email

It doesn’t matter how you receive the access token. Android applications can use AccountManager to get it done. Other developers should consider using generic authentication instructions.

Required parameters

Parameter Description
email User’s email.
oauth2_token OAuth 2.0 access token, received by application from user.

Optional parameters

Parameter Description
auto_signup If set to 1 and user with this email and Google Account doesn’t exist yet, then automatically registers a new account.
full_name User’s full name if user is about to be registered. If not set, a user email nickname will be used.
timezone User’s timezone if user is about to be registered. If not set, we guess the timezone from the client’s IP address. In case of failure, “UTC” timezone will be set up for a newly created account.
lang User’s language. Can be de, fr, ja, pl, pt_BR, zh_CN, es, hi, ko, pt, ru, zh_TW

Token from Settings

You can also obtain your personal access token directly from the Todoist web application Settings:

Settings -> Todoist Settings -> Account -> API token

Sync workflow

Retrieve data

An example of the JSON object returned, of a new user’s empty account complete data:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d seq_no=0 \
    -d seq_no_global=0 \
    -d resource_types='["all"]'
{
  "seq_no_global": 2180537512,
  "Collaborators": [],
  "DayOrdersTimestamp": "1344642991.1",
  "Notes": [],
  "Labels": [],
  "UserId": 1855589,
  "CollaboratorStates": [],
  "DayOrders": {},
  "LiveNotifications": [],
  "seq_no": 2180537512,
  "User": {
    "start_page": "overdue, 7 days",
    "join_date": "Wed 30 Apr 2014 13:24:38 +0000",
    "is_premium": false,
    "sort_order": 0,
    "full_name": "Example User",
    "has_push_reminders": false,
    "timezone": "Europe\/Athens",
    "id": 1855589,
    "next_week": 1,
    "completed_count": 20,
    "tz_offset": ["+03:00", 3, 0, 1],
    "email": "me@example.com",
    "start_day": 1,
    "is_dummy": 0,
    "inbox_project": 128501411,
    "time_format": 0,
    "image_id": null,
    "beta": 0,
    "premium_until": null,
    "business_account_id": null,
    "mobile_number": null,
    "mobile_host": null,
    "date_format": 0,
    "karma_trend": "-",
    "token": "0123456789abcdef0123456789abcdef01234567",
    "karma": 684.0,
    "is_biz_admin": false,
    "default_reminder": null
  },
  "Filters": [
    { "user_id": 1855589,
      "name": "No due date",
      "color": 6,
      "is_deleted": 0,
      "item_order": 8,
      "query": "no date",
      "id": 1855589 },
    { "user_id": 1855589,
      "name": "View all",
      "color": 6,
      "is_deleted": 0,
      "item_order": 7,
      "query": "view all",
      "id": 1855589 },
    { "user_id": 1855589,
      "name": "Priority 4",
      "color": 6,
      "is_deleted": 0,
      "item_order": 6,
      "query": "priority 4",
      "id": 1855589 },
    { "user_id": 1855589,
      "name": "Priority 3",
      "color": 6,
      "is_deleted": 0,
      "item_order": 5,
      "query": "priority 3",
      "id": 1855589 },
    { "user_id": 1855589,
      "name": "Priority 2",
      "color": 6,
      "is_deleted": 0,
      "item_order": 4,
      "query": "priority 2",
      "id": 1855589 },
    { "user_id": 1855589,
      "name": "Priority 1",
      "color": 6,
      "is_deleted": 0,
      "item_order": 3,
      "query": "priority 1",
      "id": 1855589 },
    { "user_id": 1855589,
      "name": "Assigned to others",
      "color": 12,
      "is_deleted": 0,
      "item_order": 2,
      "query": ":to_others:",
      "id": 1855589 },
    { "user_id": 1855589,
      "name": "Assigned to me",
      "color": 12,
      "is_deleted": 0,
      "item_order": 1,
      "query": ":to_me:",
      "id": 1855589 }
  ],
  "Items": [],
  "WebStaticVersion": 305,
  "Reminders": [],
  "Projects": [
    { "color": 7,
      "collapsed": 0,
      "inbox_project": true,
      "archived_date": null,
      "archived_timestamp": 0,
      "id": 1855589,
      "indent": 1,
      "name": "Inbox",
      "user_id": 1855589,
      "is_deleted": 0,
      "item_order": 0,
      "shared": false,
      "is_archived": 0}
  ],
  "LiveNotificationsLastRead": 0
}
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.sync(resource_types=['all'])
{ 'CollaboratorStates': [],
  'Collaborators': [],
  'DayOrders': {},
  'DayOrdersTimestamp': '1344642991.1',
  'Filters': [
    { 'color': 6,
      'id': 4638883,
      'is_deleted': 0,
      'item_order': 8,
      'name': 'No due date',
      'query': 'no date',
      'user_id': 1855589},
    { 'color': 6,
      'id': 4638882,
      'is_deleted': 0,
      'item_order': 7,
      'name': 'View all',
      'query': 'view all',
      'user_id': 1855589},
    { 'color': 6,
      'id': 4638881,
      'is_deleted': 0,
      'item_order': 6,
      'name': 'Priority 4',
      'query': 'priority 4',
      'user_id': 1855589},
    { 'color': 6,
      'id': 4638880,
      'is_deleted': 0,
      'item_order': 5,
      'name': 'Priority 3',
      'query': 'priority 3',
      'user_id': 1855589},
    { 'color': 6,
      'id': 4638879,
      'is_deleted': 0,
      'item_order': 4,
      'name': 'Priority 2',
      'query': 'priority 2',
      'user_id': 1855589},
    { 'color': 6,
      'id': 4638878,
      'is_deleted': 0,
      'item_order': 3,
      'name': 'Priority 1',
      'query': 'priority 1',
      'user_id': 1855589},
    { 'color': 12,
      'id': 4638876,
      'is_deleted': 0,
      'item_order': 2,
      'name': 'Assigned to others',
      'query': ':to_others:',
      'user_id': 1855589},
    { 'color': 12,
      'id': 4638874,
      'is_deleted': 0,
      'item_order': 1,
      'name': 'Assigned to me',
      'query': ':to_me:',
      'user_id': 1855589},
  ],
  'Items': [],
  'Labels': [],
  'LiveNotifications': [],
  'LiveNotificationsLastRead': 0,
  'Notes': [],
  'Projects': [
    { 'archived_date': None,
       'archived_timestamp': 0,
       'collapsed': 0,
       'color': 7,
       'id': 128501411,
       'inbox_project': True,
       'indent': 1,
       'is_archived': 0,
       'is_deleted': 0,
       'item_order': 0,
       'name': 'Inbox',
       'shared': False,
       'user_id': 1855589}
  ],
  'Reminders': [],
  'User': {
    'beta': 0,
    'business_account_id': None,
    'completed_count': 20,
    'date_format': 0,
    'default_reminder': None,
    'email': 'me@example.com',
    'full_name': 'Example User',
    'has_push_reminders': False,
    'id': 1855589,
    'image_id': None,
    'inbox_project': 128501411,
    'is_biz_admin': False,
    'is_dummy': 0,
    'is_premium': False,
    'join_date': 'Wed 30 Apr 2014 13:24:38 +0000',
    'karma': 684.0,
    'karma_trend': '-',
    'mobile_host': None,
    'mobile_number': None,
    'next_week': 1,
    'premium_until': None,
    'sort_order': 0,
    'start_day': 1,
    'start_page': 'overdue, 7 days',
    'time_format': 0,
    'timezone': 'Europe/Athens',
    'token': '0123456789abcdef0123456789abcdef01234567',
    'tz_offset': ['+03:00', 3, 0, 1]
  },
  'UserId': 1855589,
  'WebStaticVersion': 305,
  'seq_no': 2180537512L,
  'seq_no_global': 2180537512L
}

The sync API call is used to retrieve data (both all and only updated).

Required parameters

Parameter Description
token User’s API token (returned on successful login). Else the session cookie is used.
seq_no Sequence number. On the initial request you should pass 0. On all other requests you should pass the last seq_no you received from the server.
seq_no_global Global sequence number. On the initial request you should pass 0. On all other requests you should pass the last seq_no_global you received from the server.
resource_types This parameter controls which resources to fetch from the server. It can be useful for speeding up the load of most important user’s data (like the list of projects and tasks) and to get the rest of the data asynchronously later on. It should be a JSON-encoded list of strings. For example, ["projects", "labels", "filters"]. Below is the list of recognizable values for strings: projects for the list of projects, items for list of tasks, labels for the list of labels, notes for the list of notes, filters for the list of filters, reminders for the list of reminders, locations for the list of locations, user for the user’s details, live_notifications for the list of live notifications, day_orders for the list of day orders, collaborators for the list of collaborators, and all for all the above. In order to include the notification settings (that is needed on platforms that implement native notifications), the notification_settings has to explicitly be included in the list of resource types.

Optional parameters

Parameter Description
day_orders_timestamp The sync API requests return DayOrdersTimestamp that specifies when the day orders were last updated. If you omit day_orders_timestamp then none of then will be fetched. If you specify day_orders_timestamp then day orders will be returned if your timestamp is different from the servers. If you send day_orders_timestamp and the day orders have not been updated then the server won’t return the DayOrders entry at all.

Explanation of data returned

A brief explanation of what each object returned contains, while each of them will be later described in more detail.

Data Description
Users A JSON object with a user’s information.
Projects A list of JSON objects of projects.
Items A JSON list of objects of items.
Labels A JSON list of objects (including things like color, id etc.)
Filters A JSON list of custom filters.
DayOrders A JSON object specifying the order of items in daily agenda. If DayOrdersTimestamp is sent and day orders have not been updated then DayOrders won’t be returned at all!
DayOrdersTimestamp A string specifying when day orders where last updated. Use this to not fetch day orders on every request.
Reminders A JSON list containing all reminders for all items in the project.
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.
CollaboratorsStates A JSON list specifying the state of each collaborator in each project. The state can be invited, active, inactive, deleted.
LiveNotifications A JSON list of notifications for the user.
LiveNotificationsLastRead What is the last live notification the user has seen? This is used to implement unread notifications.
SettingsNotifications This is needed on platforms that implement native notifications.

Send data

Example of creating a new project, where an HTTP 200 OK with a JSON object of temporary id to real id mappings is returned (this will be explained later):

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "project_add", "temp_id": "381e601f-0ef3-4ed6-bf95-58f896d1a314", "uuid": "ed1ce597-e4c7-4a88-ba48-e048d827c067", "args": {"name": "Project1", "item_order": 1, "indent": 1, "color": 1}}]'
{
  "seq_no_global": 2180537513,
  "UserId": 1855589,
  "seq_no": 2180537513,
  "SyncStatus": {"ed1ce597-e4c7-4a88-ba48-e048d827c067": "ok"},
  "TempIdMapping": {"381e601f-0ef3-4ed6-bf95-58f896d1a314": 128501470},
}
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.sync(commands=[{'type': 'project_add', 'temp_id': '381e601f-0ef3-4ed6-bf95-58f896d1a314', 'uuid': 'ed1ce597-e4c7-4a88-ba48-e048d827c067', 'args': {'name': 'Project1', 'item_order': 1, 'indent': 1, 'color': 1}}]
{ 
  'SyncStatus': {'ed1ce597-e4c7-4a88-ba48-e048d827c067': 'ok'},
  'TempIdMapping': {'381e601f-0ef3-4ed6-bf95-58f896d1a314': 128501470},
  'UserId': 1855589,
  'seq_no': 2180537513L,
  'seq_no_global': 2180537513L,
}

The sync API call can also take a list of JSON object commands which specify which changes should be done to the model. These changes could be adding projects, deleting tasks, adding notes etc.

It supports two big features which can make syncing easier: temporary ids, that is the ability to use and resolve temporary ids, and duplication protection which ensures that a command isn’t run two times.

Required parameters

Parameter Description
commands A list of JSON object commands, which will be processed by the server in the same order as specified in this list (so special care should be taken on this order). The available commands to sent are described later in the documentation.
token User’s API token (returned on successful login). Else the session cookie is used.

Commands parameters

Parameter Description
type The type of the command sent.
args The arguments of this specific command.
uuid A universal unique identifier (UUID) that is used for duplication protection, ie. to ensure that the same command isn’t executed twice.
temp_id Only for commands creating a new object, a unique temporary id.

Explanation of extra data returned

When there are commands to be sent to the server, some extra data are returned.

Data Description
TempIdMapping A JSON list containing all the temporary ids mapped to real ids.
SyncStatus A JSON list containing the return value of each of the commands sent.

Limits

The maximum number of commands is 100 per request, and this is done to prevent timeouts and other problems when dealing with big requests.

There’s also a maximum number of 50 sync requests per minute for each user, in order to prevent clients from accidentally overloading our servers.

Temporary ids

An example that shows how temporary ids can be used and referenced:

[
  { "type": "project_add",
    "temp_id": "c7beb07f-b226-4eb1-bf63-30d782b07b1a",
    "args": {
      "name": "Project3",
      "item_order": 1,
      "indent": 1,
      "color": 1
    },
    "uuid": "ac417051-1cdc-4dc3-b4f8-14526d5bfd16"
  },
  {
    "type": "project_update",
    "args": {
      "id": "c7beb07f-b226-4eb1-bf63-30d782b07b1a",
      "color": 2
    },
    "uuid": "849fff4e-8551-4abb-bd2a-838d092775d7"
  }
]

You can see that the project_add command has a temp_id property, which specifies which temporary id this new project has. The project_update command later references this temporary id. The API will automatically resolve these ids. Additionally sync will return the real id in the result. Remember to update your local model with these real ids e.g.:

{"c7beb07f-b226-4eb1-bf63-30d782b07b1a": 128501682}

Your application will use temporary ids and the Sync API has special support for them. We suggest that you use UUIDs to generate these ids to give them uniqueness.

While the system remembers temporary ids and their mappings to real ids, it’s important to use real ids when they are available to you (typically after a sync). This is important since the API only remembers the last 500 temporary ids for each user!

Errors

The server uses the HTTP status codes to indicate result or failure of a request. And as is usually 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 codes

Status code Description
200 OK The request was processed successfuly.
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.

Return values

An example of an error return value:

{"error_code": 18, "error": "Required argument is missing: name"}

In any case, a JSON object is always returned. So if the request was succesful, a JSON object with the relevant to the request data is returned or if there is no data to return a simple "ok", while if the request failed, a JSON object of the format {"error_code": error_code, "error": error_string} is returned (where error_code is a number, and error_string a description).

An example of a single request sync return value:

{
  "SyncStatus": {"863aca2c-65b4-480a-90ae-af160129abbd": "ok"}
}

An example of a multiple requests sync return value:

{
  "SyncStatus": {
    "32eaa699-e9d7-47ed-91ea-e58d475791f1": "ok",
    "bec5b356-3cc1-462a-9887-fe145e3e1ebf": {"error_code": 15, "error": "Invalid temporary id"}
  }
}

An example of a single request operating on multiple objects return value:

{
  "SyncStatus": {
    "66386321-fb87-4f95-9dfe-7bf5c3823e85" : {
        "128501470": "ok",
        "128501607": {"error_code": 20, "error": "Project not found"}
    }
  }
}

Also, specifically for the case of the sync request, where multiple requests can be sent with a single call by the client, there is a special object reserved for indicating the return value of each specific request, the SyncStatus.

The SyncStatus is a dictionary of the return values of each of the multiple requests. Each key/value pair in this dictionary is the uuid field which matches the UUID of each request, and actual return value of each request.

If one or more of the multiple requests operate in multiple objects, then the value part is itself a dictionary of return values one for each of the multiple objects, where each object is distinguished by its id.

Projects

A project in Todoist is a JSON object. Typically a project object will look like this:

{
  "color": 1,
  "collapsed": 0,
  "archived_date": null,
  "indent": 1,
  "is_deleted": 0,
  "id": 128501470,
  "user_id": 1855589,
  "name": "Project1",
  "archived_timestamp": 0,
  "item_order": 36,
  "shared": false,
  "is_archived": 0
}
{
  'shared': False,
  'name': 'Project1',
  'user_id': 1855589,
  'color': 1,
  'is_deleted': 0,
  'collapsed': 0,
  'archived_date': None,
  'item_order': 36,
  'indent': 1,
  'is_archived': 0,
  'archived_timestamp': 0,
  'id': 128501470
}

A project in Todoist is a JSON object. Typically a project will have the following properties:

Properties

Property Description
id The unique id of the project.
user_id The unique id of the user that owns the project.
name The name of the project.
color The color of the project, an index is an array. For example #bde876, #ff8581, etc.
indent The indent of the item (a number between 1 and 4 where 1 is top-level).
item_order Project’s order in the project list. Smaller number should be located in the top.
collapsed If set to 1 the project’s sub projects are collapsed. Otherwise they aren’t.

Add a project

An example of adding a project:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "project_add", "temp_id": "4ff1e388-5ca6-453a-b0e8-662ebf373b6b", "uuid": "32774db9-a1da-4550-8d9d-910372124fa4", "args": {"name": "Project4"}}]'
{ ...
  "SyncStatus": {"32774db9-a1da-4550-8d9d-910372124fa4": "ok"},
  "TempIdMapping": {"4ff1e388-5ca6-453a-b0e8-662ebf373b6b": 128501815},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> project = api.projects.add('Project4')
>>> api.commit()

Add a new project.

Required arguments

Argument Description
name The name of the new project.

Optional arguments

Argument Description
color The color of the new project.
indent The indent of the item (a number between 1 and 4, where 1 is top-level).
item_order The order of the new project.

Update a project

An example of updating a project:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands=[{"type": "project_update", "uuid": "1ca42128-d12f-4a66-8413-4d6ff2838fde", "args": {"id": 128501815, "indent": 2}}]'
{ ...
  "SyncStatus": {"1ca42128-d12f-4a66-8413-4d6ff2838fde": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> project = api.projects.get_by_id(128501815)
>>> project.update(indent=2)
>>> api.commit()

Update an existing project.

Required parameters

Argument Description
id The id of the project to update.

Optional arguments

Argument Description
name New name of the project.
color New color of the project.
indent The indent of the item (a number between 1 and 4, where 1 is top-level).
item_order The order of the project.
collapsed 1 if the project should be collapsed, 0 if it should not be collapsed.

Delete projects

An example of deleting a project:


$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands=[{"type": "project_delete", "uuid": "367182ba-125f-4dbb-bff6-c1343fd751e4", "args": {"ids": [128501815]}}]'
{ ...
  "SyncStatus": {"367182ba-125f-4dbb-bff6-c1343fd751e4": {"128501815": "ok"}},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> project = api.projects.get_by_id(128501815)
>>> project.delete()
>>> api.commit()

Delete an existing project.

Required arguments

Argument Description
ids List of the ids of the projects to delete.

Archive a project

An example of archiving a project:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands=[{"type": "project_archive", "uuid": "bbec1a60-2bdd-48ac-a623-c8eb968e1697", "args": {"id": 128501682}}]'
{ ...
  "SyncStatus": {"bbec1a60-2bdd-48ac-a623-c8eb968e1697": "ok},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> project = api.projects.get_by_id(128501682)
>>> project.archive()
>>> api.commit()

Archive project and its children. Only available for Todoist Premium users.

Required arguments

Argument Description
id The id of the project to archive.

Unarchive a project

An example of unarchiving a project:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands=[{"type": "project_unarchive", "uuid": "7d86f042-e098-4fa6-9c1f-a61fe8c39d74", "args": {"id": 128501682}}]'
{ ...
  "SyncStatus": {"7d86f042-e098-4fa6-9c1f-a61fe8c39d74": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> project = api.projects.get_by_id(128501815)
>>> project.unarchive()
>>> api.commit()

Unarchive project and its children. Only available for Todoist Premium users.

Required arguments

Argument Description
id The id of the project to unarchive.

Update multiple orders/indents

An example of updating the orders and indents of multiple projects at once:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands=[{"type": "project_update_orders_indents", "uuid": "bf0855a3-0138-4b76-b895-88cad8db9edc", "args": {"ids_to_orders_indents": {"128501470": [42, 1], "128501607": [43, 1]}}}]'
{ ...
  "SyncStatus": {
    "bf0855a3-0138-4b76-b895-88cad8db9edc": {
      "128501470": "ok",
      "128501607": "ok"
    },
  },
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.projects.update_orders_indents({128501470: [42, 1], 128501607: [43, 1]})
>>> api.commit()

Update the orders and indents of multiple projects at once.

Required arguments

Argument Description
ids_to_orders_indents A dictionary, where a project id is the key, and a list with two elements, the order and the indent, are its value: project_id: [item_order, indent].

Items

A item in Todoist is a JSON object. The dates will be in UTC timezone. Typically a item object will look like:

{
  "due_date": null,
  "day_order": -1,
  "assigned_by_uid": 1855589,
  "is_archived": 0,
  "labels": [],
  "sync_id": null,
  "in_history": 0,
  "has_notifications": 0,
  "indent": 1,
  "checked": 0,
  "date_added": "Fri 26 Sep 2014 08:25:05 +0000",
  "id": 33511505,
  "content": "Task1",
  "user_id": 1855589,
  "due_date_utc": null,
  "children": null,
  "priority": 1,
  "item_order": 1,
  "is_deleted": 0,
  "responsible_uid": null,
  "project_id": 128501470,
  "collapsed": 0,
  "date_string": ""
}
{
  'is_archived': 0,
  'labels': [],
  'sync_id': None,
  'in_history': 0,
  'indent': 1,
  'checked': 0,
  'children': None,
  'priority': 1,
  'user_id': 1855589,
  'id': 33511505,
  'content': 'Task1',
  'item_order': 1,
  'project_id': 128501470,
  'date_string': '',
  'due_date': None,
  'day_order': -1,
  'assigned_by_uid': 1855589,
  'collapsed': 0,
  'has_notifications': 0,
  'date_added': 'Fri 26 Sep 2014 08:25:05 +0000',
  'is_deleted': 0,
  'due_date_utc': None,
  'responsible_uid': None
}

Properties

Property Description
id Unique task id.
user_id The owner of the task.
content The text of the task.
project_id The id of the project to add the task to.
date_string The date of the task, added in free form text, for example it can be every day @ 10. Look at our reference to see which formats are supported.
date_lang The language of the date_string.
due_date_utc Should be formatted as YYYY-MM-DDTHH:MM, example: 2012-3-24T23:59. Value of due_date_utc must be in UTC. If you want to pass in due dates, note that date_string is required, while due_date_utc can be omitted. If date_string is provided, it will be parsed as local timestamp, and converted to UTC internally, according to the user’s profile settings.
in_history If set to 1, the task is marked completed.
collapsed If set to 1 the task’s sub tasks are collapsed. Otherwise they aren’t.
indent The indent of the item (a number between 1 and 4, where 1 is top-level).
priority The priority of the task (a number between 1 and 4, 4 for very urgent and 1 for natural).
indent The indent of the item (a number between 1 and 4, where 1 is top-level).
item_order The order of the task.
children The tasks child tasks (a list of task ids such as [13134,232345]).
labels The tasks labels (a list of label ids such as [2324,2525]).
assigned_by_uid The id of user who assigns current task. 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 automatically be set up by your uid.
responsible_uid The id of user who is responsible for accomplishing the current task. 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 automatically be set up by null.

Add an item

An example of adding a task:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "item_add", "temp_id": "43f7ed23-a038-46b5-b2c9-4abda9097ffa", "uuid": "997d4b43-55f1-48a9-9e66-de5785dfd69b", "args": {"content": "Task1", "project_id": 128501470}}]'
{ ...
  "SyncStatus": {"997d4b43-55f1-48a9-9e66-de5785dfd69b": "ok"},
  "TempIdMapping": {"43f7ed23-a038-46b5-b2c9-4abda9097ffa": 33548400},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> item = api.items.add('Task1', 128501470)
>>> api.commit()

Add a new task to a project.

Required arguments

Argument Description
content The text of the task.
project_id The id of the project to add the task to.

Optional arguments

Argument Description
priority The priority of the task (a number between 1 and 4, 4 for very urgent and 1 for natural).
indent The indent of the item (a number between 1 and 4, where 1 is top-level).
date_string The date of the task, added in free form text, for example it can be every day @ 10. Look at our reference to see which formats are supported.
date_lang The language of the date_string.
due_date_utc Should be formatted as YYYY-MM-DDTHH:MM, example: 2012-3-24T23:59. Value of due_date_utc must be in UTC. If you want to pass in due dates, note that date_string is required, while due_date_utc can be omitted. If date_string is provided, it will be parsed as local timestamp, and converted to UTC internally, according to the user’s profile settings.
item_order The order of the task.
children The tasks child tasks (a list of task ids such as [13134,232345])
labels The tasks labels (a list of label ids such as [2324,2525])
assigned_by_uid The id of user who assigns current task. 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 automatically be set up by your uid.
responsible_uid The id of user who is responsible for accomplishing the current task. 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 automatically be set up by null.
note Add a note directly to the task, note is a string of the content.

Update an item

An example of updating a task:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "item_update", "uuid": "318d16a7-0c88-46e0-9eb5-cde6c72477c8", "args": {"id": 33548400, "priority": 2}}]'
{ ...
  "SyncStatus": {"318d16a7-0c88-46e0-9eb5-cde6c72477c8": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> item = api.items.get_by_id(33548400)
>>> item.update(priority=2)
>>> api.commit()

Update an existing task.

Required arguments

Argument Description
id The id of the item to update.

Optional arguments

Argument Description
content The text of the task.
date_string The date of the task, added in free form text, for example it can be every day @ 10. Look at our reference to see which formats are supported.
date_lang The language of the date_string.
priority The priority of the task (a number between 1 and 4, 4 for very urgent and 1 for natural).
indent The indent of the item (a number between 1 and 4, where 1 is top-level).
item_order The order of the task.
collapsed 1 if the item should be collapsed, 0 if it should not be collapsed.
children The tasks child tasks (a list of task ids such as [13134,232345])
labels The tasks labels (a list of label ids such as [2324,2525])
assigned_by_uid The id of user who assigns current task. 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 automatically be set up by your uid.
responsible_uid The id of user who is responsible for accomplishing the current task. 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 automatically be set up by null.

Delete items

An example of deleting a task:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "item_delete", "uuid": "f8539c77-7fd7-4846-afad-3b201f0be8a5", "args": {"ids": [33548400]}}]'
{ ...
  "SyncStatus": {"f8539c77-7fd7-4846-afad-3b201f0be8a5": {"33548400": "ok"}},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> item = api.items.get_by_id(33548400)
>>> item.delete()
>>> api.commit()

Delete an existing task.

Required arguments

Argument Description
ids List of the ids of the items to delete.

Move an item

An example of moving of a task from one project to another project:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "item_move", "uuid": "818f108a-36d3-423d-857f-62837c245f3b", "args": {"project_items": {"128501470": [33548400]}, "to_project": 128501607}}]'
{ ...
  "SyncStatus": {"818f108a-36d3-423d-857f-62837c245f3b": {"33548400": "ok"}},
  ... }

>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.items.get_by_id(33548400)
>>> item.move(128501607)
>>> api.commit()

Move a task from one project to another project.

Required arguments

Argument Description
project_items A JSON mapping telling Todoist where the items are currently found. From project ids to item ids, could be like this {"1523":["9637423"]}, where 1523 is project id and 9637423 is item id.
to_project A project_id that the items should be moved to. Could be 1245.

Complete items

An example of completing a task:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "item_complete", "uuid": "a74bfb5c-5f1d-4d14-baea-b7415446a871", "args": {"project_id": 128501470, "ids": [33548400]}}]'
{ ...
  "SyncStatus": {"a74bfb5c-5f1d-4d14-baea-b7415446a871": {"33548400": "ok"}},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.items.get_by_id(33548400)
>>> item.complete()
>>> api.commit()

Complete tasks and move them to history.

Required arguments

Argument Description
project_id The id of the project which the items are part of.
ids A JSON list of ids to complete.

Optional arguments

Argument Description
force_history If these tasks should be moved to history, default is 1. Setting it to 0 will not move it to history. Useful when checking off sub tasks.

Uncomplete items

An example of uncompleting a task:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "item_uncomplete", "uuid": "710a60e1-174a-4313-bb9f-4df01e0349fd", "args": {"project_id": 128501470, "ids": [33548400]}}]'
{ ...
  "SyncStatus": {"710a60e1-174a-4313-bb9f-4df01e0349fd": {"33548400": "ok"}},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.items.get_by_id(33548400)
>>> item.uncomplete()
>>> api.commit()

Uncomplete tasks and move them to the active projects.

Required arguments

Argument Description
project_id The id of the project to which the items will be moved to.
ids A JSON list of ids to uncomplete.

Optional arguments

Argument Description
update_item_orders If this is set to 0 the item orders should not be updated, while by default this is set 1 and they are updated.
restore_state A dictionary, where item id is the key, and its value is a list of four elements, whether the item is in history, whether it is checked, its order and indent: item_id: [in_history, checked, item_order, indent]

Complete a recurring task

An example of completing a recurring task:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "item_update_date_complete", "uuid": "c5888360-96b1-46be-aaac-b49b1135feab", "args": {"id": 33548400, "new_date_utc": "2014-10-30T23:59", "date_string": "every day", "is_forward": 1}}]'
{ ...
  "SyncStatus": {"c5888360-96b1-46be-aaac-b49b1135feab": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.items.update_date_complete(33548400, '2014-10-30T23:59', 'every day', 1)
>>> api.commit()

Complete a recurring task, and 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).

Required arguments

Argument Description
id The id of the item to update.

Optional arguments

Argument Description
new_date_utc Should be formatted as YYYY-MM-DDTHH:MM (in UTC).
date_string The date of the task, added in free form text, for example it can be every day @ 10. Look at our reference to see which formats are supported.
is_forward Indicates if it’s a complete 1 or uncomplete 0.

Update multiple orders/indents

An example of updating the orders and indents of multiple items at once:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "item_update_orders_indents", "uuid": "a2bf0c06-f834-4442-99ab-b86fdfc66ed5", "args": {"ids_to_orders_indents": {"33548400": [1, 1]}}}]'
{ ...
  "SyncStatus": {"a2bf0c06-f834-4442-99ab-b86fdfc66ed5": {"33548400": "ok"}},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.items.update_orders_indents({33548400: [1, 1]})
>>> api.commit()

Update the orders and indents of multiple items at once.

Required arguments

Argument Description
ids_to_orders_indents A dictionary, where an item id is the key, and a list with two elements, the order and the indent, are its value: item_id: [item_order, indent].

Update day orders

An example of updating the day orders of multiple items at once:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "item_update_day_orders", "uuid": "dbeb40fc-905f-4d8a-8bae-547d3bbd6e91", "args": {"ids_to_orders": {"33548400": 1}}}]'
{ ...
  "SyncStatus": {"dbeb40fc-905f-4d8a-8bae-547d3bbd6e91": {"33548400": "ok"}},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.items.update_day_orders({33548400: 1})
>>> api.commit()

Update the day orders of multiple items at once.

Required arguments

Argument Description
ids_to_orders A dictionary, where an item id is the key, and the day order its value: item_id: day_order.

Labels

A label in Todoist is a JSON object. Typically a label object will look like:

{
  "is_deleted": 0,
  "uid": 1,
  "color": 7,
  "id": 1234,
  "name": "Label1"
}
{
  'color': 7,
  'is_deleted': 0,
  'uid': 1,
  'name': 'Label1',
  'id': 1234
}

Properties

Property Description
id The id of the label.
name The name of the label.
color The color of the label.
item_order Label’s order in the label list.

Add a label

An example of adding a label:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "label_add", "temp_id": "f2f182ed-89fa-4bbb-8a42-ec6f7aa47fd0", "uuid": "ba204343-03a4-41ff-b964-95a102d12b35", "args": {"name": "Label1"}}]'
{ ...
  "SyncStatus": {"ba204343-03a4-41ff-b964-95a102d12b35": "ok"},
  "TempIdMapping": {"f2f182ed-89fa-4bbb-8a42-ec6f7aa47fd0": 1234},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> label = api.labels.add('Label1')
>>> api.commit()

Add a label.

Required arguments

Argument Description
name The name of the label.

Optional arguments

Argument Description
color The color of the label.
item_order Label’s order in the label list.

Update a label

An example of updating a label:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "label_update", "uuid": "9c9a6e34-2382-4f43-a217-9ab017a83523", "args": {"id": 1234, "color": 3}}]'
{ ...
  "SyncStatus": {"9c9a6e34-2382-4f43-a217-9ab017a83523": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> label = api.labels.get_by_id(1234)
>>> label.update(color=3)
>>> api.commit()

Update a label.

Required arguments

Argument Description
id The id of the label.

Optional arguments

Argument Description
name The name of the label.
color The color of the label.
item_order Label’s order in the label list.

Delete a label

An example of deleting a label:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "label_delete", "uuid": "aabaa5e0-b91b-439c-aa83-d1b35a5e9fb3", "args": {"id": 1234}}]'
{ ...
  "SyncStatus": {"aabaa5e0-b91b-439c-aa83-d1b35a5e9fb3": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> label = api.labels.get_by_id(1234)
>>> label.delete()
>>> api.commit()

Delete a label.

Required arguments

Argument Description
id The id of the label.

Update multiple orders

An example of updating the orders of multiple labels at once:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands=[{"type": "label_update_orders", "uuid": "1402a911-5b7a-4beb-bb1f-fb9e1ed798fb", "args": {"id_order_mapping": {"1234":  1, "5678": 2}}}]'
{ ...
  "SyncStatus": {
    "517560cc-f165-4ff6-947b-3adda8aef744": {
      "1234": "ok",
      "5678": "ok"
    }
  },
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.labels.update_orders({1234: 1, 5678: 2})
>>> api.commit()

Update the orders of multiple labels at once.

Required arguments

Argument Description
id_order_mapping A dictionary, where a label id is the key, and the order its value: label_id: order.

Notes

A note in Todoist is a JSON object. Typically a note object will look like:

{
  "is_deleted": 0,
  "is_archived": 0,
  "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"
  }
  "posted_uid": 1855589,
  "item_id": 33548400,
  "uids_to_notify": null,
  "id": 1234,
  "posted": "Wed 01 Oct 2014 14:54:55 +0000"
}
{
  'is_deleted': 0,
  'is_archived': 0,
  'content': 'Note',
  'item_id': 33548400,
  'posted_uid': 1855589,
  'posted': 'Wed 01 Oct 2014 14:54:55 +0000',
  'id': 1234,
  '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': None
}

Notes are only available for Todoist Premium users.

Properties

Property Description
id The id of the note.
content The content of the note.
item_id The item which the note is part of.
project_id The project which the note is part of (in the case of a project note)
file_attachment A file attached to 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 upload_file API call, or by any external resource.

Base file properties

Attribute Description
file_name The name of the file.
file_size The size of the file in bytes.
file_type MIME type.
file_url 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) respources, as exposing this files in Todoist may issue a browser warning.
upload_state Upload completion state.

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 upload_file API call) have following sizes: 96x96, 288x288, 528x528.

Attribute Description
tn_l Large thumbnail.
tn_m Medium thumbnail.
tn_s Small 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.

Add a note

An example of adding a note:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "note_add", "temp_id": "59fe4461-287b-4b00-bacc-ee771137a732", "uuid": "e1005f08-acd6-4172-bab1-4338f8616e49", "args": {"item_id": 33548400, "content": "Note1"}}]'
{ ...
  "SyncStatus": {"e1005f08-acd6-4172-bab1-4338f8616e49": "ok"},
  "TempIdMapping": {"59fe4461-287b-4b00-bacc-ee771137a732": 1234},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> note = api.notes.add(33548400, 'Note1')
>>> api.commit()

Add a note.

Required arguments

Argument Description
item_id The id of the item.
content The content of the note.

Optional arguments

Argument Description
file_attachment A file attached to the note.

Add a project note

An example of adding a project note:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "note_add", "temp_id": "95653826-fc43-47b3-86c8-c11f90fe7aba", "uuid": "f5d12bd9-d14d-4529-b223-9cd7d593119e", "args": {"project_id": 128501682, "content": "Note1"}}]'
{ ...
  "SyncStatus": {"f5d12bd9-d14d-4529-b223-9cd7d593119e": "ok"},
  "TempIdMapping": {"95653826-fc43-47b3-86c8-c11f90fe7aba": 1234},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> note = api.notes.add(128501682, 'Note1')
>>> api.commit()

Add a project note.

Required arguments

Argument Description
project_id The id of the project.
content The content of the note.

Optional arguments

Argument Description
file_attachment A file attached to the note.

Update a note

An example of updating a note:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "note_update", "uuid": "8a38f9c5-2cd0-4da5-87c1-26d617b354e0", "args": {"id": 1234, "content": "UpdatedNote1"}}]'
{ ...
  "SyncStatus": {"8a38f9c5-2cd0-4da5-87c1-26d617b354e0": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> note api.notes.get_by_id(1234)
>>> note.update(content='UpdatedNote1')
>>> api.commit()

Update a note.

Required arguments

Argument Description
id The id of the note.

Optional arguments

Argument Description
content The content of the note.
file_attachment A file attached to the note.

Delete a note

An example of deleting a note:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "note_delete", "uuid": "8d666fda-73c3-4677-8b04-5d223632c24f", "args": {"id": 1234, "item_id": 33548400}}]'
{ ...
  "SyncStatus": {"8d666fda-73c3-4677-8b04-5d223632c24f": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> note = api.notes.get_by_id(1234)
>>> note.delete()
>>> api.commit()

Delete a note.

Required arguments

Argument Description
id The id of the note.

Upload a file

On success, an HTTP 200 OK with JSON data of file data is returned:

$ curl https://todoist.com/API/v6/upload_file \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d file_name=example.jpg \
    --get --upload-file example.jpg
{
  "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
  ]
}
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.upload_file('example.jpg')
{
  '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.

Required parameters

Parameter Description
token The user’s token (received on login).
file_name The file name to be uploaded.

Base file properties

Attribute Description
file_name The name of the file
file_size The size of the file in bytes
file_type MIME type
file_url 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) respources, as exposing this files in Todoist may issue a browser warning.
upload_state Upload completion state

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 upload_file API call) have following sizes: 96x96, 288x288, 528x528.

Attribute Description
tn_l Large thumbnail.
tn_m Medium thumbnail.
tn_s Small 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.

Filters

A filter in Todoist is a JSON object. Typically a filter object will look like:

{
  "user_id": 1855589,
  "name": "Priority 1",
  "color": 6,
  "item_order": 3,
  "query": "priority 1",
  "is_deleted": 0,
  "id": 4638878
}
{
  'user_id': 1855589,
  'name': 'Priority 1',
  'color': 6,
  'is_deleted': 0,
  'item_order': 3,
  'query': 'priority 1',
  'id': 4638878
}

Filters are only available for Todoist Premium users.

Properties

Property Description
id The id of the filter.
name The name of the filter.
item_order Filter’s order in the filter list.
color The color of the filter.
query The query to search for. Examples of searches can be found in the Todoist help page.

Add a filter

An example of adding a filter:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "filter_add", "temp_id": "9204ca9f-e91c-436b-b408-ea02b3972686", "uuid": "0b8690b8-59e6-4d5b-9c08-6b4f1e8e0eb8", "args": {"name": "Filter1", "query": "no due date"}}]'
{ ...
  "SyncStatus": {"0b8690b8-59e6-4d5b-9c08-6b4f1e8e0eb8": "ok"},
  "TempIdMapping": {"9204ca9f-e91c-436b-b408-ea02b3972686": 9},
  ... }

>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> filter = api.filters.add('Filter1', 'no due date')
>>> api.commit()

Add a filter.

Required arguments

Argument Description
name The name of the filter.
query The query to search for. Examples of searches can be found in the Todoist help page.

Optional arguments

Argument Description
item_order Filter’s order in the filter list.
color The color of the filter.

Update a filter

An example of updating a filter:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "filter_update", "uuid": "a68b588a-44f7-434c-b3c5-a699949f755c", "args": {"id": 9, "query": "tomorrow"}}]'
{ ...
  "SyncStatus": {"a68b588a-44f7-434c-b3c5-a699949f755c": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> filter = api.filters.get_by_id(9)
>>> filter.update(query='tomorrow')
>>> api.commit()

Update a filter.

Required arguments

Argument Description
id The id of the filter.

Optional arguments

Argument Description
name The name of the filter.
query The query to search for. Examples of searches can be found in the Todoist help page.
item_order Filter’s order in the filter list.
color The color of the filter.

Delete a filter

An example of deleting a filter:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "filter_delete", "uuid": "b8186025-66d5-4eae-b0dd-befa541abbed", "args": {"id": 9}}]'
{ ...
  "SyncStatus": {"b8186025-66d5-4eae-b0dd-befa541abbed": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> filter = api.filters.get_by_id(9)
>>> filter.delete()
>>> api.commit()

Delete a filter.

Required arguments

Argument Description
id The id of the filter.

Update multiple orders

An example of updating the orders of multiple filters at once:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands=[{"type": "filter_update_orders", "uuid": "517560cc-f165-4ff6-947b-3adda8aef744", "args": {"id_order_mapping": {"9":  1, "10": 2}}}]'
{ ...
  "SyncStatus": {
    "517560cc-f165-4ff6-947b-3adda8aef744": {
      "9": "ok",
      "10": "ok"
    }
  },
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.filters.update_orders({9: 1, 10: 2})
>>> api.commit()

Update the orders of multiple filters at once.

Required arguments

Argument Description
id_order_mapping A dictionary, where a filter id is the key, and the order its value: filter_id: order.

Reminders

A reminder in Todoist is a JSON object. Typically a reminder object will look like:

{
  "due_date": "Mon 06 Oct 2014 11:00:00 +0000",
  "due_date_utc": "Mon 06 Oct 2014 11:00:00 +0000",
  "is_deleted": 0,
  "service": "email",
  "item_id": 33511505,
  "notify_uid": 1855589,
  "type": "absolute",
  "id": 1234,
  "date_string": "Oct 6 @ 2pm"
}
{
  'due_date': 'Mon 06 Oct 2014 11:00:00 +0000',
  'is_deleted': 0,
  'service': 'email',
  'due_date_utc': 'Mon 06 Oct 2014 11:00:00 +0000',
  'item_id': 33511505,
  'notify_uid': 1855589,
  'type': 'absolute',
  'id': 1234,
  'date_string': 'Oct 6 @ 2pm'
}

Reminders are only available for Todoist Premium users.

Properties

Property Description
id The id of the reminder.
item_id The item id for which the reminder is about.
service The way to get notified of the reminder: email for e-mail, mobile for mobile text message, or push for mobile push notification.
type 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_date_utc Should be formatted as YYYY-MM-DDTHH:MM, example: 2012-3-24T23:59. Value of due_date_utc must be in UTC. If you want to pass in due dates, note that date_string is required, while due_date_utc can be omitted. If date_string is provided, it will be parsed as local timestamp, and converted to UTC internally, according to the user’s profile settings.
date_string The date of the task, added in free form text, for example it can be every day @ 10. Look at our reference to see which formats are supported.
date_lang The language of the date_string.
notify_uid The user id which should be notified of the reminder, typically the current user id creating the reminder.

Add a reminder

An example of adding a relative reminder:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "reminder_add", "temp_id": "e24ad822-a0df-4b7d-840f-83a5424a484a", "uuid": "41e59a76-3430-4e44-92b9-09d114be0d49", "args": {"item_id": 33511505, "service": "email", "minute_offset": 30}}]'
{ ...
  "SyncStatus": {"41e59a76-3430-4e44-92b9-09d114be0d49": "ok"},
  "TempIdMapping": {"e24ad822-a0df-4b7d-840f-83a5424a484a": 1234},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> reminder = api.reminders.add(33511505, service='email', minute_offset=30)
>>> api.commit()

An example of adding an absolute reminder:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "reminder_add", "temp_id": "952a365e-4965-4113-b4f4-80cdfcada172u", "uuid": "e7c8be2d-f484-4852-9422-a9984c58b1cd", "args": {"item_id": 33511505, "service": "email", "due_date_utc": "2014-10-15T11:00"}}]'
{ ...
  "SyncStatus": {"e7c8be2d-f484-4852-9422-a9984c58b1cd": "ok"},
  "TempIdMapping": {"952a365e-4965-4113-b4f4-80cdfcada172": 1234},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> reminder = api.reminders.add(33511505, service='email', due_date_utc='2014-10-15T11:00')
>>> api.commit()

An example of adding a location reminder:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "reminder_add", "temp_id": "7ad9609d-579f-4828-95c5-3600acdb2c81", "uuid": "830cf409-daba-479c-a624-68eb0c07d01c", "args": {"item_id": 33511505, "service": "email", "type": "location", "name": "Aliados", "loc_lat": "41.148581", "loc_long":"-8.610945000000015", "loc_trigger":"on_enter", "radius": 100}}]'
{ ...
  "SyncStatus": {"830cf409-daba-479c-a624-68eb0c07d01c": "ok"},
  "TempIdMapping": {"7ad9609d-579f-4828-95c5-3600acdb2c81": 1234},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> reminder = api.reminders.add(33511505, service='email', type='location', name='Aliados', loc_lat='41.148581', loc_long='-8.610945000000015', loc_trigger='on_enter', radius=100)
>>> api.commit()

Add a reminder.

Required arguments

Argument Description
item_id The item id for which the reminder is about.

Optional arguments

Argument Description
service The way to get notified of the reminder: email for e-mail, mobile for mobile text message, or push for mobile push notification.
type 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.
minute_offset 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 set in order to add a relative reminder.
due_date_utc Should be formatted as YYYY-MM-DDTHH:MM, example: 2012-3-24T23:59. Value of due_date_utc must be in UTC. If you want to pass in due dates, note that date_string is required, while due_date_utc can be omitted. If date_string is provided, it will be parsed as local timestamp, and converted to UTC internally, according to the user’s profile settings.
date_string The date of the task, added in free form text, for example it can be every day @ 10. Look at our reference to see which formats are supported.
date_lang The language of the date_string.
notify_uid The user id which should be notified of the reminder, typically the current user id creating the reminder.
name An alias name for the location.
loc_lat The location latitude.
loc_long The location longitude.
loc_trigger What should the trigger the reminder: on_enter for entering the location, or on_leave for leaving the location.
radius The radius around the location that is still considered as part of the location.

Update a reminder

An example of updating a reminder:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "reminder_update", "uuid": "b0e7562e-ea9f-4c84-87ee-9cbf9c103234", "args": {"id": 1234, "due_date_utc": "2014-10-10T15:00"}}]'
{ ...
  "SyncStatus": {"b0e7562e-ea9f-4c84-87ee-9cbf9c103234": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> reminder = api.reminders.get_by_id(1234)
>>> reminder.update(due_date_utc='2014-10-10T15:00')
>>> api.commit()

Update a reminder.

Required arguments

Argument Description
id The id of the filter.

Optional arguments

Argument Description
service The way to get notified of the reminder: email for e-mail, mobile for mobile text message, or push for mobile push notification.
type 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.
minute_offset The relative time in minutes from the current time in which the reminder should be triggered.
due_date_utc Should be formatted as YYYY-MM-DDTHH:MM, example: 2012-3-24T23:59. Value of due_date must be in UTC. If you want to pass in due dates, note that date_string is required, while due_date (due_date) can be omitted. If date_string is provided, it will be parsed as local timestamp, and converted to UTC internally, according to the user’s profile settings.
date_string The date of the task, added in free form text, for example it can be every day @ 10. Look at our reference to see which formats are supported.
date_lang The language of the date_string.
notify_uid The user id which should be notified of the reminder, typically the current user id creating the reminder.
name An alias name for the location.
loc_lat The location latitude.
loc_long The location longitude.
loc_trigger What should the trigger the reminder: on_enter for entering the location, or on_leave for leaving the location.
radius The radius around the location that is still considered as part of the location.

Delete a reminder

An example of deleting a reminder:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "reminder_delete", "uuid": "0896d03b-eb90-49f7-9020-5ed3fd09df2d", "args": {"id": 9}}]'
{ ...
  "SyncStatus": {"0896d03b-eb90-49f7-9020-5ed3fd09df2d": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> reminder = api.reminders.get_by_id(1234)
>>> reminder.delete()
>>> api.commit()

Delete a reminder.

Required arguments

Argument Description
id The id of the filter.

Clear the locations

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "clear_locations", "uuid": "d285ae02-80c6-477c-bfa9-45272d7bddfb", "args": {}}]'
{ ...
  "SyncStatus": {"d285ae02-80c6-477c-bfa9-45272d7bddfb": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> reminder = api.locations.clear()
>>> api.commit()

Clears the locations list, which is used for the location reminders.

Users

A user in Todoist is a JSON object. The dates will be in the UTC timezone. Typically a user object will have the following properties:

An example of a user object:

{
  "start_page": "overdue, 7 days",
  "is_premium": false,
  "sort_order": 0,
  "full_name": "Example User",
  "has_push_reminders": false,
  "timezone": "Europe\/Athens",
  "id": 1855589,
  "next_week": 1,
  "completed_count": 20,
  "tz_offset": ["+03:00", 3, 0, 1],
  "email": "me@xample.com",
  "karma": 684.0,
  "start_day": 1,
  "date_format": 0,
  "inbox_project": 128501411,
  "time_format": 0,
  "image_id": null,
  "beta": 0,
  "karma_trend": "-",
  "business_account_id": null,
  "mobile_number": null,
  "mobile_host": null,
  "is_dummy": 0,
  "premium_until": null,
  "join_date": "Wed 30 Apr 2014 13:24:38 +0000",
  "api_token": "0123456789abcdef0123456789abcdef01234567",
  "is_biz_admin": false,
  "default_reminder": null
}
{
  'beta': 0,
  'business_account_id': None,
  'completed_count': 20,
  'date_format': 0,
  'default_reminder': None,
  'email': 'me@exampe.com',
  'full_name': 'Example User',
  'has_push_reminders': False,
  'id': 1855589,
  'image_id': None,
  'inbox_project': 128501411,
  'is_biz_admin': False,
  'is_dummy': 0,
  'is_premium': False,
  'join_date': 'Wed 30 Apr 2014 13:24:38 +0000',
  'karma': 684.0,
  'karma_trend': '-',
  'mobile_host': None,
  'mobile_number': None,
  'next_week': 1,
  'premium_until': None,
  'sort_order': 0,
  'start_day': 1,
  'start_page': 'overdue, 7 days',
  'time_format': 0,
  'timezone': 'Europe/Athens',
  'api_token': '0123456789abcdef0123456789abcdef01234567',
  'tz_offset': ['+03:00', 3, 0, 1]
}

Properties

Property Description
id User’s unique id.
api_token User’s token (that should be used to call the other API methods).
email User’s email.
full_name User’s real name.
start_page User’s default view on Todoist. The start page can be one of the following: _info_page for the info page, _blank for a blank page, _project_<PROJECT_ID> for project with id <PROJECT_ID>, and <ANY_QUERY> to query after anything.
timezone User’s timezone in a string.
tz_offset User’s timezone offset [GMT_STRING, HOURS, MINUTES, IS_DAYLIGHT_SAVINGS_TIME].
time_format If it’s 0 then show time as 13:00, else show time as 1:00pm.
date_format If it’s 0 then show dates as DD-MM-YYYY, else show dates as MM-DD-YYYY.
sort_order If it’s 0 then show Oldest dates first when viewing projects. Else Oldest dates last.
mobile_number User’s mobile number.
mobile_host User’s mobile host.
premium_until When does the user’s Premium subscription expire?
default_reminder What is the default reminder for the user? Reminders are only possible for Premium users. The default reminder can be one of the following: email, mobile, push
auto_reminder How many minutes before should the default reminder be set? It can be -1, 0, 10, 30, 60, 120, e.g. 10 minutes before the due date. -1 is set to mean that no default reminder will be added

Register a new user

And example of registering a new user:

$ curl https://todoist.com/API/v6/register \
    -d email=me@example.com \
    -d full_name=Example\ User \
    -d password=secret
{
  "start_day": 7,
  "start_page": "overdue, 7 days",
  "date_format": 1,
  "last_used_ip": "10.20.30.40",
  "api_token": "0123456789abcdef0123456789abcdef01234567",
  "karma_trend": "-",
  "inbox_project": 128501411,
  "time_format": 1,
  "image_id": null,
  "beta": 0,
  "sort_order": 0,
  "business_account_id": null,
  "full_name": "Example User",
  "mobile_number": null,
  "shard_id": 2,
  "timezone": "UTC",
  "is_premium": false,
  "mobile_host": null,
  "id": 1855589,
  "has_push_reminders": false,
  "is_dummy": 0,
  "premium_until": null,
  "team_inbox": null,
  "next_week": 1,
  "token": "0123456789abcdef0123456789abcdef01234567",
  "tz_offset": ["+00:00", 0, 0, 0],
  "join_date": "Wed 30 Apr 2014 13:24:38 +0000",
  "seq_no": 2180270834,
  "karma": 0.0,
  "is_biz_admin": false,
  "default_reminder": null,
  "email": "me@example.com"}
}
>>> import todoist
>>> api = todoist.TodoistAPI()
>>> api.register('me@example.com', 'Example User', 'secret')
{
  'start_page': 'overdue, 7 days',
  'join_date': 'Wed 30 Apr 2014 13:24:38 +0000',
  'last_used_ip': '10.20.30.40',
  'is_premium': False,
  'sort_order': 0,
  'full_name': 'Example User',
  'api_token': '0123456789abcdef0123456789abcdef01234567',
  'shard_id': 2,
  'has_push_reminders': False,
  'id': 1855589,
  'team_inbox': None,
  'next_week': 1,
  'tz_offset': ['+00:00', 0, 0, 0],
  'timezone': 'UTC',
  'email': 'me@example.com',
  'start_day': 7,
  'is_dummy': 0,
  'inbox_project': 128501411,
  'time_format': 1,
  'image_id': None,
  'beta': 0,
  'premium_until': None,
  'business_account_id': None,
  'mobile_number': None,
  'mobile_host': None,
  'date_format': 1,
  'karma_trend': '-',
  'token': '0123456789abcdef0123456789abcdef01234567',
  'seq_no': 2180270834,
  'karma': 0.0,
  'is_biz_admin': False,
  'default_reminder': None
}

Register a new user.

Required parameters

Parameter Description
email User’s email.
full_name User’s full name.
password User’s password, should be at least 5 characters long.

Optional parameters

Parameter Description
lang User’s language. Can be de, fr, ja, pl, pt_BR, zh_CN, es, hi, ko, pt, ru, zh_TW.
timezone User’s timezone. As default we use the user’s IP address to determine the timezone.

Delete an existing user

An example of deleting an existing user:

$ curl https://todoist.com/API/v6/delete_user \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d current_password=secret
"ok"
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.delete_user('secret')
ok

Delete an existing user.

Required parameters

Parameter Description
token User’s token.
current_password User’s current password.

Optional parameters

Parameter Description
reason_for_delete Reason for deletion (used for feedback).

Update user’s properties

An example of updating the user’s properties:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "user_update", "uuid": "52f83009-7e27-4b9f-9943-1c5e3d1e6889", "args": {"time_format": 0}}]'
{ ...
  "SyncStatus": {"52f83009-7e27-4b9f-9943-1c5e3d1e6889": "ok"},
  ... }

>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.user.update(time_format=0)

Update the details of the user.

Optional parameters

Parameter Description
email User’s email.
full_name User’s full name.
password User’s password, which should be at least 5 characters long.
timezone User’s timezone.
date_format How should dates be formatted? If 0 DD-MM-YYYY will be used, if 1 MM-DD-YYYY will be used.
time_format How should times be formatted? If 0 13:00 will be used, if 1 1:00pm will be used.
start_day First day of week. 1 for Monday, 7 for Sunday.
next_week When postponing what day should we choose? 1 for Monday, 7 for Sunday.
start_page Can be one of following values: _blank to show blank page, _info_page to show info page _project_<PROJECT_ID> where <PROJECT_ID> is the id of the project to show, <ANY_QUERY> to query after anything (for example tod,tom,!!1).
default_reminder Can be one of the following values: email to send reminders by email, mobile to send reminders to mobile devices via SMS, push to send reminders to smart devices using push notifications (one of Android or iOS official client must be installed on the client side to receive these notifications), no_default to turn off sending default reminders.

Update karma goals

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "update_goals", "uuid": "b9bbeaf8-9db6-452a-a843-a192f1542892", "args": {"vacation_mode": 1}}]'
{ ...
  "SyncStatus": {"b9bbeaf8-9db6-452a-a843-a192f1542892": "ok"},
  ... }

>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.user.update_goals(vacation_mode=1)

Update the karma goals of the user.

Optional parameters

Parameter Description
daily_goal The target number of tasks to complete per day.
weekly_goal The target number of tasks to complete per week.
ignore_days A list with the days of the week to ignore. 1 for Monday, 7 for Sunday.
vacation_mode Marks the user as being on vacation.
karma_disabled Disables the karma and goals measuring alltogether.

Date query and search

On success, an HTTP 200 OK with a JSON object with the tasks found is returned:

$ curl https://todoist.com/API/v6/query \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d queries='["tomorrow","p1"]'
[
  {
    "query": "tomorrow",
    "type": "date",
    "data": [
      { "due_date": "Wed 08 Oct 2014 20:59:59 +0000",
        "is_deleted": 0,
        "assigned_by_uid": 1855589,
        "is_archived": 0,
        "labels": [],
        "sync_id": null,
        "day_order": 0,
        "postpone_count": 0,
        "in_history": 0,
        "has_notifications": 0,
        "indent": 1,
        "date_added": "Tue 07 Oct 2014 06:11:06 +0000",
        "user_id": 1855589,
        "children": null,
        "priority": 1,
        "complete_count": 0,
        "checked": 0,
        "id": 35825425,
        "content": "Task2",
        "item_order": 2,
        "seq_no": 2306453653,
        "responsible_uid": null,
        "project_id": 128501470,
        "collapsed": 0,
        "date_string": "8 Oct" },
      { "due_date": "Wed 08 Oct 2014 20:59:59 +0000",
        "is_deleted": 0,
        "assigned_by_uid": 1855589,
        "is_archived": 0,
        "labels": [],
        "sync_id": null,
        "day_order": 1,
        "postpone_count": 0,
        "in_history": 0,
        "has_notifications": 0,
        "indent": 1,
        "date_added": "Tue 07 Oct 2014 06:20:48 +0000",
        "user_id": 1855589,
        "children": null,
        "priority": 1,
        "complete_count": 0,
        "checked": 0,
        "id": 35826737,
        "content": "Task 3",
        "item_order": 3,
        "seq_no": 2306541514,
        "responsible_uid": null,
        "project_id": 128501470,
        "collapsed": 0,
        "date_string": "8 Oct"}
    ]
  },
  {
    "query": "p1",
    "type": "priority",
    "data": [
      { "due_date": null,
        "is_deleted": 0,
        "assigned_by_uid": 1855589,
        "is_archived": 0,
        "labels": [],
        "sync_id": null,
        "postpone_count": 5,
        "in_history": 0,
        "has_notifications": 0,
        "indent": 1,
        "date_added": "Fri 26 Sep 2014 11:54:48 +0000",
        "user_id": 1855589,
        "children": null,
        "priority": 4,
        "complete_count": 1,
        "checked": 0,
        "id": 33548400,
        "content": "Task1",
        "item_order": 1,
        "seq_no": 2306454606,
        "responsible_uid": null,
        "project_id": 128501470,
        "collapsed": 0,
        "date_string": "" }
    ]
  }
]
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.query(['tomorrow', 'p1'])
[
  {
    'data': [
      { 'assigned_by_uid': 1855589,
        'checked': 0,
        'children': None,
        'collapsed': 0,
        'complete_count': 0,
        'content': 'Task2',
        'date_added': 'Tue 07 Oct 2014 06:11:06 +0000',
        'date_string': '8 Oct',
        'day_order': 0,
        'due_date': 'Wed 08 Oct 2014 20:59:59 +0000',
        'has_notifications': 0,
        'id': 35825425,
        'in_history': 0,
        'indent': 1,
        'is_archived': 0,
        'is_deleted': 0,
        'item_order': 2,
        'labels': [],
        'postpone_count': 0,
        'priority': 1,
        'project_id': 128501470,
        'responsible_uid': None,
        'seq_no': 2306453653L,
        'sync_id': None,
        'user_id': 1855589 },
      { 'assigned_by_uid': 1855589,
        'checked': 0,
        'children': None,
        'collapsed': 0,
        'complete_count': 0,
        'content': 'Task 3',
        'date_added': 'Tue 07 Oct 2014 06:20:48 +0000',
        'date_string': '8 Oct',
        'day_order': 1,
        'due_date': 'Wed 08 Oct 2014 20:59:59 +0000',
        'has_notifications': 0,
        'id': 35826737,
        'in_history': 0,
        'indent': 1,
        'is_archived': 0,
        'is_deleted': 0,
        'item_order': 3,
        'labels': [],
        'postpone_count': 0,
        'priority': 1,
        'project_id': 128501470,
        'responsible_uid': None,
        'seq_no': 2306541514L,
        'sync_id': None,
        'user_id': 1855589 }
    ],
    'query': 'tomorrow',
    'type': 'date'
  },
  {
    'data': [
      { 'assigned_by_uid': 1855589,
        'checked': 0,
        'children': None,
        'collapsed': 0,
        'complete_count': 1,
        'content': 'Task1',
        'date_added': 'Fri 26 Sep 2014 11:54:48 +0000',
        'date_string': '',
        'due_date': None,
        'has_notifications': 0,
        'id': 33548400,
        'in_history': 0,
        'indent': 1,
        'is_archived': 0,
        'is_deleted': 0,
        'item_order': 1,
        'labels': [],
        'postpone_count': 5,
        'priority': 4,
        'project_id': 128501470,
        'responsible_uid': None,
        'seq_no': 2306454606L,
        'sync_id': None,
        'user_id': 1855589}],
    'query': 'p1',
    'type': 'priority'
  }
]

You can query after date, priority, or labels (only available for Todoist Premium users).

Required arguments

Argument Description
token The user’s token (received on login).
queries A JSON list of queries to search. Examples of searches can be found in the Todoist help page, but note, that not all of these examples are currently applicable for this method.

Optional arguments

Argument Description
as_count If set to 1 then no data will be returned, instead the count of tasks matching will be returned.

Miscellaneous

An example of getting the user’s absolute URL to redirect or to open in a browser:

$ curl https://todoist.com/API/v6/get_redirect_link \
    -d token=0123456789abcdef0123456789abcdef01234567
{"link": "https:\/\/local.todoist.com\/secureRedirect?path=%2Fapp&token=abcdefghijklmnopqrstuvwxyz01234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ"}
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.get_redirect_link()
{'link': 'https:\/\/local.todoist.com\/secureRedirect?path=%2Fapp&token=abcdefghijklmnopqrstuvwxyz.0123456789.ABCDEFGHIJKLMNOPQRSTUVWXYZ'}

Get the user’s absolute URL to redirect or to open in a browser. For the first time the link logs in the user automatically and performs a redirect to a given page, but once used, the link keeps working as a plain redirect. The link keeps working as a login link for as long as one week after it’s been issued.

Required parameters

Parameter Description
token The user’s token (received on login).

Optional parameters

Parameter Description
path The path to redirect user’s browser (default is “/app”).
hash The hash part of the path to redirect user’s browser.

Get productivity stats

An example of getting the user’s productivity stats:

$ curl https://todoist.com/API/v6/get_productivity_stats \
    -d token=0123456789abcdef0123456789abcdef01234567
{
  "karma_last_update": 50.0,
  "karma_trend": "up",
  "days_items": [
    { "date": "2014-11-03",
      "items": [],
      "total_completed": 0 },
  ],
  "completed_count": 0,
  "karma_update_reasons": [
    { "positive_karma_reasons": [4],
      "new_karma": 50.0,
      "negative_karma": 0.0,
      "positive_karma": 50.0,
      "negative_karma_reasons": [],
      "time": "Mon 20 Oct 2014 12:06:52"}
  ],
  "karma": 50.0,
  "week_items": [
    { "date": "2014-11-03\/2014-11-09",
      "items": [],
      "total_completed": 0 },
  ],
  "project_colors": {},
  "karma_graph": "https:\/\/todoist.com\/chart?cht=lc&chs=255x70&chd=s:A9&chco=dd4b39&chf=bg,s,ffffff&chxt=x,y&chxl=0:%7cMo%2C%2020%7c%7c1:%7c0%7c50&chxs=0,999999%7c1,999999",
  "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
  }
}
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.get_productivity_stats()
{
  'karma_last_update': 50.0,
  'karma_trend': 'up',
  'days_items': [
    { 'date': '2014-11-03',
      'items': [],
      'total_completed': 0}
  ],
  'completed_count': 0,
  'karma_update_reasons': [
    { 'positive_karma_reasons': [4],
      'new_karma': 50.0,
      'negative_karma': 0.0,
      'positive_karma': 50.0,
      'negative_karma_reasons': [],
      'time': 'Mon 20 Oct 2014 12:06:52' }
  ],
  'karma': 50.0,
  'week_items': [
    { 'date': '2014-11-03/2014-11-09',
      'items': [],
      'total_completed': 0 },
  ],
  'project_colors': {},
  'karma_graph': 'https://todoist.com/chart?cht=lc&chs=255x70&chd=s:A9&chco=dd4b39&chf=bg,s,ffffff&chxt=x,y&chxl=0:%7cMo%2C%2020%7c%7c1:%7c0%7c50&chxs=0,999999%7c1,999999',
  '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.

Required parameters

Parameter Description
token The user’s token (received on login).

Update notification settings

An example of updating the user’s notification settings

$ curl https://todoist.com/API/v6/update_notification_setting \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d notification_type=item_completed \
    -d service=email \
    -d dont_notify=1
{
  "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
  }
}
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.update_notification_setting('item_completed', 'email', 1)
{
  'biz_invitation_rejected': {
    'notify_push': True,
    'notify_email': True
  },
  'user_left_project': {
    'notify_push': True,
    'notify_email': True
  },
  'note_added': {
    'notify_push': True,
    'notify_email': True
  },
  'biz_trial_enter_cc': {
    'notify_push': True,
    'notify_email': True
  },
  'item_completed': {
    'notify_push': True,
    'notify_email': False
  },
  'biz_trial_will_end': {
    'notify_push': True,
    'notify_email': True
  },
  'biz_account_disabled': {
    'notify_push': True,
    'notify_email': True
  },
  'share_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.

Required parameters

Parameter Description
token The user’s token (received on login).
notification_type The notification type.
service The service type, which can be email or push.
dont_notify Should we notify on this service? Can be 1 or 0.

Get all completed items

An example of getting the user’s completed tasks

$ curl https://todoist.com/API/v6/get_all_completed_items \
    -d token=0123456789abcdef0123456789abcdef01234567
{
  "items": [
    { "content": "Item11",
      "meta_data": null,
      "user_id": 1855589,
      "task_id": 33511505,
      "note_count": 0,
      "project_id": 128501470,
      "completed_date": "Tue 17 Feb 2015 15:40:41 +0000",
      "id": 33511505
    }
  ],
  "projects": {
    "128501470":
    { "color": 7,
      "collapsed": 0,
      "archived_date": null,
      "indent": 1,
      "is_deleted": 0,
      "id": 128501470,
      "user_id": 1855589,
      "name": "Project1",
      "item_order": 36,
      "archived_timestamp": 0,
      "is_archived": 0 }
  }
}
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.get_all_completed_items()
{
  'items': [
    { 'user_id': 1855589,
      'task_id': 33511505,
      'note_count': 0,
      'completed_date': 'Tue 17 Feb 2015 15:40:41 +0000',
      'content': 'Item1',
      'meta_data': None,
      'project_id': 128501470,
      'id': 33511505},
  ],
  'projects': {
    '128501470':
      { 'name': 'Inbox',
        'user_id': 1855589,
        'color': 7,
        'is_deleted': 0,
        'collapsed': 0,
        'inbox_project': True,
        'archived_date': None,
        'item_order': 36,
        'is_archived': 0,
        'indent': 1,
        'archived_timestamp': 0,
        'id': 128501470 }
  }
}

Get all the user’s completed items (tasks). Only available for Todoist Premium users.

Required parameters

Parameter Description
token The user’s token (received on login).

Optional parameters

Parameter Description
project_id Filter the tasks by project_id.
limit The number of items to return (default is 30, while maximum is 50).
offset Can be used for pagination, when more than the limit tasks are returned.
from_date Return items with a completed date same or older than from_date (formated as 2007-4-29T10:13).
to_date Return items with a completed date newer than to_date (formated as 2007-4-29T10:13).

Add item

An example of adding a task:

$ curl https://todoist.com/API/v6/add_item \
    -d token=0123456789abcdef0123456789abcdef01234567
    -d content=Task1
{ "due_date": null,
  "assigned_by_uid": 1855589,
  "is_archived": 0,
  "labels": [],
  "sync_id": null,
  "in_history": 0,
  "has_notifications": 0,
  "date_added": "Wed 18 Feb 2015 11:09:11 +0000",
  "indent": 1,
  "children": null,
  "content": "Task1",
  "is_deleted": 0,
  "user_id": 1855589,
  "due_date_utc": null,
  "id": 33548400,
  "priority": 4,
  "item_order": 1,
  "responsible_uid": null,
  "project_id": 128501411,
  "collapsed": 0,
  "checked": 0,
  "date_string": "" }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.add_item("Task1")
{ 'is_archived': 0,
  'labels': [],
  'sync_id': None,
  'in_history': 0,
  'checked': 0,
  'id': 33548400,
  'priority': 4,
  'user_id': 1855589,
  'date_added': 'Wed 18 Feb 2015 11:09:11 +0000',
  'children': None,
  'content': 'Task1',
  'item_order': 1,
  'project_id': 128501411,
  'date_string': '',
  'due_date': None,
  'assigned_by_uid': 1855589,
  'collapsed': 0,
  'has_notifications': 0,
  'indent': 1,
  'is_deleted': 0,
  'due_date_utc': None,
  'responsible_uid': None }

Add a new task to a project. Note, that this is provided as a helper method, a shortcut, to quickly add a task without going through the Sync workflow described in a previous section.

Required parameters

Parameter Description
token The user’s token (received on login).
content The text of the task.

Optional parameters

Parameter Description
project_id The id of the project to add the task to (defaults to Inbox project).
date_string The date of the task, added in free form text, for example it can be every day @ 10. Look at our reference to see which formats are supported.
priority The priority of the task (a number between 1 and 4, 4 for very urgent and 1 for natural).
indent The indent of the item (a number between 1 and 4, where 1 is top-level).
item_order The order of the task.
children The tasks child tasks (a list of task ids such as [13134,232345])
labels The tasks labels (a list of label ids such as [2324,2525])
assigned_by_uid The id of user who assigns current task. 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 automatically be set up by your uid.
responsible_uid The id of user who is responsible for accomplishing the current task. 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 automatically be set up by null.
note Add a note directly to the task, note is a string of the content.

Sharing projects

Commands that are related to sharing projects will be described in this section.

Share a project

An example of sharing a project:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "share_project", "temp_id": "854be9cd-965f-4ddd-a07e-6a1d4a6e6f7a", "uuid": "fe6637e3-03ce-4236-a202-8b28de2c8372", "args": {"project_id": "128501470", "message": "", "email": "you@example.com"}}]'
{ ...
  "SyncStatus": {"fe6637e3-03ce-4236-a202-8b28de2c8372": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.share_project(128501470, 'you@example.com', message='')
>>> api.commit()

Share a project.

Required arguments

Argument Description
project_id The project to be shared.
email The user email with whom to share the project.

Optional arguments

Argument Description
message A message to be sent to the user.

Delete a collaborator

An example of deleting a person from a shared project:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "delete_collaborator", "uuid": "0ae55ac0-3b8d-4835-b7c3-59ba30e73ae4", "args": {"project_id": 128501470, "email": "you@example.com"}}]'
{ ...
  "SyncStatus": {"0ae55ac0-3b8d-4835-b7c3-59ba30e73ae4": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.delete_collaborator(128501470, 'you@example.com')
>>> api.commit()

Delete a person from a shared project.

Required arguments

Argument Description
project_id The project to be shared.
email The user email with whom the project was shared with.

Accept an invitation

An example of accepting an invitation:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "accept_invitation", "uuid": "4b254da4-fa2b-4a88-9439-b27903a90f7f", "args": {"invitation_id": 1234,  "invitation_secret": "abcdefghijklmno"}}]'
{ ...
  "SyncStatus": {"4b254da4-fa2b-4a88-9439-b27903a90f7f": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.invitations.accept(1234, 'abcdefghijklmno')
>>> api.commit()

Accept an invitation.

Required arguments

Argument Description
invitation_id The invitation id.
invitation_secret The secret fetched from the live notification.

Reject an invitation

An example of rejecting an invitation:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "reject_invitation", "uuid": "284fd900-c36f-44e5-ab92-ee93455e50e0", "args": {"invitation_id": 1234,  "invitation_secret": "abcdefghijklmno"}}]'
{ ...
  "SyncStatus": {"284fd900-c36f-44e5-ab92-ee93455e50e0": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.invitations.reject(1234, 'abcdefghijklmno')
>>> api.commit()

Reject an invitation.

Required arguments

Argument Description
invitation_id The invitation id.
invitation_secret The secret fetched from the live notification.

Delete an invitation

An example of deleting an invitation:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "delete_invitation", "uuid": "399f6a8d-ddea-4146-ae8e-b41fb8ff6945", "args": {"invitation_id": 128501470}}]'
{ ...
  "SyncStatus": {"399f6a8d-ddea-4146-ae8e-b41fb8ff6945": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.invitations.delete(128501470)
>>> api.commit()

Delete an invitation.

Required arguments

Argument Description
invitation_id The invitation to be deleted.

Take ownership

An example of taking ownership of a shared project:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "take_ownership", "uuid": "c6ff0de7-24a9-4cb8-a0e3-da5f669f6aea", "args": {"project_id": 128501470}}]'
{ ...
  "SyncStatus": {"c6ff0de7-24a9-4cb8-a0e3-da5f669f6aea": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.take_ownership(128501470)
>>> api.commit()

Take ownership of a shared project.

Required arguments

Argument Description
project_id The shared project of which to take the ownership.

Accept a business invitation

An example of accepting a business invitation:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "biz_accept_invitation", "uuid": "48538e47-7a9f-4f3d-927a-463ea997675e", "args": {"invitation_id": 1234,  "invitation_secret": "abcdefghijklmno"}}]'
{ ...
  "SyncStatus": {"48538e47-7a9f-4f3d-927a-463ea997675e": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.biz_invitations.accept(1234, 'abcdefghijklmno')
>>> api.commit()

Accept an invitation from Todoist for Business.

Required arguments

Argument Description
invitation_id The invitation id.
invitation_secret The secret fetched from the live notification.

Reject a business invitation

An example of rejecting a business invitation:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "biz_reject_invitation", "uuid": "a1b0460a-aab3-4555-9109-779cd0cb0966", "args": {"invitation_id": 1234,  "invitation_secret": "abcdefghijklmno"}}]'
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.biz_invitations.reject(1234, 'abcdefghijklmno')
>>> api.commit()

Reject an invitation from Todoist for Business.

Required arguments

Argument Description
invitation_id The invitation id.
invitation_secret The secret fetched from the live notification.

Live notifications

Examples of live notifications:

{
    "created": 1377639720,
    "from_uid": 123,
    "invitation_id": 456,
    "invitation_secret": "abcdefghijklmno",
    "notification_key": "notification_123",
    "notification_type": "share_invitation_sent",
    "seq_no": 12345567890,
    "state": "accepted"
}

{
    "created": 1377639720,
    "from_uid": 123,
    "invitation_id": 456,
    "notification_key": "notification_123",
    "notification_type": "share_invitation_accepted",
    "project_id": 789,
    "seq_no": 1234567890
}

{
    "created": 1377639720,
    "from_uid": 123,
    "invitation_id": 456,
    "notification_key": "notification_123",
    "notification_type": "share_invitation_rejected",
    "project_id": 789,
    "reject_email": "me@example.com",
    "seq_no": 1234567890
}

{
    "created": 1377639720,
    "from_uid": 123,
    "notification_key": "notification_123",
    "notification_type": "user_left_project",
    "project_id": 456,
    "seq_no": 1234567890
}

{
    "created": 1377639720,
    "from_uid": 123,
    "notification_key": "notification_123",
    "notification_type": "user_removed_from_project",
    "project_id": 456,
    "removed_name": "Example User",
    "removed_uid": 789,
    "seq_no": 1234567890
}

{
    "assigned_by_uid": 789,
    "created": 1377639720,
    "from_uid": 123,
    "item_content": "NewTask",
    "item_id": 456,
    "notification_key": "notification_123",
    "notification_type": "item_assigned",
    "project_id": 789,
    "responsible_uid": 321,
    "seq_no": 1234567890
}

{
    "assigned_by_uid": 789,
    "created": 1377639720,
    "from_uid": 123,
    "item_content": "NewTask",
    "item_id": 456,
    "notification_key": "notification_123",
    "notification_type": "item_completed",
    "project_id": 789,
    "responsible_uid": 321,
    "seq_no": 1234567890
}

{
    "assigned_by_uid": 789,
    "created": 1377639720,
    "from_uid": 123,
    "item": 456,
    "item_content": "NewTask",
    "notification_key": "notification_123",
    "notification_type": "item_uncompleted",
    "project": 789,
    "responsible_uid": 321,
    "seq_no": 1234567890
}

{
    "created": 1377639720,
    "from_uid": 123,
    "item_id": 456,
    "note_content": "NewTask",
    "note_id": 789,
    "notification_key": "notification_123",
    "notification_type": "note_added",
    "project_id": 321,
    "seq_no": 1234567890
}

{
    "created": 1377639720,
    "email": "me@example.com",
    "from_uid": 123,
    "notification_key": "notification_123",
    "notification_type": "biz_policy_disallowed_invitation",
    "project_id": 456,
    "seq_no": 1234567890,
    "user": {
        "email": "you@example.com",
        "full_name": "Example User",
        "id": "789",
        "image_id": "321"
    }
}

{
    "created": 1377639720,
    "from_uid": 123,
    "inviter_id": 456,
    "notification_key": "notification_123",
    "notification_type": "biz_policy_rejected_invitation",
    "seq_no": 1234567890,
    "user": {
        "email": "you@example.com",
        "full_name": "Example User",
        "id": "789",
        "image_id": "321"
    }
}

{
    "active_until": 1399299727,
    "created": 1377639720,
    "from_uid": 123,
    "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": 1377639720,
    "currency": "usd",
    "description": "2 x Subscription to Monthly ($3.00/month)",
    "from_uid": 123,
    "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": 1377639720,
    "from_uid": 123,
    "notification_key": "notification_123",
    "notification_type": "biz_account_disabled",
    "plan": "business_monthly",
    "quantity": 10,
    "seq_no": 1234567890
}

{
    "account_name": "Example Inc.",
    "created": 1377639720,
    "from_uid": 123,
    "from_user": {
        "email": "you@example.com",
        "full_name": "Example User",
        "id": "456",
        "image_id": "789"
    },
    "invitation_id": 321,
    "invitation_message": "Welcome to our team!",
    "invitation_secret": "abcdefghijklmno",
    "notification_key": "notification_123",
    "notification_type": "biz_invitation_created",
    "seq_no": 1234567890
}

{
    "created": 1377639720,
    "from_uid": 123,
    "from_user": {
        "account_name": "Example Inc.",
        "email": "you@example.com",
        "full_name": "Example User",
        "id": "456",
        "image_id": "789"
    },
    "invitation_id": 321,
    "notification_key": "notification_123",
    "notification_type": "biz_invitation_accepted",
    "seq_no": 1234567890
}

{
    "created": 1377639720,
    "from_uid": 123,
    "from_user": {
        "account_name": "Example Inc.",
        "email": "you@example.com",
        "full_name": "Example User",
        "id": "456",
        "image_id": "789"
    },
    "invitation_id": 321,
    "notification_key": "notification_123",
    "notification_type": "biz_invitation_rejected",
    "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 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 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 attempts to be paid, and the 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.

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
created Required. Live notification creation date. Integer representing a timestamps since epoch.
from_uid Required. The id of user who initiated this live notification.
notification_key Required. Unique notification key.
notification_type Required. Type of notification. Different notification type define different extra fields which are described below.
seq_no Required. Notification sequence number.
from_user Optional. User data, useful on share_invitation_sent.
project_name Optional. The project name, useful for share_invitation_* where you may not have the project in the local model.
invitation_secret Optional. Useful for accepting/rejecting invitations.

Here are the extra properties for the share_invitation_sent type of live notifications:

Property Description
state 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 The name of the user removed.
removed_uid The uid of the user removed.

Here are the extra properties for the biz_trial_will_end type of live notifications:

Property Description
quantity The number of users under the control of the business account.
plan Tariff plan name. Valid values are business_monthly and business_yearly.
active_until 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 The number of users under the control of the business account.
plan Tariff plan name. Valid values are business_monthly and business_yearly.
active_until 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 Invoice amount. Integer value in 0.01 of currency.
attempt_count Number of automatic payment attempts made for this invoice.
currency Currency value. Three-letter ISO currency code representing the currency in which the charge was made.
description Invoice description.
next_payment_attempt Timestamp value.

Here are the extra properties for the biz_account_disabled type of live notifications:

Property Description
quantity The number of users under the control of the business account.
plan Tariff plan name. Valid values are business_monthly and business_yearly.
active_until 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 Invitation state. Initially invited, can change the state to accepted or rejected.
invitation_secret Invitation secret. Should be used to accept or reject invitation.
invitation_message Invitation message.
account_name Business account (company) name.

Mark last read

An example of marking the last read notification:

$ curl https://todoist.com/API/v6/sync \
    -d token=0123456789abcdef0123456789abcdef01234567 \
    -d commands='[{"type": "live_notifications_mark_as_read", "uuid": "588b9ccf-29c0-4837-8bbc-fc858c0c6df8", "args": {"seq_no": 1234}}]'
{ ...
  "SyncStatus": {"588b9ccf-29c0-4837-8bbc-fc858c0c6df8": "ok"},
  ... }
>>> import todoist
>>> api = todoist.TodoistAPI('0123456789abcdef0123456789abcdef01234567')
>>> api.live_notifications.mark_as_read(1234)
>>> api.commit()

Mark the last read live notification.

Required arguments

Argument Description
seq_no The sequence number of the last read notification.

URL schemes

The following URL schemes might be also useful when accessing the Todoist applications (iOS and Android) or when performing certain action with them, so they are also included here for completeness.

Views

The following schemes are available to open a specific view:

Scheme Description
todoist:// Opens Todoist.
todoist://today Opens the today view.
todoist://next7days Opens the next 7 days view.
todoist://profile Opens the profile view.
todoist://inbox Opens the inbox view.
todoist://teaminbox Opens the team inbox view. If the user doesn’t have a business account (access to team inbox), it will show an alert saying that he/she doesn’t have access to the team inbox because doesn’t have a business account and will be redirected automatically to the inbox view.
todoist://notifications Opens notifications view.

Tasks

Example of adding a task:

todoist://addtask?content=mytask&date=tomorrow&priority=4

The following scheme is available to create new tasks:

Scheme Description
todoist://addtask Opens the add task view to add a new task to Todoist.

Here’s an example of a content value:

Create document about URL Schemes!

And how it should be supplied using Percent-encoding:

Create&20document%20about%20URL%20Schemes%21

Here’s an example of a date value:

Tomorrow @ 14:00

And how it should be supplied using Percent-encoding:

Tomorrow%20@%2014:00

The todoist://addtask scheme accepts the following optional values:

Value Description
content The content of the task, which should be a string that in Percent-encoding (also known as URL encoding).
date The due date of the task, which should be a string that in Percent-encoding (also known as URL encoding). Look at our reference to see which formats are supported.
priority The priority of the task, which should be a string with a value from 1 to 4.

If all the values are empty, it will just open the add task view. This URL Scheme will not automatically add the task to Todoist, it will just open the add task view and fill the fields.

Projects

The following scheme is available to show all the projects:

Scheme Description
todoist://projects Opens the projects view (shows all projects).

Example of opening a specific project:

todoist://project?id=128501470

The following scheme is available to open a specific project:

Scheme Description
todoist://project Opens an specific project using the id of the project.

The todoist://project scheme accepts the following required value:

Value Description
id The id of the project to view. If the id doesn’t exist, you don’t have access to the project, or the value is empty, an alert will be showed and the user will be redirected to the projects view.

Labels

The following scheme is available to show all the labels:

Scheme Description
todoist://labels Opens the labels view (shows all labels)

Example of opening a specific label:

todoist://label?id=1234

The following scheme is available to open a specific label:

Scheme Description
todoist://label Opens an specific label using the id of the label.

The todoist://label scheme accepts the following required value:

Value Description
id The id of the label to view. If the id doesn’t exist, you don’t have access to the label, or the value is empty, an alert will be showed and the user will be redirected to the labels view.

Filters

The following scheme is available to show all the filters:

Scheme Description
todoist://filters Opens the filters view (shows all filters)

Example of opening a specific filter:

todoist://filter?id=9

The following scheme is available to open a specific filter:

Scheme Description
todoist://filter Opens an specific filter using the id of the filter.

The todoist://filter scheme accepts the following required value:

Value Description
id The id of the filter to view. If the id doesn’t exist, you don’t have access to the filter, or the value is empty, an alert will be showed and the user will be redirected to the filters view.

Example of searching for “Test & Today”:

todoist://search?query=Test%20%26%20Today

The following scheme is available for searching (Android only):

Scheme Description
todoist://search Used to search in the Todoist application.

The todoist:/search scheme accepts the following required value:

Value Description
query The query to search in the Todoist application, which should be a string that in Percent-encoding (also known as URL encoding).

Webhooks

The Todoist Webhooks API allows applications to receive realtime notification (in form of HTTP POST payload) on the subscribed user events.

Notice that once you have webhook setup, you will start receiving webhook events from all your app users immediately.

Webhooks 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
item:added
item:updated
item:deleted
item:completed
item:uncompleted
note:added
note:updated
note:deleted
project:added
project:updated
project:deleted
project:archived
project:unarchived
label:added
label:deleted
label:updated
filter:added
filter:deleted
filter:updated

Event Structure / Delivery

Event JSON Object

Each webhook event is structured as a JSON object. The event JSON object follows this general structure:

{"event_name": "...", "user_id"=..., "event_data": {...}}

The structure of “event_data” object varies depending on the type of event it is. For instance, if it is a “item:added” event notification, The “event_data” will represents the newly added item.

Example Delivery

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": 1234,
    "event_data": {
      "due_date": null,
      "day_order": -1,
      "assigned_by_uid": 1855589,
      "is_archived": 0,
      "labels": [],
      "sync_id": null,
      "in_history": 0,
      "has_notifications": 0,
      "indent": 1,
      "checked": 0,
      "date_added": "Fri 26 Sep 2014 08:25:05 +0000",
      "id": 33511505,
      "content": "Task1",
      "user_id": 1855589,
      "due_date_utc": null,
      "children": null,
      "priority": 1,
      "item_order": 1,
      "is_deleted": 0,
      "responsible_uid": null,
      "project_id": 128501470,
      "collapsed": 0,
      "date_string": ""
    }
  },
  {
    "event_name": "item:updated",
    "user_id": 528,
    "event_data": {
      "due_date": null,
      "day_order": -1,
      "assigned_by_uid": 1855589,
      "is_archived": 0,
      "labels": [],
      "sync_id": null,
      "in_history": 0,
      "has_notifications": 0,
      "indent": 1,
      "checked": 0,
      "date_added": "Fri 26 Sep 2014 08:25:05 +0000",
      "id": 43311505,
      "content": "Task1",
      "user_id": 1855589,
      "due_date_utc": null,
      "children": null,
      "priority": 1,
      "item_order": 1,
      "is_deleted": 0,
      "responsible_uid": null,
      "project_id": 223501470,
      "collapsed": 0,
      "date_string": ""
    }
  },
  ...
}

Event Delivery

When your subscribed webhook events occourred, we would deliver an event notification to your configured webhook callback url via a HTTP POST request. Notice that the payload would be a JSON array because multiple event notifications could be delivered in a single notification request.

Payload Verification

To verify each webhook request was indeed sent by Todoist, we would include a X-Todoist-Hmac-SHA256 header which was 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.

Failed Delivery

When a event notification failed to be delivered to your webhook callback URL endpoint (i.e. due to server error, network failure, incorrect response…etc), it would be redelivered after 30 mins (1hr and 1.5hr for the second and the third retry respectively), and each notification would be redelivered for at most three times.

Your callback endpoint must respond with a HTTP 200 when receiving a event notification request. Response other than HTTP 200 would be considered as failed delivery, and the notification would be redelivered again.