instagrapi

instagrapi vs instaloader: which Python Instagram library should you use?

Updated

TL;DR

instaloader and instagrapi solve overlapping but distinct problems. instaloader is a download-first tool: a Python library plus a polished CLI for archiving public profiles, posts, stories, and metadata to disk. If your job is “pull every photo from these 200 accounts and write JSON sidecars next to each one,” instaloader is the shorter path. instagrapi is a full client for the Instagram private mobile API: login with 2FA and challenge handling, posting photos, videos, reels and stories, sending DMs, walking hashtag and location feeds, with pydantic-typed responses for every endpoint. If you are writing a service or anything beyond read-only archival, reach for instagrapi. The rest of this guide goes into where each tool earns its place.

Project profiles

Both libraries are MIT-licensed, both are pure Python, both are maintained by independent open-source contributors with no commercial backer gating features. That matters: nothing in either project is held back behind a paid tier, and there is no risk of a vendor changing the license once you are bedded in.

instaloader has been around since 2016 and ships as a single CLI plus a library import. Its scope is deliberately narrow — download things from Instagram — and its surface reflects that focus. instagrapi has been actively maintained since 2020 and tracks Instagram’s private mobile API closely. Both projects publish releases regularly on PyPI and accept community pull requests; check each project’s changelog for the latest cadence before you commit, because Instagram’s surface shifts and the freshness of recent releases is a meaningful signal.

API surface

The two libraries overlap on read endpoints and diverge sharply on everything else. instaloader covers profile metadata, post downloads, hashtag and location feeds, and (when logged in) story downloads. instagrapi covers all of that plus the full write surface — uploads, DMs, comments, follows, story posting — along with typed models for every response. Below is the side-by-side.

Capabilityinstagrapiinstaloader
Public profile metadata
Post downloads
Story downloads✅ (logged-in)
Photo upload
Video / reel upload
Direct messages
2FA / challenge handlerpartial
Hashtag / location feeds
pydantic typed responses
Async API

For production work the dimensions that matter most are the ones where the libraries actually differ. Posting, DMs and reel uploads are instagrapi-only — there is no path to those endpoints via instaloader, by design. 2FA and challenge_required handling is also materially better in instagrapi: a challenge_code_handler callback and first-class TOTP/SMS support versus instaloader’s narrower login story. Typed responses are an instagrapi-only convenience; instaloader returns dicts and bespoke classes. Worth flagging plainly: neither library has a real async API. Both are sync-first, and that is a real limitation if you intend to fan out hundreds of concurrent calls — you will be reaching for threads or process pools either way.

Login behavior

Login is where these libraries differ in ways that show up on day three of a project, not day one. instagrapi exposes dump_settings(path) and load_settings(path) for persisting the device fingerprint and cookie jar, plus a challenge_code_handler callback that receives the challenge type (SMS, email, in-app) so your code can prompt the user, read from a queue, or fetch from your inbox programmatically. TOTP and SMS 2FA are both supported via verification_code= on login() or via the same handler pattern. The persistence model is explicit: you control the path, and the device fingerprint stays stable across runs, which is the part Instagram’s risk system actually cares about.

instaloader supports session save and restore through save_session_to_file / load_session_from_file, which is enough for an interactive CLI that runs as you. For accounts with 2FA enabled, login works but the flow is less ergonomic — there is no equivalent to challenge_code_handler for catching challenge_required mid-script and resolving it without restarting. If your account never sees a challenge, this rarely matters; if it does, you feel it.

When to pick instaloader

Three scenarios where instaloader is the better answer:

  1. Ad-hoc CLI archival of public profiles. You want to run instaloader profile_name once and walk away with a folder of JPEGs and .json.xz sidecars. The CLI is mature, the flags are well-documented, and there is nothing to set up beyond pip install.
  2. One-shot research downloads. A grad student grabbing 50 hashtags’ worth of public posts for a study, a journalist archiving a public account before it goes private. No login, no posting, no orchestration — just batch download with sensible defaults.
  3. Download-only with a small dependency surface. instaloader pulls in fewer transitive deps than instagrapi. If your container needs to stay lean and your job description ends at “save these photos,” that’s a real, if modest, win.

In all three cases you are buying a tool that does one job well and asks little in return.

When to pick instagrapi

Three scenarios where instagrapi is the right call:

  1. Building a service. You are running on a schedule, possibly for multiple users, possibly across multiple accounts. You need session reuse, typed responses you can pass to a queue, and an explicit challenge handler so a 2FA prompt at 3am does not crash the worker. instagrapi is built for this; instaloader is not.
  2. Writes — DMs, comments, posts, stories. Anything that mutates state on Instagram lives behind the private API write surface, and instagrapi is the only one of the two libraries that exposes it. Photo uploads, reel uploads, story posting, sending and reading DMs, leaving comments — none of that is reachable from instaloader.
  3. Typed integration into FastAPI or Django. instagrapi returns pydantic models, which slot directly into FastAPI request/response types and serialize cleanly. Editor autocomplete actually works on media.like_count and user.follower_count. With instaloader, you are passing dicts around and writing your own validators.

If your project is going to live longer than a weekend, the second-day costs of instagrapi (session storage, proxy rotation, challenge handling) are worth paying.

Wrapping up

If your job ends at downloading public content, instaloader is the shorter path; if it includes posting, DMs, multi-account work, or anything beyond read-only archival, instagrapi is the only realistic choice. For download-only scraping pipelines, the scraper guide walks through the instagrapi setup end to end.

Related guides

Frequently asked

Is instagrapi a fork of instaloader?

No. They are independent projects with different goals. instaloader is a download-focused CLI/library; instagrapi is a full mobile-API client with login, posting, DMs, and stories.

Can I use both in one project?

Technically yes — they don't share state — but it's rare to want to. If you need posting or DMs, instagrapi covers downloading too, so a single dependency is simpler.

Which one is faster?

For pure profile downloads on a single account, instaloader's optimized batch routines are competitive. For everything else (login flows, multi-account orchestration, posting, real-time scraping), instagrapi is the more practical tool.

Does instaloader support 2FA and challenge_required?

instaloader has limited login support and no robust challenge-resolution callbacks. instagrapi exposes a `challenge_code_handler` callback for SMS/email challenges and supports TOTP/SMS 2FA flows out of the box.

Skip the infra?

Async CLI to download Instagram, powered by HikerAPI (no-ban backend).

Try insta-dl → Full comparison
More from the team