Backends¶
insta-dl talks to Instagram through a swappable backend. Pick the one that matches how you want to authenticate and what you're willing to pay (in dollars or in account-ban risk).
At a glance¶
| hiker (default) | aiograpi | |
|---|---|---|
| What it is | Client for the HikerAPI commercial proxy | Async fork of instagrapi (private API) |
| Authentication | API token (x-access-key header) |
Instagram username + password + 2FA |
| Cost | Paid per request, 100 free requests to start | Free |
| Account-ban risk | None — your Instagram account is never used | Real, mitigated by session reuse |
| Stability when Instagram changes APIs | High — managed proxy patches things upstream | Brittle — needs library updates |
| Private profiles | Whatever HikerAPI exposes | Anything your account can already see |
:feed, :saved, DMs |
Not exposed | Possible but not yet wired into the CLI |
| Setup time | 30 seconds | Few minutes (login, possibly 2FA, store session) |
| Status in insta-dl | Functional | Functional |
When to pick which¶
Use hiker if:
- You're building an automated archiver and don't want your Instagram account to get banned.
- You want it to just work and don't mind paying for stable APIs.
- You only need public data (profiles, posts, hashtags, public stories/highlights) — which is what most people need.
- You don't have an Instagram account, or don't want to use yours.
Use aiograpi if:
- You need to download content only your logged-in account can see (private profiles you follow, your own feed, your saved collection, DMs).
- You want zero ongoing cost and can tolerate occasional breakage when Instagram changes things.
- You're comfortable storing an Instagram session file locally.
hiker — setup¶
# 1. Get a token at https://hikerapi.com (100 free requests, no card)
export HIKERAPI_TOKEN='your_token_here'
# 2. Run
insta-dl instagram
You can also pass the token per-invocation: insta-dl --hiker-token 'TOKEN' instagram.
The hiker backend talks to https://api.hikerapi.com for metadata and to Instagram's CDN (*.cdninstagram.com, *.fbcdn.net) for media files. Downloads are HTTPS-only (HTTP redirects are rejected), capped at 500 MB per resource, and signed query tokens are stripped before metadata is written to disk.
hiker — what's exposed¶
| Capability | HikerAPI endpoint | insta-dl method |
|---|---|---|
| Profile by username | /v2/user/by/username |
get_profile() |
| Single post by shortcode | /v2/media/info/by/code |
get_post_by_shortcode() |
| User posts (paginated) | /v1/user/medias/chunk |
iter_user_posts() |
| User stories | /v2/user/stories |
iter_user_stories() |
| User highlights | /v2/user/highlights |
iter_user_highlights() |
| Highlight items | /v2/highlight/by/id |
iter_highlight_items() |
| Hashtag (recent) | /v2/hashtag/medias/recent |
iter_hashtag_posts() |
| Post comments (paginated) | /v2/media/comments |
iter_post_comments() |
aiograpi — setup¶
aiograpi and its transitive Rust dependencies (pydantic-core, orjson) are not pulled in by a bare pip install instagram-dl. Opt in explicitly:
Without the extra, selecting --backend aiograpi fails fast with a message telling you which extra to install. With the extra installed:
insta-dl --backend aiograpi \
--login YOUR_USERNAME \
--password YOUR_PASSWORD \
--session ~/.config/insta-dl/session.json \
instagram
The session file is created on the first successful login and reused after that. On subsequent runs you can drop --password and pass only --session — insta-dl loads the saved cookies and skips the login flow entirely. If the session has expired and you also passed --login/--password, it transparently re-logs in.
For 2FA, the aiograpi library supports interactive TOTP prompts during login. Once you've logged in successfully and dumped a session, future runs reuse it without re-prompting.
aiograpi — what's exposed¶
| Capability | aiograpi method | insta-dl method |
|---|---|---|
| Profile by username | user_info_by_username() |
get_profile() |
| Single post by shortcode | media_pk_from_code() + media_info() |
get_post_by_shortcode() |
| User posts (paginated) | user_medias_chunk() |
iter_user_posts() |
| User stories | user_stories() |
iter_user_stories() |
| User highlights | user_highlights() |
iter_user_highlights() |
| Highlight items | highlight_info() |
iter_highlight_items() |
| Hashtag (recent) | hashtag_medias_v1_chunk() |
iter_hashtag_posts() |
| Post comments (paginated) | media_comments_v1_chunk() |
iter_post_comments() |
Adding a third backend¶
Both backends implement the same InstagramBackend ABC (see Python API and Architecture). To add a third:
- Create
insta_dl/backends/<name>.pywith a class implementing every abstract method. - Map raw responses to DTOs in
insta_dl/backends/_<name>_map.py. - Wire it up in
insta_dl/backends/__init__.py:make_backend. - Add a
--backend <name>choice ininsta_dl/cli.py.
See CONTRIBUTING.md for the checklist (host allowlist, .part safety, byte budget, tests).