Skip to content

Instantly share code, notes, and snippets.

@Maxr1998
Last active February 21, 2023 13:18
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save Maxr1998/82cebde74a4845cb485ac0d5a6dbefa6 to your computer and use it in GitHub Desktop.
Save Maxr1998/82cebde74a4845cb485ac0d5a6dbefa6 to your computer and use it in GitHub Desktop.
Python script to delete completed tasks from your Todoist Inbox
import todoist
api = todoist.TodoistAPI(token='<your_token_here')
# Initial sync of your account
api.sync()
# Find Inbox in project - can be adapted to delete completed tasks for other projects as well
projects = api.projects.all()
inbox = next(p for p in projects if 'inbox_project' in p)
# Process tasks until explicitly aborted
while True:
# Get completed tasks for project, a maximum of 100 tasks is supported per batch
completed = api.items.get_completed(project_id=inbox['id'], limit=100)
if not completed:
break # No completed tasks left, abort
# Delete the completed tasks
for c in completed:
api.items.delete(c['id'])
# Commit deletion requests
api.commit()
@taurit
Copy link

taurit commented Jan 15, 2023

I tried to use it in 2023, but unfortunately, it wouldn't work as-is, or with minor changes I made.
Perhaps it's related to this Reddit discussion where it's mentioned that the old python API used here was deprecated.

What I tried was:

  • update the script to have my API token
  • run the following in the console:
> pip install --user todoist
> python clean.py
Traceback (most recent call last):
  File "clean.py", line 3, in <module>
    api = todoist.TodoistAPI(token='... my token here ...')
AttributeError: module 'todoist' has no attribute 'TodoistAPI'

I also tried to switch to use todoist-python and use the new API

from todoist.api import TodoistAPI
api = TodoistAPI(token='... my token here ...')

but it wouldn't work either without further modifications.
So don't waste time trying to run it unless you want to update the code yourself ;)

@dmbeta
Copy link

dmbeta commented Jan 25, 2023

You can use the python requests library to make a request to the sync api and then delete them like before:
https://developer.todoist.com/sync/v9#get-all-completed-items

from todoist_api_python.api import TodoistAPI
import requests
import json
token = "your_token_here"
api = TodoistAPI(token)

def deleteTask(id):
    try:
        is_success = api.delete_task(task_id=id)
        print(id)
    except Exception as error:
        print(error)

url = "https://api.todoist.com/sync/v9/completed/get_all"

headers = {
    "Bearer": "your_token_here",
    "Authorization": "Bearer your_token_here"
}

response = requests.request("GET", url, headers=headers)

raw = json.loads(response.text)
items = raw["items"]
for item in items:
    deleteTask(item["id"])

@taurit
Copy link

taurit commented Jan 26, 2023

You can use the python requests library to make a request to the sync api and then delete them like before (...)

Thanks for sharing the code, @dmbeta!

I played with it for a while but eventually gave up for the following reasons:

  • Todoist API throttles requests. It does it to the degree, where use of batch commands of Sync API is required. I tried that too, but it was still hindering cleanup of thousands of items.
  • Deleting a task doesn't really remove it from the database. It might disappear from the archive, but the delete operation with details is added to the Activity Log and stays there forever. So the operation brings no protection against e.g. leak of historical data from the company, which was my main motivator :(

Thanks again.

@dmbeta
Copy link

dmbeta commented Jan 26, 2023

Maybe we can change the content before deleting, but I imagine that is also stored in the activity log. At this point then, we need a different more private to-do app, perhaps one with end-to-end encryption on the content of tasks. Only end-to-end encrypted to-do app I know of is Lunatask https://lunatask.app/ and note-taking apps like Joplin, but Lunatask isn't fully supported on mobile yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment