Moving from Instagram to Mastodon

For some time I’ve wanted to move the Instagram account of to my Mastodon instance and delete the instagram account. Earlier this year I did just that and I’d like to share my method in case someone would want to move their account(s). Note: while PixelFed is better suited to hosting media centered content, I didn’t feel like setting up a PixelFed instance so I stuck with Mastodon.

Exporting Instagram data

Instagram offers a Data Download Tool. Its output is an archive containing all the posts, replies, stories you sent on Instagram. For processing the output in a computer program, be sure to select a JSON export.

The data download’s archive looks like this:

 ├── account_information
 ├── ads_and_content
 ├── autofill_information
 ├── comments
 ├── comments_settings
 ├── contacts
 ├── content
 ├── device_information
 ├── events
 ├── followers_and_following
 ├── fundraisers
 ├── guides
 ├── information_about_you
 ├── likes
 ├── login_and_account_creation
 ├── media
 ├── messages
 ├── recent_searches
 ├── saved
 ├── shopping
 ├── story_sticker_interactions
 └── your_topics

The content folder contains a posts_1.json file with, in my case, around 125 posts. The JSON post entries refer to media in the media/posts folder.

Importing into Mastodon

The goal is to import every Instagram post as a toot on a freshly created account on my Mastodon instance, keeping the chronological order (as well as the dates) and the media from the posts. Locations were deemed too cumbersome to keep, as geotagging toots is a feature request from 2016.

Given the requirement to backdate toots, using the toot API isn’t feasible as it only supports immediately posting toots and scheduling toots in the future. Instead of extending the toot API, I chose to create an ig_import CLI admin script that runs as a one-time job on the IG data archive. The script is available as commit 73b035b2 in my mastodon fork and this patch file. Note this patch is tested against mastodon v3.3.0, using it with a different release might not work.

Prior to running the script you should create a new user (even if just for testing, before importing to your actual account). The password will be printed to stdout.

RAILS_ENV=production ./bin/tootctl accounts create \
  <my-account> \
  --email <my-account> \

You can start the import as follows. Ensure that the entire IG archive is available and replace <my-account> with your mastodon account name:

RAILS_ENV=production bin/tootctl ig_import import ig-json/content/posts_1.json

You should see stdout output similar to Created status with ID xxx. The script completed successfully if its return code is 0 (verify with echo $? right after the script completed).

Chunking long posts

I discovered that some of my IG posts were too long to fit into a single toot (500 characters limit on most Mastodon instances), so some posts had to be split up into multiple toots. Posting all the media on the first toot and posting subsequent toots as replies, it doesn’t look too bad (see screenshot below). It does make the profile page a bit longer however.

The result

Long posts are split into multiple toots.

All in all, I’m satisfied with the outcome. The toot view doesn’t indicate that more than four media files are attached to a toot though. Also, as this is implemented as an admin script it is cumbersome to setup, requiring admin and CLI access to the Mastodon instance. Suggestions on making this more accessible are welcomed.


  1. I would like to import albums per name to libranet feduniverse as image hoster…. can you make a related app for that vause fed up with FB? I have more than 1000 albums on FB…

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.