instaloader returns 401 "Please wait a few minutes". What now?
That 401 is Instagram telling your IP or session to slow down. Waiting clears it once. Then it returns sooner, and eventually a login wall or a ban. instaloader is not broken. Instagram changed the rules for logged-out and scripted traffic.
If you only need public profiles, posts, and comments, stop reading Instagram yourself. Call an API that does it. Openhandle returns the same fields, absorbs Instagram changes, and never asks you for an Instagram account.
Checked September 2026 · request and response run against the API · no affiliate links
curl "https://api.openhandle.dev/v1/instagram/profiles/@northstar_forge_test" \
-H "Authorization: Bearer $OPENHANDLE_API_KEY"import { OpenHandle } from '@openhandle/sdk';
const openhandle = new OpenHandle({ apiKey: process.env.OPENHANDLE_API_KEY! });
const response = await openhandle.instagram.profile('northstar_forge_test').get();
console.log(response.data.metrics.followers); // 48291{
"platform": "instagram",
"resource": "profile",
"capturedAt": "2026-09-18T10:05:40Z",
"source": "live",
"data": {
"id": "910000000001",
"handle": "northstar_forge_test",
"displayName": "Northstar Forge",
"isVerified": true,
"isPrivate": false,
"metrics": { "followers": 48291, "following": 318, "posts": 5 }
}
}Trimmed to the fields an instaloader Profile object gives you. The full profile has bio, links, avatar, business fields, and more. The example is a Test account, so you can run it on a free Test key.
What people try, and what happens
- —Sleep longer between requests. Works for a small script. Fails the moment you need more than a few hundred profiles a day.
- —Log in with a session file. Raises the limit for a while. Then the account gets a checkpoint or a ban. Using a real person’s account for this breaks Instagram’s terms.
- —Rotate proxies. Costs money, needs upkeep, and Instagram flags data center ranges quickly. You are now running infrastructure, not a script.
- —Pin an older instaloader version. Does nothing. The limit is on Instagram’s side, not in the library.
Map instaloader to the API
| instaloader | Openhandle |
|---|---|
Profile.from_username(L.context, name) | GET /v1/instagram/profiles/@name |
profile.followers | data.metrics.followers |
profile.get_posts() | GET /v1/instagram/profiles/@name/posts, one page per request |
post.get_comments() | GET /v1/instagram/posts/{id}/comments |
Post.from_shortcode(...) | POST /v1/urls/fetch with the post URL |
| Downloading media files | Media URLs served from our CDN. They do not expire. |
What stays the same
Public accounts only. A private account returns PROFILE_PRIVATE, the same wall instaloader hits without a following session. Hidden like counts come back as null. We never write a zero for a number Instagram hid.
When this does not work
The answers you will see instead of a 401.
| Situation | Status | Code |
|---|---|---|
| The account is private | 403 | PROFILE_PRIVATE |
| The account is deleted, banned, or never existed | 404 | PROFILE_NOT_FOUND |
| You passed your own per-second limit | 429 | RATE_LIMITED |
{
"error": {
"code": "RATE_LIMITED",
"message": "Too many requests. Retry after the Retry-After header.",
"requestId": "req_01j8…",
"retryable": true
}
}Rate limits are per key, 10 requests per second, and never billed. Higher on request. Every new workspace starts with 100 free live requests, no card needed.
Read next
More Instagram questions
Send your agent ahead.
Paste the prompt into your agent and it sets everything up. Or come yourself, it takes five minutes.