Import Instagram photos to Pixelfed via Mastodon-compatible API
Python 100.0%
Other 0.1%
5 2 0

Clone this repository

https://tangled.org/mauvehed.com/import-pixelfed https://tangled.org/did:plc:ds34d7navj6bkch53it5yjkc/import-pixelfed
git@gitfed.mauve.haus:mauvehed.com/import-pixelfed git@gitfed.mauve.haus:did:plc:ds34d7navj6bkch53it5yjkc/import-pixelfed

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

import-pixelfed#

Import Instagram photos from a data export into Pixelfed via the Mastodon-compatible API.

Features#

  • Parses Instagram data export JSON
  • Imports posts in chronological order (oldest first)
  • Strips GPS/location EXIF data from images before upload
  • Prepends original post date to captions
  • Supports multi-image carousel posts
  • Photos only (skips videos and reels)
  • Posts as unlisted visibility
  • Progress tracking with resume capability
  • Rate limiting to avoid server hammering
  • Dry run mode for testing

Requirements#

  • Python 3.12+
  • uv package manager
  • Instagram data export (request from Instagram settings)
  • Pixelfed account with Personal Access Token

Installation#

git clone https://git.mauve.haus/mauvehed/import-pixelfed.git
cd import-pixelfed
uv sync

Configuration#

Copy the example environment file and fill in your values:

cp .env.example .env

Environment variables:

Variable Description Default
PIXELFED_HOST Your Pixelfed instance hostname pixelfed.social
ACCESS_TOKEN Personal Access Token from Pixelfed (required)
EXPORT_PATH Path to Instagram export folder ./ig_export
RATE_LIMIT_DELAY Seconds between posts 5
DRY_RUN Set to 1 to test without uploading (unset)

Getting a Pixelfed Access Token#

  1. Log into your Pixelfed instance
  2. Go to Settings > Applications > Personal Access Tokens
  3. Create a new token with write scope
  4. Copy the token to your .env file

Instagram Export Structure#

Place your Instagram data export in the ig_export/ directory:

ig_export/
├── your_instagram_activity/media/
│   └── posts_1.json          # Posts metadata
└── media/
    └── posts/YYYYMM/*.jpg    # Post images

Usage#

Test parsing without uploading:

DRY_RUN=1 uv run import_to_pixelfed.py

Run Import#

uv run import_to_pixelfed.py

The script will:

  1. Load posts from posts_1.json
  2. Sort by date (oldest first)
  3. Skip video posts
  4. Strip GPS data from images
  5. Upload media and create posts
  6. Save progress to import_progress.json

Resuming Interrupted Imports#

The script automatically tracks progress. If interrupted, simply run it again and it will skip already-imported posts.

Caption Format#

Since the Mastodon API does not support backdating posts, the original date is prepended to each caption:

Originally posted: 2019-07-15

Beach day! #summer

Captions are truncated at 500 characters if needed.

Error Handling#

  • Retries on rate limits (429) and server errors (500, 502, 503)
  • Failed posts are logged to import_failed.json for manual review
  • Import can be resumed after fixing issues