I’ve been using Gitlab for years to manage my notes. It is free, secure, resilient, trusted by thousands of companies. GitLab is based on git meaning zero effort synchronization with any git-based service or your local copy.
Recently I discovered Notion, which makes it so pleasant to edit content. And what made me comfortable moving all my notes to Notion is an “Export all workspace content” feature, which generates a decent quality markdown.
The only thing I was missing is a regular automatic backup. I did a bit of investigation on how Notion’s backup feature works and set up my own daily exports to GitLab. It’s been working fine for the last two weeks, so today I will show how you can set up your own in a couple of minutes.
Note: this method might not be the best if you embed a lot of large files in your workspace.
1. Register GitLab account
Go to https://gitlab.com/ and get a free account if you don’t have one yet, it should be enough to backup up to 10Gb of data.
Optional. If you want some extra security — set up 2FA.
2. Extract notion token and space id
This is probably the most complicated step. Since Notion doesn’t have API yet, we would need to mimic Notion behavior in our backup script. To do so we need to extract token_v2 and spaceId from the “Export all workspace content” request.
I will explain how to do it in Google Chrome:
- Open http://notion.so/, go to “Settings & Members” → “Settings”
- Open Chrome DevTools by pressing Command+Option+J (Mac) or Control+Shift+J (Windows, Linux, Chrome OS)
- Go to the Network tab, as shown on a screenshot below
- Enable “XHR” filter (1), clear console (2), start the export (3), select “enqueueTask” (4)
In the opened “Headers” tab you would need to scroll down until you see “cookie:” and a lot of text, in this text you need to identify a part, which looks like(5):
Where xxx is a very long sequence of letters and digits and can span multiple lines. Copy everything between “token_v2=” and “;” and save it somewhere. Label it NOTION_TOKEN_V2, we will need it later.
Now scroll to the very bottom and under the “Request Payload” section you will see something like (6):
Save the value inside quotes, label it NOTION_SPACE_ID.
3. Create push token in GitLab
In order to allow a script to update your backup, we need to generate a token with appropriate rights. On GitLab go to Settings → Access Tokens and fill the form as shown on the screenshot.
Once you press “Create Personal access token” you will see “Your new personal access token” only once, copy and save it, label it CI_PUSH_TOKEN, we will need it later.
4. Create a GitLab repository to store a backup
Create New Project, choose any “Project name” you like, make sure the “Private” box is selected, so only you can access your backup, click “Create Project”
5. Set up CI/CD script
Once you create a project you will be redirected to the empty project page. Click the “Set up CI/CD” button.
It will open an editor for the .gitlab-ci.yml file. Paste a script which I prepared for you: https://gitlab.com/aburtsev/notion-backup-script/-/raw/master/.gitlab-ci.yml
This script mimics the behavior of the Notion backup feature, but instead of downloading a zip file to your computer, it will upload it to your GitLab project.
Press “Commit changes”
6. Schedule a backup job
Once the script is ready, from the left-hand side menu select “CI / CD” → “Schedules”.
Press “New schedule”
That will open the “Schedule a new pipeline” form, let's go field by field.
- Description: anything you like (e.g Notion Backup)
- Interval pattern: when do you want to run a backup. For example, mine runs at 4 am daily. Please pick a random minute from 0 to 59 and an hour from 0 to 23 when you want to run the backup. For example, if you want it to run at 5:42 am you should put “42 5 * * *” in. Please don’t just copy-paste this value to make sure everyone doesn’t hit Notion servers at the same time. You might find this schedule editor helpful.
- Cron Timezone: just pick your timezone
- Target Brance: leave a master
- Variables: That’s the values we’ve been collecting so far, plus few constants:
NOTION_TOKEN_V2 paste token_v2 from step 2
NOTION_SPACE_ID paste spaceId from step 2
CI_PUSH_TOKEN paste token from step 3
TZ pick yours from https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
("TZ database name" column)
That’s it, now you can “Save pipeline schedule” and the new pipeline will appear in the list.
Now press the “play” button to run it manually and make sure it works. Wait a couple of minutes until the progress circle is green.
Optional. If you want to follow logs you can press a link in the “Last Pipeline” column and then select a running job.
Once a backup job is finished you can go to the project home page and notice a backup folder, you can go there and navigate through your contents, generated by Notion.
If you reached up to this point—congrats! You have your automated backups set up and they will run daily at the selected time. I hope it was helpful.
You are welcome to buy me a coffee if it was useful enough for your project, good luck!