Export Most of Your Data from Todoist with Nushell

Editor’s Note: Fixed some typos and the list numbering not working. See diff
I have recently changed how I use Todoist, but before doing so, I exported all (okay, I think it was more like most of) my data.
Since I exported all of my data once, I now want to export and back up my Todoist data regularly.
Here is how to get most of your data from Todoist using Nushell:
I’m going to assume you have Nushell installed. If not, install Nushell.
I would probably recommend doing so in Homebrew:
brew install nushell
But I’m not sure, because I installed Nushell before I realized I should be installing as much of my software through a package manager as possible.
-
Get your API key from Todoist.
Be aware that this API key has, as far as I can tell, admin-level permissions for your Todoist account.
Whatever you can do through the GUI, the API key allows you authorization to do. You can only have 1 API key at a time. You can’t restrict the API key in any way.
You can revoke the API key by clicking the
Issue a new API token
button (on the same page). But that is going to log you out of all Todoist sessions, which is super annoying if you are logged into Todoist in Chrome, your phone and have a bunch of scripts and widgets using that API key. -
Set the API key as the
TODOIST_API_TOKEN
environment variable -
Copy this in as
sync.nu
:#! /usr/bin/env nu use std log const COMPLETED_TASKS_MAX_LIMIT = 200 const ARCHIVED_SECTIONS_MAX_LIMIT = 100 def get-sync-data [] { log info "Getting sync data" let result = http post --headers [ "Authorization" $"Bearer ($env.TODOIST_API_TOKEN)" ] --content-type "application/x-www-form-urlencoded" https://api.todoist.com/sync/v9/sync { sync_token: "*", resource_types: '["all"]' } $result } def get-completed-tasks-with-offset [offset: int] { log info $"Getting completed tasks with offset: ($offset)" const annotate_notes = true const annotate_items = true const limit = $COMPLETED_TASKS_MAX_LIMIT let url = $"https://api.todoist.com/sync/v9/completed/get_all?limit=($limit)&annotate_notes=($annotate_notes)&annotate_items=($annotate_items)&offset=($offset)" let result = http post --headers [ "Authorization" $"Bearer ($env.TODOIST_API_TOKEN)" ] --content-type "application/x-www-form-urlencoded" $url { sync_token: "*", resource_types: '["all"]' } $result } def get-completed-tasks [] { mut results = [] mut offset = 0 while true { let result = get-completed-tasks-with-offset $offset $results = $results | append $result $offset += $COMPLETED_TASKS_MAX_LIMIT if ($result | get items | is-empty) { break } } $results } def get-stats [] { log info "Getting stats" let result = http get --headers [ "Authorization" $"Bearer ($env.TODOIST_API_TOKEN)" ] https://api.todoist.com/sync/v9/completed/get_stats $result }
-
Copy this in as
runner.nu
:#! /usr/bin/env nu const RFC3339_FORMAT = "%Y-%m-%dT%H:%M:%S%z" source ./sync.nu let sync_data = get-sync-data let completed_tasks = get-completed-tasks let completed_tasks_stats = get-stats let endpoints = { "sync": $sync_data, "completed/get_all": $completed_tasks, "completed/get_stats": $completed_tasks_stats } let metadata = { "created_at": (date now | format date $RFC3339_FORMAT), } let result = {endpoints: $endpoints, metadata: $metadata} $result | save -f todoist-export.json
-
Run
nu runner.nu
in your terminal.You should get a file called
todoist-export.json
in the same directory as the script.