Docs / Instagram API Key and Authentication
Instagram API Key and Authentication
One static header, no OAuth flow, no refresh, no expiry. First, the honest answer to the question most people are actually asking.
Maintained by the InScrape API team · Last reviewed 2026-09-19
There is no Meta 'Instagram API key' for reading public accounts
This is the thing worth knowing before you spend a week in the Meta developer console. Meta does not hand out an API key that lets you read arbitrary public Instagram profiles. What you get from Meta is an app id and an app secret, which you exchange through an OAuth flow for an access token that is bound to a specific Instagram account and to the permissions Meta has approved for your app. The token authorises you to act on behalf of that account. It does not authorise you to read a competitor, a creator you are vetting, or any handle that has not connected to your app. No amount of app review changes that, because it is a design decision rather than a permissions gap.
What Meta actually issues, in order
Register an app, add the Instagram product, connect an Instagram Business or Creator account to a Facebook Page, run a user through the OAuth consent screen, receive a short-lived access token that expires in about an hour, exchange it for a long-lived token that lasts about sixty days, and refresh that token before it dies. Then submit for App Review for any permission worth having. Five moving parts, all of which you maintain forever, and at the end of it you can read the accounts your users have connected and nothing else. That is a reasonable amount of work if you are building a scheduling tool. It is a lot of work to discover you cannot read the data you wanted. If you are still weighing the two, the Graph API comparison page runs the same argument endpoint by endpoint; this page is only about the credential.
What an InScrape key is instead
One opaque string, sent as one header, on every request. It is not an OAuth token: there is no authorisation code, no token exchange, no refresh endpoint and no expiry date. It is not tied to any Instagram account, because the API never authenticates as an Instagram user. It is tied to your team's credit balance, which is the only thing it identifies. Keys are issued at signup with 100 free credits attached.
curl "https://api.socialscrape.dev/v1/instagram/posts?handle=natgeo&limit=12" \
-H "x-api-key: $INSCRAPE_KEY"The header, exactly
The header name is x-api-key, lowercase by convention though HTTP header names are case-insensitive. There is no Bearer prefix, no Authorization header and no query-string alternative, so a key cannot end up in a server access log or a browser history entry by accident. Sending the key in any other position returns 401 INVALID_API_KEY.
// Node
const headers = { "x-api-key": process.env.INSCRAPE_KEY };
// Python
headers = {"x-api-key": os.environ["INSCRAPE_KEY"]}
// Wrong: these all return 401
// Authorization: Bearer sk_...
// ?api_key=sk_...
// X-Api-Token: sk_...Never ship the key to a browser or a mobile app
This is a security boundary, so treat it as one. The key is a bearer credential with spending power: anyone holding it can drain your credit balance and read data billed to you. Anything you put in front-end JavaScript, a mobile binary, a public repository or a client-side environment variable prefixed for browser exposure is readable by anybody who wants it. Call the API from your own server, from a serverless function, or from a background job, and let your front end talk to your backend instead. If a key has ever been rendered into a page or committed to a repository, treat it as compromised and rotate it rather than assuming nobody looked.
Rotation and revocation
Keys are stored as a SHA-256 hash. The plaintext is shown once at creation and cannot be recovered afterwards, which means we cannot email it back to you and nor can anyone impersonating you. To rotate, create a second key, deploy it, confirm traffic has moved, then revoke the first. Revocation takes effect on the next request rather than on a cache expiry, so a leaked key stops working as soon as you revoke it. Multiple keys on one team share a single credit pool, so per-service or per-environment keys cost nothing extra and make it obvious which service to rotate when something leaks.
What a rejected key looks like
An unknown, mistyped or revoked key returns 401 with credits_charged 0. Note that credits_remaining is 0 on a 401 as well, not because your balance is empty but because an unrecognised key identifies no team whose balance could be reported. Do not treat a 401 as a billing signal.
{
"success": false,
"error": {
"code": "INVALID_API_KEY",
"message": "Invalid or revoked API key. No credits were charged."
},
"credits_charged": 0,
"credits_remaining": 0
}What each side issues
| Instagram Graph API | InScrape | |
|---|---|---|
| Credential | App id plus app secret, exchanged via OAuth for an access token | One key string, issued at signup |
| Bound to | An Instagram Business or Creator account that has authorised your app | Your team's credit balance |
| Expiry | Short-lived token about an hour, long-lived about sixty days, refresh required | None. The key works until you revoke it |
| Approval | Meta App Review for most useful permissions | None |
| Reads accounts you do not control | No | Yes, when the account is public |
| Sent as | access_token parameter or Authorization header | x-api-key header |
| Recoverable if lost | Re-run the OAuth flow | No. Stored hashed; issue a new key |
FAQ
How do I get an Instagram API key?
From Meta, you do not: Meta issues an app id, an app secret and an OAuth access token tied to an account that has authorised your app, and none of that reads public accounts you do not control. From us, you get a key on the signup screen with 100 free credits attached, and it works on the next request.
Do I need an Instagram API token or an OAuth flow?
No. There is no token exchange, no refresh cycle and no consent screen. One static header on every request is the whole authentication model.
Can I use the Instagram API without an access token?
For public data, yes, through an API like this one. The endpoints read what is visible to a logged-out visitor, so no Instagram token exists in the request path at all. For private data on an account you own, no: that genuinely requires Meta's OAuth token and there is no way around it.
Does the key expire?
No. It has no expiry date and no refresh cycle. It stops working only when you revoke it.
Can I have more than one key?
Yes, and it is a good idea. Separate keys per environment or per service share the same credit balance and let you revoke one without taking everything else down.
What happens if I lose the key?
Issue a new one and revoke the old one. We store only a SHA-256 hash, so nobody, including us, can read the original back out.
Can I call the API directly from my front end?
No. That publishes a credential with spending power to every visitor. Proxy through your own backend.

