I recently learned that Mint is shutting down, which is a bit of a bummer because I've been using them for 10 years as a way to keep an eye on my finances. The replacement service through Credit Karma looks feature incomplete and it will only preserve three years of history, which is a bit of a non-starter for me. I will most likely be looking for something else, but in the meantime, I've been looking for a way to preserve all my data, so I can take it with me.
The two types of data that are important to me are the transaction history and the balance history. The former is fairly straightforward to do through the web interface (though it has to be done in multiple parts since mint caps exports to 10k transactions), but the balance history is tricker. Under Trends > Net Worth, I can set the filters to a single account and export the history to CSV, but the data will only contain monthly balances. However, I noticed that Mint internally has daily balance history, because when I manually set the date range to any range of 44 days or less, the daily balances show up. This is impractical to do for every account manually, so I went to work writing a script to automate this.
Version 1: Bash Scripts
For my first attempt, I used the developer console to find the rest API calls and copied it as a curl command:
I took this command, piped it into jq to convert the data to CSV, and wrapped it in a bash loop over the data range. The end result looked something like this:
This generally worked, but it was a bit annoying to need to update my cookie whenever my Mint web session was logged out. It was also a bit slow, which could run into issues if Mint auto logs me out due to inactivity. So, I started looking at some other options.
Version 2: JavaScript
In the developer console, I noticed I could also copy the REST API network request as a JavaScript fetch() statement. I got an idea that perhaps I could write a little script that could be executed in the JavaScript console. The nice thing about that is that I don't need to manually update the cookie, because the browser automatically includes that when the request is sent. I can also do more advanced data processing and send queries in parallel. The end result was:
The script prints progress as it goes. For 10 years of data and 88 accounts, it takes about 12 minutes to run. When it finishes, it downloads a CSV file that looks something like:
Date
Membership Share
Money Mkt Advantage
Free Checking
...
2/19/2013
8007.6
5479.63
...
2/20/2013
8007.6
5479.63
...
2/21/2013
8007.6
479.63
...
...
...
...
...
..
11/6/2016
5216.34
0
3503.31
..
11/7/2016
5216.34
0
1567.27
..
...
...
...
...
..
(The blank entries for Membership Share are because that account did not exist until later, so there is no data).
How to Run this for Yourselves
For those of you interested in running this yourselves, I would urge caution regarding running code from strangers on the Internet, especially if you do not know how to read JavaScript for yourselves. Self XSS is a common tactic that scammers will use to take over your account. I have also only tested this on my Mint account and that of one other person, so no guarantees that this will work for you. If you understand the risks, here are the steps:
Open an incognito tab in a Chrome or Chromium based browser (I havwe tested on Microsoft Edge).
Login to your Mint account.
From any page on Mint, open up the developer console by right clicking and selecting "Inspect" (or Ctrl + Shift + I).
Find the "Console" tab.
Paste the JavaScript code from the previous section into the console and press Enter.
Look for messages such as Fetching account 1/88: Membership Share in the console to show up every 10-20 seconds, which show the progress of the script.
If you need to abort the script, just reload the page.
At the end, a message like Finished in 12.31635 minutes will be shown and mint_bal_history.csv will show up in your Downloads.
Update 2023-11-16: I noticed today that Monarch has built a browser plugin to download all the Mint data, including the daily balance history. That is probably a more robust option than what I posted here.