Blog / Risk and compliance
Private Instagram API: Meaning and Limits
By the InScrape API team · Published 2026-09-02 · 6 min read

Two completely different people search for "private Instagram API" and neither of them knows the other exists.
The first is a developer who has found a GitHub library described as a private API wrapper and wants to know what that means: the undocumented, unversioned endpoints that Instagram's own iOS and Android apps call, which no public documentation covers and which nobody outside Meta supports. The second is someone with a list of handles, some of them locked, asking whether an API can view a private profile — the posts, the followers, the stories behind the padlock.
This post answers both, starting with the second, because that answer is short.
No API can read a private account, including ours
A private account is an access control. The person who set it decided which accounts may see their posts, and Instagram enforces that decision server-side. There is no public endpoint, no parameter, no paid tier and no "enterprise" arrangement that changes it.
Send a private handle to any endpoint here that takes one, and you get this:
{
"success": true,
"credits_charged": 1,
"credits_remaining": 99,
"processing_time_ms": 1842,
"requested_at": "2026-10-04T00:00:00Z",
"query": { "username": "some_locked_account" },
"data": { "profile": null }
}
HTTP 200, charged at the endpoint rate. This is a completed lookup. Profile data alone does not identify whether an account is private. Public profile details may be returned when available; otherwise profile is null. Private posts are not returned. There is no escalation path behind it and no support ticket that unlocks a different answer, and this page is not hedging: the answer does not change if you ask us directly.
If a service tells you otherwise, there are only two possibilities.
It is lying. The common version returns the fields Instagram shows to logged-out visitors on a private profile — avatar, display name, bio, follower count — and lets you assume the posts are coming next. They are not. The other version returns an empty array and charges you for it.
It is using someone's logged-in session. This is the one worth understanding, because it is technically real. A private account's posts are visible to accounts that follow it. So a service can only return them by making the request as an account that already follows that person: a bought account, a burner farm, or a session harvested from a user of some "who viewed your profile" app. In every case, the data reached you because a human identity was used as a key. If it is your account, you have agreed to Instagram's terms and passed an authentication gate, which is exactly the ground the legal analysis says not to stand on. If it is not your account, someone else's credentials were spent on your query.
Neither is a supply chain you want under a product.
What to do instead when your list contains private accounts
The request is billable at the profile endpoint rate even though the private content cannot be read. Filter known private accounts before calling if avoiding that charge matters.
curl -i "https://api.socialscrape.dev/v1/instagram/profile?handle=some_locked_account" \
-H "x-api-key: $INSCRAPE_KEY"
# HTTP/1.1 200 · credits_charged: 1
So the pattern is: attempt, inspect the returned profile data, record the outcome, move on. Private accounts become a coverage number you report rather than a hole you pretend is not there. For influencer or creator work this is rarely a problem in practice, because accounts that exist to be discovered are public by design.
What you cannot do is treat the gap as a vendor problem to shop around. Every honest provider has the same gap, in the same place, for the same reason.
The other meaning: Instagram's internal API
Now the first search. Instagram's apps do not scrape HTML; they call a JSON API on i.instagram.com that Meta has never published, never versioned publicly and never promised anything about. That is the "private API" in the library sense: private as in internal, not private as in locked accounts.
Open-source wrappers around it — instagram-private-api, instagrapi and their forks — work by impersonating the mobile client. That means reproducing a device fingerprint, the app's signing behaviour and its header set, and then logging in to obtain a session. The login is not optional. These endpoints are authenticated; without a session token they return an error, not data.
Which collapses the whole category into one sentence: a private API wrapper is a logged-in API, whatever the README says about being lightweight. Which repository you picked up matters less than that; the four categories of open-source scraper each fail in their own way, and this one fails on the login.
What that costs you in production
Your account is the unit of enforcement. Instagram measures, rate-limits and restricts the identity, not the script. When the challenge screen appears, it appears on the account, and clearing it needs a human with the phone. The scraping warning post covers the mechanics of that.
Sessions are pinned tighter than people expect. A session established from one device fingerprint and one IP range tends to get challenged when either changes. That interacts badly with the proxy rotation you will inevitably add, so the two mitigations fight each other.
It breaks on Instagram's release schedule, not yours. Signature logic, endpoint paths and required parameters change when the app ships. Your pipeline's uptime becomes a function of how quickly an unpaid maintainer merges a fix, and outages arrive without notice.
It still does not return private metrics. This is the part people miss. Impressions, reach and saves are not hidden behind a cleverer endpoint; they belong to the account owner and are exposed only through the official Graph API, for accounts that have connected to your app. Reimplementing the mobile client does not get you there either.
Internal API wrapper versus a hosted public-data API
| Internal API wrapper | Hosted public-data API | |
|---|---|---|
| Instagram account required | Yes, one per worker | No |
| Reads private accounts | Only ones the logged-in account already follows | No private content; 200 private-account lookup billed at profile endpoint rate |
| Who absorbs a challenge | Your account, needs a human | Nobody, there is no account |
| Breaks when the app updates | Yes, on Meta's schedule | No |
| Reach, impressions, saves | No | No |
| Ongoing work | Yours: sessions, fingerprints, proxies, parsers | Your provider's |
The row that decides it for most teams is the third one. Everything else is money; a checkpoint at 3am is a person.
The honest boundary, stated once
Across every endpoint in the catalogue, this API reads what a logged-out visitor can see on a public account. It never authenticates, holds no cookies, and has no Instagram account anywhere in the chain. That is why it cannot be challenged, and also why it cannot see past a padlock. The two facts are the same fact.
Things no read API returns, ours included:
- Anything on a private account, in whole or in part
- Direct messages, notifications and saved posts
- Impressions, reach and saves, which are Graph API metrics for accounts you manage
- Story viewer lists
- Follower email addresses and phone numbers
And it does not write. There is no endpoint that posts, comments, likes, follows or publishes anything. Engagement rate, posting cadence and fake-follower heuristics are calculations you run on what comes back, not fields we return.
If you genuinely need private-account data
There is exactly one legitimate route, and it is not a scraping route. Ask the account owner. If they convert to a Business or Creator account and authorise your app, the Graph API gives you their private metrics properly, with consent, and with none of the fragility above. It works only for accounts that opt in, which is the correct constraint rather than a limitation to route around. For accounts nobody has connected to you, no Graph permission exists at all, which is why a public-data alternative is a different tool rather than a cheaper one.
For everything else — competitor tracking, creator discovery, monitoring, research — public data is the whole surface, and reading it without a login is what keeps the operational and legal questions boring.
Free tier is 100 credits. A private-account lookup uses the profile endpoint rate.
Try it with 100 free credits.
No credit card, credits never expire, and failed requests are not charged.

