Download Instagram profile media (reels MP4, photos JPG, full carousel multi-image JPG) via sessionid (instagrapi), Apify dataset fallback, or interactive se...
Design & media
Instagram Downloader
Try itDownload Instagram profile media (reels MP4, photos JPG, full carousel multi-image JPG) via sessionid (instagrapi), Apify dataset fallback, or interactive se...
What it does
Download Instagram profile media (reels MP4, photos JPG, full carousel multi-image JPG) via sessionid (instagrapi), Apify dataset fallback, or interactive setup wizard. No password sharing required.
The skill document
Instagram Downloader Skill v2.2
Purpose: Download all media (reels MP4, carousels with ALL images, photos JPG) from an Instagram profile. Three operation modes: sessionid (cookie, recommended), Apify (no login, limited), setup wizard (Playwright browser).
⚠ 2026-07-07:
--loginmode is BROKEN. Meta deprecated the instagrapi login endpoint server-side. The--login,--password, and--totpflags exist but return 404. Use--setup(Playwright) or a manual--sessionidcookie instead.
Operation Modes
graph LR
subgraph Sessionid[Mode 1: Sessionid 🥇]
direction TB
S1[sessionid cookie] --> S2[login_by_sessionid]
S2 --> S3[user_id_from_username]
S3 --> S4[user_medias → ALL posts]
S4 --> S5[photo_download / video_download]
S5 --> S6[📁 YYYY-MM-DD/shortcode/]
end
subgraph Apify[Mode 2: Apify]
direction TB
A1[Apify Actor Dataset] --> A2[toon-file or --dataset API]
A2 --> A3{GQL available?}
A3 -->|Yes <4w| A4[✅ All carousel images]
A3 -->|No >4w| A5[❌ First image only]
end
subgraph Setup[Mode 3: Setup Wizard]
direction TB
U1[--setup flag] --> U2[Playwright Chromium]
U2 --> U3[User logs in]
U3 --> U4[Extract sessionid]
U4 --> U5[💾 Save to config.json]
end
Mode Comparison
| Aspect | Sessionid 🥇 | Apify (legacy) | Setup Wizard |
|---|---|---|---|
| Authentication | Cookie sessionid | None | Playwright browser |
| All posts (any date) | ✅ Yes | ✅ Yes | N/A (setup only) |
| Carousels: ALL images | ✅ Yes | ❌ 1st image only (old posts) | N/A |
| Carousels: recent only | ✅ Yes | ✅ GQL enhancement | N/A |
| Private profiles | ✅ (if you follow) | ❌ | N/A |
| No watermark reels | ✅ Yes | ✅ Yes (Apify) | N/A |
| Session persistence | ✅ config.json | N/A | ✅ config.json |
| Setup time | 1 min (first time) | 5 min (Apify account) | 30s (one-time) |
| Cost | $0 | ~$0.03/run | $0 |
Architecture
Credential Resolution Priority
The script auto-detects credentials in this order:
--sessionidCLI flag — one-shot session cookie (highest priority)SESSIONIDenvironment variable — for CI/automation- Config file (
~/.ig-downloader/config.json) — persistent, set by--setup - Chrome cookies — automatic extraction from browser SQLite (if logged in)
When no sessionid is found → falls to --setup (interactive) or Apify mode
(if dataset provided).
⚠ The
--loginmode (and itssettings.jsonpersistence) is BROKEN. Meta deprecated the login endpoint. All auth must use sessionid or --setup.
Mode 1: Sessionid (Recommended)
flowchart LR
COOKIE[sessionid cookie] --> LOGIN[login_by_sessionid]
LOGIN --> UID[user_id_from_username]
UID --> MEDIAS[user_mediasamount=0 → ALL posts]
MEDIAS --> TYPE{media_type}
TYPE -->|1: Photo| PHOTO[photo_download → .jpg]
TYPE -->|2: Video| REEL[video_download → .mp4]
TYPE -->|8: Carousel| CAR[media_info → resources[]]
CAR --> IMG1[_01.jpg]
CAR --> IMG2[_02.jpg]
CAR --> IMGN[_0N.jpg]
PHOTO --> DIR[📁 YYYY-MM-DD/shortcode/]
REEL --> DIR
IMG1 --> DIR
DIR --> INFO[+ post_info.txt]
Mode 2: Apify (Fallback)
Same as v1.x: Apify Actor → dataset → toon file → download (with GQL carousel enhancement for recent posts).
Interactive Setup
flowchart TD
A[Run: ig-downloader --setup] --> B{Playwright installed?}
B -->|Yes| C[Launch Chromium browser]
C --> D[Navigate to instagram.com]
D --> E[User logs in]
E --> F[Poll context.cookies every 3s]
F --> G{sessionid detected?}
G -->|No| F
G -->|Yes| H[Save to config.json]
H --> I[Close browser ✅]
B -->|No| J{Chrome DB accessible?}
J -->|Yes| K[DPAPI + AES-GCM decrypt]
K --> L{File locked?}
L -->|No| M[Extract sessionid]
L -->|Yes| J
M --> H
J -->|No| N[Prompt user: paste sessionid manually]
N --> O[Save to config.json]
O --> I
Prerequisites
- Python 3.7+
instagrapi >= 2.0.0:pip install instagrapirequests:pip install requests- Chrome (optional, for interactive setup and cookie extraction)
- Apify account (free tier, only needed for Apify legacy mode)
Getting the Sessionid Cookie
Method A: Manual (1 minute)
- Open Chrome, go to
https://www.instagram.com - Log in to Instagram
- Press F12 → Application → Cookies →
www.instagram.com - Find
sessionid— copy its value - Run:
python instagram_downloader.py -u username --sessionid "YOUR_SESSIONID"
Method B: Interactive Setup (recommended)
python instagram_downloader.py --setup
This opens Instagram in your browser. Log in, and the script automatically detects the sessionid cookie, saves it to ~/.ig-downloader/config.json, and exits. After that, no --sessionid flag needed.
Method C: Environment Variable
set SESSIONID=YOUR_SESSIONID
python instagram_downloader.py -u username
Workflow
Sessionid Mode (Recommended, Full Access)
# One-time setup (Playwright browser → logs in → saves cookie)
python instagram_downloader.py --setup
# Then just download — sessionid auto-loaded from config
python instagram_downloader.py -u username -o ./downloads
# Or pass cookie directly (one-shot, no config needed)
python instagram_downloader.py -u username --sessionid "1234..." -o ./downloads
Apify Mode (No Login)
# Via MCP
await mcp_call-actor({ actor: "unseenuser/IG-posts", input: { usernames: ["username"] } })
await mcp_get-dataset-items({ datasetId: "", limit: 999, clean: true })
# Then download
python instagram_downloader.py --toon-file ./data.txt \
-u username \
--date-start YYYY-MM-DD --date-end YYYY-MM-DD \
-o ./instagram_downloads
Script Reference
Location: instagram_downloader.py (same directory)
Command-Line Options
Mode Selection (auto-detected in order: login → sessionid → Apify → setup)
| Option | Description |
|---|---|
--sessionid STR | Instagram sessionid cookie (one-shot, overrides config/env). Recommended auth method. |
--setup | Interactive setup: Playwright → Chrome → manual paste. Saves to config. |
--login | ⚠ BROKEN — Meta deprecated the endpoint. Do NOT use. |
--password STR | ⚠ BROKEN — part of --login mode. |
--totp CODE | ⚠ BROKEN — part of --login mode. |
--setup | Interactive setup: opens browser, polls for login, saves sessionid to config. |
--dataset ID | Apify dataset ID (legacy, no login). |
--api-token KEY | Apify API token (required with --dataset). |
--toon-file PATH | Apify dataset exported as JSON/YAML. |
Files & Target
| Option | Description |
|---|---|
-u / --username HANDLE | Target Instagram handle (required for login/sessionid/setup). |
-o / --output DIR | Output directory (default: ./instagram_downloads). |
--flat | Flatten: single folder instead of YYYY-MM-DD/shortcode/. |
Filters (Apify mode only; login/sessionid modes download ALL posts)
| Option | Description |
|---|---|
--date-start YYYY-MM-DD | Earliest post date (inclusive). |
--date-end YYYY-MM-DD | Latest post date (inclusive). |
--type {reel,carousel,photo,all} | Filter by post type (default: all). |
--own-only | Only posts authored by --username. |
--mentions-only | Only posts from other accounts mentioning --username. |
Misc
| Option | Description |
|---|---|
--no-verify | Skip SSL verification (not recommended). |
--version | Show version and exit. |
--help | Show help message. |
Default Output Structure
instagram_downloads/
└── YYYY-MM-DD/
├── / # Reel
│ ├── .mp4
│ ├── .jpg # Thumbnail
│ └── post_info.txt
├── / # Photo
│ ├── .jpg
│ └── post_info.txt
└── / # Carousel
├── .jpg # First image (cl.photo_download)
├── _02.jpg # Image 2/N (from media_info)
├── _03.jpg # Image 3/N
├── ...
└── post_info.txt
Sessionid Under the Hood
Cookie Extraction
The --setup flow:
- Opens
https://www.instagram.comin the default browser viawebbrowser.open() - Polls the Chrome cookie SQLite database every 3 seconds
- Reads cookies using
sqlite3+ DPAPI key decryption (AES-GCM with no-authentication-tag) - Once
sessionidis detected, saves to~/.ig-downloader/config.json - Closes automatically
Media Fetching
user_id_from_username()→ numeric user IDuser_medias(user_id, amount=0)→ ALL media items (amount=0 means unlimited)- Each
Mediaobject has:pk,code(shortcode),media_type(1=photo, 2=video, 8=carousel),taken_at(datetime) - Carousels:
media_info(pk)returnscarousel_media[]with all resources - Downloads via
photo_download()/video_download()with proper auth
Config Storage
{
"sessionid": "YOUR_SESSIONID_COOKIE",
"created_at": "2026-07-07T22:00:00"
}
Location: ~/.ig-downloader/config.json
Examples
Sessionid mode (from config, simplest)
# After running --setup once
python instagram_downloader.py -u username -o ./downloads
Sessionid mode (direct flag)
python instagram_downloader.py \
-u username \
--sessionid "1234567890%3Aabcdef" \
-o ./downloads
Sessionid mode (environment variable)
set SESSIONID=1234567890%3Aabcdef
python instagram_downloader.py -u username -o ./downloads
Setup wizard (first time only)
python instagram_downloader.py --setup
Apify mode (toon file, with filters)
python instagram_downloader.py \
--toon-file ./data.txt \
-u username \
--type reel \
--date-start YYYY-MM-DD \
--date-end YYYY-MM-DD \
-o ./reels_only
Apify mode (API token)
python instagram_downloader.py \
--dataset \
--api-token apify_api_xxx \
-u username \
-o ./downloads
Troubleshooting
| Problem | Solution |
|---|---|
| "No instagrapi" | pip install instagrapi |
| Login fails | Check username/password. For 2FA, provide --totp CODE. For challenge, check terminal for SMS/email prompt. |
| "Login required" in sessionid mode | sessionid expired. Re-run --setup to get a fresh one. |
| "No sessionid found" | Run --setup or pass --sessionid directly. |
| Chrome cookie extraction fails | Use --sessionid flag with manual cookie from DevTools. |
| 403 on fbcdn.net | Use login/sessionid mode (instagrapi handles auth). |
| Apify returns 403 | CDN URL expired → re-run the Actor. |
| GQL timeout | Old post > 4 weeks → falls back to Apify thumbnail. |
| No items in sessionid mode | Check username; profile may be private and sessionid may not follow it. |
| ModuleNotFoundError: No module named 'win32crypt' | Auto-detected; falls back to manual --sessionid flag. |
| "No items parsed" in toon mode | Toon format may differ → try --dataset API mode. |
Known Issues
1. Sessionid Expiration
Instagram session cookies expire after some time (days-weeks). When this happens, re-run --setup or pass a fresh --sessionid. Login mode avoids this via saved sessions + auto-reload.
2. Login Challenge Detection
Instagram may trigger a challenge (SMS/email code) on first login from a new IP. The script detects this and prompts you interactively. After the first successful login, the saved session prevents future challenges.
3. Chrome DPAPI Decryption
Cookie extraction uses Windows DPAPI + AES-GCM. Works with Chrome's latest cookie encryption (no-authentication-tag variant). If Chrome updates its format, extraction may break.
4. Private Profiles
Login/sessionid modes can only download profiles that the logged-in user follows. For private profiles you don't follow, Apify mode with unseenuser/IG-posts may work (the actor runs its own session).
5. Carousel GQL Limit (Apify mode)
GQL enhancement works only for recent posts (< 4 weeks). Older posts get single thumbnail. Login/sessionid modes avoid this entirely.
6. CDN URL Expiry (Apify mode)
Apify URLs expire after hours. Download soon after fetching. Login/sessionid modes avoid this entirely.
Changelog
| Version | Date | Changes |
|---|---|---|
| 2.1.0 | 2026-07 | Login mode: --login with password prompt, 2FA (--totp), challenge handler, saved session persistence via dump_settings() |
| 2.0.0 | 2026-07 | Sessionid mode with instagrapi full access; interactive setup wizard; Chrome cookie extraction; config management; 3-mode architecture |
| 1.1.0 | 2026-07 | instagrapi GQL hybrid for carousel enhancement; --no-instagrapi flag |
| 1.0.0 | 2026-07 | Initial Apify-based release |
Instagram Downloader Skill v2.2.0 — Sessionid + Apify + Playwright setup. Zero compromises.
Related skills
Collect Instagram Profiles data and return results
Scrapes Instagram profile statistics and recent posts for any list of accounts using apidojo's Instagram scraper on Apify. Triggers when the user asks to: get Instagram profile data for an account, fetch follower count and post count for Instagram users, scrape Instagram bio and stats in bulk, export Instagram account metadata, check profile information for a list of Instagram handles, or get engagement data from Instagram profiles. Returns username, follower count, following count, post count, bio, and recent post metrics. Ideal for influencer vetting, brand research, and list enrichment.
Scrapes Instagram posts for any hashtag using apidojo's Instagram scraper on Apify. Triggers when the user asks to: get Instagram posts for a hashtag, scrape Instagram content by tag, export Instagram post data for a keyword or topic, fetch posts under an Instagram challenge or trend, collect Instagram media for a specific tag, or download Instagram post metadata by hashtag. Returns post URL, caption, like count, comment count, author handle, and timestamp per post. Ideal for trend analysts, UGC collectors, and social media researchers.
Extracts Instagram user profiles, followers, and following lists using apidojo's Instagram User Scraper on Apify. Triggers when the user asks to: find Instagram users by keyword or name, get follower lists for Instagram accounts, get following lists for Instagram accounts, export Instagram profile data in bulk, fetch public email addresses from Instagram business profiles, search for Instagram users by username or handle, or build a dataset of Instagram account metadata. Returns username, follower count, bio, post count, verification status, public email, and more. Ideal for influencer researchers, outreach teams, and competitive intelligence analysts.
Researches Instagram profiles, posts, and Reels via the Crawlora API, returning clean JSON. Use when the user wants a public Instagram profile's stats, a specific post's media/engagement, or a user's Reels feed — instead of scraping the app.