Sync Instagram saved posts to Raindrop.io bookmarks — either from a JSON data export or directly via the Instagram API.
Follows the same CLI and configuration patterns as x2raindrop-cli.
- Sync saved Instagram posts directly via the Instagram API.
- Import from Instagram JSON exports (
saved_posts.json). - Map Instagram collections to Raindrop sub-collections automatically.
- Skip duplicate links by default to avoid duplicate Raindrops.
- Add custom tags and optional collection targeting during import.
- Preview changes with dry-run mode before creating bookmarks.
- Use batch or one-by-one import modes.
- Support Instagram session reuse and optional TOTP-based 2FA login.
# Using uv (recommended)
uv tool install ig2raindrop-cli
# Or with pip
pip install ig2raindrop-cliAfter installation, run the CLI with:
ig2raindrop --version
ig2raindrop --helpIf you installed with uv tool, you can also run it without a global install:
uvx ig2raindrop --help# Clone and install with uv
git clone https://github.com/dotWee/py-ig2raindrop-cli.git
cd ig2raindrop-cli
uv sync --all-groups# 1. Create a config file
ig2raindrop config init
# 2. Edit config.toml with your credentials
# - Set your Instagram username/password
# - Set your Raindrop.io API token
# 3. Login to Instagram
ig2raindrop ig login
# 4. Sync saved posts to Raindrop.io
ig2raindrop syncSettings are loaded from (in order of priority):
- CLI flags — highest priority
- Environment variables — prefixed with
IG_,RAINDROP_, orSYNC_ - Config file —
config.toml(or path via--config/-c) - Defaults — built-in fallbacks
Create a default config with ig2raindrop config init:
log_level = "INFO"
[instagram]
username = ""
password = ""
totp_seed = ""
[raindrop]
token = "YOUR_RAINDROP_TOKEN"
[sync]
collection_id = 0
collection_title = ""
ig_collection = ""
tags = ["instagram", "saved"]
max_count = 0
no_batch = false
map_ig_collections = false
dry_run = false| Variable | Description |
|---|---|
IG_USERNAME |
Instagram username |
IG_PASSWORD |
Instagram password |
IG_TOTP_SEED |
TOTP seed for automatic 2FA (base32) |
RAINDROP_TOKEN |
Raindrop.io API test token |
SYNC_COLLECTION_ID |
Target Raindrop collection ID |
SYNC_TAGS |
Comma-separated tags |
SYNC_MAX_COUNT |
Maximum posts to fetch |
# Sync all saved posts using config file
ig2raindrop sync
# Sync a specific Instagram collection
ig2raindrop sync --ig-collection "Travel"
# Limit to 50 posts
ig2raindrop sync --max 50
# Mirror Instagram collections into Raindrop sub-collections
# under the configured parent `collection_id`
ig2raindrop sync --map-ig-collections
# Dry run (preview only)
ig2raindrop sync --dry-run
# Use a custom config file
ig2raindrop sync -c /path/to/config.tomlBy default, imports skip duplicates so links that already exist in the target Raindrop collection are not added again.
When map_ig_collections is enabled (via config or --map-ig-collections),
saved posts are grouped by their Instagram collection name and routed into
sub-collections under the configured parent collection_id:
- Existing sub-collections whose title matches an Instagram collection name are reused.
- Missing sub-collections are created automatically under the parent.
- Saved posts that are not in any Instagram collection land directly in the parent collection.
A valid sync.collection_id is required for this mode; otherwise the sync
falls back to a flat import.
# Import from an Instagram data export file
ig2raindrop import-file saved_posts.json
# Into a specific Raindrop collection
ig2raindrop import-file saved_posts.json --collection 12345
# Custom tags
ig2raindrop import-file saved_posts.json --tags "instagram,bookmarks"
# Dry run
ig2raindrop import-file saved_posts.json --dry-run# Authenticate with Instagram
ig2raindrop ig login
# With a one-time 2FA code
ig2raindrop ig login --2fa-code 123456
# Check authentication status
ig2raindrop ig status
# Clear stored session
ig2raindrop ig logout
# List saved collections
ig2raindrop ig collections# List all Raindrop.io collections
ig2raindrop raindrop collections# Create a default config.toml
ig2raindrop config init
# Show current configuration (secrets masked)
ig2raindrop config show
# Show the default config file path
ig2raindrop config path| Option | Short | Description |
|---|---|---|
--version |
-v |
Show version and exit |
--config |
-c |
Path to config file (on most commands) |
-
Raindrop.io API token — Create a test token at Raindrop.io App Settings.
-
One of the following sources:
- Instagram data export — Request your data from Instagram (Settings → Your Activity → Download Your Information). Select JSON format. The file you need is
saved_posts.json. - Instagram account credentials — For
syncandigcommands that use the Instagram API.
- Instagram data export — Request your data from Instagram (Settings → Your Activity → Download Your Information). Select JSON format. The file you need is
# Install dev dependencies
uv sync --all-groups
# Run tests
uv run pytest
# Run tests with coverage
uv run pytest --tb=short -qThe release workflow runs when a semantic version tag is pushed (for example v1.0.1).
It will:
- create a GitHub release with generated notes
- build source and wheel distributions
- publish packages to PyPI
- publish packages to GitHub Packages (Python registry)
- upload built artifacts to the GitHub release
- build and publish multi-arch Docker images to GHCR
# 1) Ensure all checks pass locally
uv sync --locked --all-groups
uv run ruff check src tests
uv run ruff format --check src tests
uv run pytest
# 2) Commit release changes (including version bump)
git add .
git commit -m "release: prepare v1.0.1"
# 3) Create and push tag
git tag v1.0.1
git push origin main --tagsCopyright (c) 2026 Lukas 'dotWee' Wolfsteiner lukas@wolfsteiner.media
Licensed under the Do What The Fuck You Want To Public License. See the LICENSE file for details.