---
name: instagram-oauth-app
description: >-
  The Instagram Platform layer on top of the shared `meta-graph-app` skill —
  read that one first for the Meta developer account, app, redirect URIs,
  access levels, review regimes, `appsecret_proof` and Graph API versioning.
  This file covers only what Instagram adds: Instagram Login versus Facebook
  Login for Business, the `instagram_business_*` permissions, the separate
  Instagram App ID and App Secret, `graph.instagram.com`, and the 1-hour →
  60-day → refresh token ladder. Use when asked to get Instagram OAuth
  credentials, create an Instagram app, connect an Instagram Business or
  Creator account, migrate off Instagram Basic Display, rotate an Instagram
  app secret, or fix an error like `Invalid platform app`, `Invalid scrubbed
  redirect_uri`, or a token that stops working after 60 days. For Meta Ads use
  `meta-ads-oauth-app`.
---

# Instagram (Meta) OAuth2 App Registration

Get a working Instagram OAuth2 client — a Meta app with an Instagram use case, redirect URIs, `instagram_business_*`
scopes, and an **Instagram App ID and Instagram App Secret** — for a platform that connects many customers'
Instagram accounts.

The registration mechanics are not here; they are the same for every Meta product and live in the base skill. Two
things are specific to Instagram, and both are decided before you write a line of code.

**First, the product split.** Meta ships two mutually-incompatible Instagram configurations with different hosts,
different permission strings and different prerequisites, and almost every write-up on the internet describes a
third one that Meta shut off in 2024. Pick wrong and you rebuild the connector.

**Second, the credentials are not the ones you expect.** A Meta app has an App ID and App Secret, and Instagram
Login uses a *different*, separately-displayed Instagram App ID and Instagram App Secret. Handing over the wrong
pair produces an authorization error that reads like a redirect-URI problem.

## Built on: `meta-graph-app`

**Read `meta-graph-app` first, in full, then come back here.** It owns:

- **The Meta developer account, the business portfolio, and the app** — the creation wizard, and the fact that
  neither the app type nor any use case you add can be undone afterwards.
- **Redirect-URI mechanics** — exact matching, HTTPS only, the dashboard's silently appended trailing slash, the
  requirement that authorize and token exchange send the same value, and this platform's callback list.
- **Access levels and the review regimes** — Standard vs Advanced Access and why only app-role users can connect
  without it, App Review submission contents (screencast, test credentials, policy URLs), Business Verification,
  Access Verification / Tech Provider, Ongoing Review and the annual Data Use Checkup. Note that `instagram_basic`,
  `instagram_business_basic`, `instagram_business_content_publish`, `instagram_content_publish` and
  `instagram_manage_insights` are all on the Access Verification list.
- **`appsecret_proof` and the "Require App Secret" switch**, and what rotating an app secret breaks.
- **Graph API versioning and the two-year rule**, the current version table, the rate-limit headers, and the generic
  `#1` / `#4` / `#10` / `#17` / `#100` / `#102` / `#190` / `#200` error codes.

If you loaded only this file, you are missing all of the above, and nothing below substitutes for it — in particular,
creating the app, registering redirect URIs, getting Advanced Access and rotating the secret are base-skill steps.

## Inputs specific to Instagram

The base skill's input table applies in full. Collect these on top of it, in the same batch.

| Input | Notes |
| --- | --- |
| **Which Instagram product** | Instagram Login or Facebook Login for Business (§ Platform state, then §1) |
| **Test Instagram account** | A professional (Business or Creator) account you control (§2, §8) |
| **Facebook Page** | Only if choosing Facebook Login for Business (§2) |
| **Scope set** | What the connector actually calls (§4) |

## Quick Start

1. Read **Platform state** first — the product you pick determines every later step.
2. Confirm a professional Instagram account exists, and a linked Page if you are on the Facebook path (§2).
3. Create the app per the base skill and add the Instagram use case (§3).
4. Register the redirect URIs in the Instagram business login panel (§3).
5. Select the `instagram_business_*` scopes the connector calls, and no more (§4).
6. Make at least one successful call while restricted to app-role users, then submit for App Review (§5).
7. Capture the **Instagram** App ID and App Secret — not the Meta app's (§6).
8. Wire up the 1-hour → 60-day → refresh token chain (§7).
9. Verify with a second Instagram account that has no role on the app (§8), then hand off (§9).

## Platform state (verified 2026-09-20 — re-verify before trusting)

Read this alongside the base skill's Platform state. The Instagram product lineup changed twice in two years and the
stale advice is everywhere.

**Instagram Basic Display API is gone.** Meta announced it on **September 4, 2024** and shut it down on
**December 4, 2024**; the changelog states that "All requests to the Instagram Basic Display API will return an error
message." Meta's own words: after that date "there will no longer be a set of Instagram APIs for consumer developer
apps." The old `/docs/instagram-basic-display-api` URL still resolves, but it now lands on the Instagram Platform
landing page with no Basic Display content. **If a plan, ticket or tutorial mentions Basic Display, `user_profile`,
`user_media`, or personal Instagram accounts, it is describing a dead product — stop and re-scope.**

**There are exactly two current products.** Both require an Instagram **professional** account (Business or Creator).
Neither works with a personal Instagram account.

| | **Instagram API with Instagram Login** | **Instagram API with Facebook Login for Business** |
| --- | --- | --- |
| Launched | July 23, 2024 | The older, Page-linked path |
| Requires a Facebook Page | **No** | **Yes** — IG account must be linked to a Page |
| Who logs in | The Instagram user, with Instagram credentials | The Facebook user who manages the Page |
| API host | `graph.instagram.com` | `graph.facebook.com` |
| Permission prefix | `instagram_business_*` | `instagram_*` plus `pages_*` |
| Extra reach | — | Hashtag search, business discovery, basic metrics on *other* accounts |

**Pick Instagram Login** unless you need a capability only the Facebook path has (hashtag search, business discovery,
metrics on accounts other than the connected one) or unless customers are already Page-linked and expect a Facebook
consent screen. Instagram Login removes the single biggest onboarding failure — a customer whose Instagram account is
not linked to a Facebook Page, which they often cannot fix themselves. The two are not interchangeable at runtime:
different host, different permission strings, different token endpoints.

**Scope names were renamed and the old ones are dead.** Announced **September 17, 2024**: `business_basic` →
`instagram_business_basic`, `business_content_publish` → `instagram_business_content_publish`,
`business_manage_comments` → `instagram_business_manage_comments`, `business_manage_messages` →
`instagram_business_manage_messages`. The old values were deprecated **January 27, 2025**. A separate permission,
**`instagram_business_manage_insights`**, arrived **March 24, 2025** — it is newer than most tutorials and is
missing from at least one of Meta's own summary pages, so do not conclude it does not exist if you cannot find it in
a scope list.

**Legacy v1.0 Instagram endpoints** were deprecated **January 21, 2025** with a compliance deadline of
**May 20, 2025**.

If the App Dashboard does not look like this, stop and report what you actually see rather than clicking on.

## 1. Reuse the existing app, or register a new one

The base skill's reuse-versus-new decision applies, with one Instagram-specific addition: a new app means a **new
Instagram App ID**, and every existing customer connection is bound to the old one.

Register a **new** app only when the user explicitly wants one — and note the case that is unique to this product: a
deliberate move between the two Instagram products is a **migration, not a config change**. Different host and
different permission strings mean the connector code changes and every customer re-authorizes. Say which path you
are taking before you touch anything.

## 2. The Instagram account, and the Page

Beyond the base skill's developer account and business portfolio, Instagram needs one more account object, and
sometimes two:

- **Instagram professional account** — Business or Creator. Converting a personal account is a setting inside the
  Instagram app itself, done by the account owner, not by you.
- **Facebook Page** — for **Facebook Login for Business** only. That Instagram account must additionally be linked
  to a Page, and the person authorizing must have a role on that Page. This is the requirement customers most often
  cannot satisfy on their own, and the main reason to prefer Instagram Login.

Converting an Instagram account to professional is one of the human-only steps the base skill describes: hand it
back to the account owner rather than looping on it.

## 3. Add the Instagram use case, and register the redirect URIs

Meta folded Instagram-specific app creation into the generic wizard the base skill covers; the old "create an
Instagram app" page is now a pointer. At the **Use cases** step, select the Instagram use case — currently surfaced
as *"Manage messaging and content on Instagram"*. This is the choice that shapes the dashboard, and per the base
skill it cannot be removed later.

Then, in the dashboard, customize the use case to use **Business Login for Instagram** (Instagram Login) *or*
**Facebook Login for Business**, matching the decision from Platform state. The Instagram Login settings live under
**App Dashboard → Instagram → API setup with Instagram business login**, whose panels you will use again in §6.

Redirect URIs are registered under **App Dashboard → Instagram → API setup with Instagram business login →
3. Set up Instagram business login → Business login settings**. Add each URL and save; the matching rules and the
trailing-slash trap are in the base skill, and this panel is exactly where that trap bites.

Two Instagram-specific behaviours on the callback itself:

- After a successful authorization Meta appends **`#_`** to your redirect URI. Strip it before exchanging the code.
- The authorization code is valid for **1 hour** and is **single use**.

A detail worth knowing before you fight it: if you chose messaging, Meta **adds `instagram_business_basic` and
`instagram_business_manage_messages` by default**. Prune the list to what the connector actually calls — the base
skill explains what an unused permission request costs at review time.

## 4. Permissions and scopes

Scope is sent on the authorize request as a comma- or space-separated list. Use the set that matches your product.

**Instagram API with Instagram Login** (`graph.instagram.com`):

| Scope | Grants |
| --- | --- |
| `instagram_business_basic` | Profile and media reads; **required**, and required to refresh a token |
| `instagram_business_content_publish` | Publish media (the container → publish flow) |
| `instagram_business_manage_insights` | Account and media insights — added March 24, 2025 |
| `instagram_business_manage_comments` | Read and moderate comments |
| `instagram_business_manage_messages` | Instagram Direct messaging |

**Instagram API with Facebook Login for Business** (`graph.facebook.com`): `instagram_basic`,
`instagram_content_publish`, `instagram_manage_comments`, `instagram_manage_insights`, `instagram_manage_messages`,
plus `pages_show_list` and `pages_read_engagement` to find and read the linked Page.

**As of 2026-09-20, Unified.to's Instagram connector requests** `instagram_business_basic` as its base/login scope,
adds `instagram_business_content_publish` for publishing, and adds `instagram_business_manage_insights` for insights
— the `instagram_business_*` set, which means it is built on **Instagram API with Instagram Login**, not the
Facebook-Page path. It calls `graph.instagram.com`, sends the token as a bearer header, and does **not** ship shared
platform credentials: each customer supplies their own Instagram App ID and Secret. Two auth quirks to raise with the
connector's owner rather than assume: as of this date it is configured to authorize against
`api.instagram.com/oauth/authorize` and to exchange at `graph.instagram.com/access_token`, while Meta's Business
Login guide documents `https://www.instagram.com/oauth/authorize` for authorize and
`https://api.instagram.com/oauth/access_token` for the code exchange (see §7) — and it carries no long-lived-token
refresh configuration, which matters given the 60-day expiry. **Confirm the current scope set and endpoints with the
connector's owner before you register anything.**

## 5. What the base skill's review regimes mean here

All of them apply unchanged. Three Instagram-specific points:

**Instagram apps do have app modes.** Unlike Business-type apps, an app built through the Instagram use case starts
in **Development mode**, so the base skill's app-mode material is live for this product: only users with a role on
the app can authorize, and flipping to Live without approved permissions makes the app visible without granting
anything.

**The ordering trap is explicit for Instagram.** Meta's Instagram App Review page states: "To request Advanced
Access to certain permissions, you need to make at least 1 successful API call." So the sequence is: build → add
your own Instagram account as an app role/tester → make real calls in Development mode → *then* submit.

**A platform constraint Meta calls out in the submission**: "Web or mobile Web is the only platform that currently
supports Instagram API with Instagram Login." A reviewer expecting a native mobile flow will not find one.

## 6. Capture the credentials

For **Instagram Login**, the values live at **App Dashboard → Instagram → API setup with Instagram business login →
3. Set up Instagram business login → Business login settings**:

- **Instagram App ID** → your OAuth `client_id`
- **Instagram App Secret** → your OAuth `client_secret`

**These are not the Meta app's App ID and App Secret** (Settings → Basic). The Meta pair is a different credential
for a different surface; using it against `api.instagram.com` fails in ways that look like a misconfigured app rather
than a wrong ID. For **Facebook Login for Business**, the opposite is true — that path uses the Meta app's App ID and
App Secret, the ones the base skill describes. Record which product this app is, next to the credentials, or the
next person will pick the wrong pair.

This is also the one place where the base skill's `appsecret_proof` guidance needs care: verify *which* secret keys
the HMAC for your product before enabling "Require App Secret," rather than assuming it is the Instagram App Secret.

Also capture, alongside the base skill's list: the authorize, token, long-lived exchange and refresh endpoints (§7),
and the API host (`graph.instagram.com` or `graph.facebook.com`).

## 7. Token lifetimes and refresh

Instagram Login tokens go through three stages. A connector that stops at stage one dies after an hour; one that
stops at stage two dies after 60 days.

| Stage | Call | Result |
| --- | --- | --- |
| Code → short-lived | `POST https://api.instagram.com/oauth/access_token` with `client_id`, `client_secret`, `grant_type=authorization_code`, `redirect_uri`, `code` | Token valid **1 hour** |
| Short-lived → long-lived | `GET https://graph.instagram.com/access_token?grant_type=ig_exchange_token&client_secret=…&access_token=…` | Token valid **60 days** (`expires_in` 5184000) |
| Long-lived → refreshed | `GET https://graph.instagram.com/refresh_access_token?grant_type=ig_refresh_token&access_token=…` | New token, another **60 days** |

Constraints that decide whether a connection survives:

- Instagram's renewal mechanism is unusual for Meta in that a connection *can* be kept alive indefinitely without
  sending the user back through consent — but **you refresh the access token itself** and must store the *new*
  value each time. A client that keeps refreshing the original value eventually fails.
- The refresh call requires a token that is **at least 24 hours old and not yet expired**, and the token must carry
  `instagram_business_basic`. There is no grace period after expiry — a connection that goes 60 days without a
  refresh is dead and the customer must re-authorize. Refresh well before day 60, not on it.
- **Authorize host discrepancy, verified today:** Meta's Business Login guide shows the embed URL as
  `https://www.instagram.com/oauth/authorize`, while Meta's own `oauth-authorize` reference page documents
  `GET https://api.instagram.com/oauth/authorize`. Both are official and current. Widely-repeated advice names only
  one or the other. Treat `www.instagram.com/oauth/authorize` as the documented user-facing entry point and test
  whichever the connector is configured for, rather than assuming the other is wrong.
- **Facebook Login for Business has a different token story** (`graph.facebook.com`, `fb_exchange_token`, Page
  tokens, and no `ig_refresh_token` equivalent). Do not carry any of the table above across to it; `meta-ads-oauth-app`
  §5 describes how that ladder behaves.

## 8. Verify end-to-end

The base skill's round trip and its rule about testing as a user with no role on the app both apply. These are the
Instagram-specific steps layered on it:

1. Authorize a **second** Instagram professional account with **no role on the app**, through your platform's real
   connect flow.
2. Confirm the code exchange succeeds, then the long-lived exchange, then a **refresh** — and that the connector
   stores the token each stage returns.
3. Make one real read call against `graph.instagram.com` with the pinned version.

| Symptom | Cause |
| --- | --- |
| `Invalid platform app` / app not recognized | Using the Meta App ID instead of the **Instagram** App ID (§6), or the wrong product entirely |
| `Invalid scrubbed redirect_uri` / redirect mismatch | URI not registered exactly in the Instagram business login panel (§3) |
| Consent succeeds, token exchange fails | The `#_` fragment was not stripped, or the code was already used or is over an hour old (§3) |
| Works, then dies after ~1 hour | Never exchanged the short-lived token for a long-lived one (§7) |
| Works, then dies after ~60 days | No refresh, or refresh attempted after expiry, or the refreshed token was not stored (§7) |
| Refresh returns an error on a fresh connection | Token is under 24 hours old (§7) |
| Customer cannot connect: "no professional account" | Personal Instagram account — owner must convert to Business or Creator (§2) |
| Customer cannot connect on the Facebook path only | Instagram account not linked to a Facebook Page, or the user lacks a role on the Page (§2) |
| A tutorial's endpoints 404 or return "no longer available" | The guide predates December 2024 and targets Basic Display (§ Platform state) |

## 9. Hand off

Follow the base skill's handoff rules and add, to its closing list: **which Instagram product** the app is built on;
the Instagram App ID and where its secret was delivered (distinct from the Meta app's pair); the authorize, token,
exchange and refresh endpoints; the exact `instagram_business_*` scope strings; the API host; and the refresh
schedule the platform must run before day 60.

## Stop and ask

The base skill's stop-and-ask list applies. Additionally, hand back to a human when: the choice between Instagram
Login and Facebook Login for Business is not clearly implied by the capabilities needed, since it determines the
connector's host and permission strings; customers' Instagram accounts are personal, or unlinked from a Page on the
Facebook path; someone proposes migrating a live app between the two Instagram products, which re-authorizes every
customer and changes the code; the plan or ticket assumes Instagram Basic Display or personal accounts; or the
connector does not refresh long-lived tokens on a schedule.

## References

Instagram specific. The generic Meta developer-account, app-creation, review, credential and Graph API references
are in `meta-graph-app`. All verified to resolve 2026-09-20.

- Instagram Platform — https://developers.facebook.com/docs/instagram-platform
- Instagram Platform overview (products, tokens, permissions) — https://developers.facebook.com/docs/instagram-platform/overview
- Instagram API with Instagram Login — https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login
- Business Login for Instagram — https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/business-login
- Instagram API with Facebook Login for Business — https://developers.facebook.com/docs/instagram-platform/instagram-api-with-facebook-login
- Business Login for Instagram (Facebook Login path) — https://developers.facebook.com/docs/instagram-platform/instagram-api-with-facebook-login/business-login-for-instagram
- `oauth/authorize` reference — https://developers.facebook.com/docs/instagram-platform/reference/oauth-authorize/
- `access_token` reference (long-lived exchange) — https://developers.facebook.com/docs/instagram-platform/reference/access_token/
- `refresh_access_token` reference — https://developers.facebook.com/docs/instagram-platform/reference/refresh_access_token/
- Instagram Platform changelog — https://developers.facebook.com/docs/instagram-platform/changelog
- Instagram Platform App Review — https://developers.facebook.com/docs/instagram-platform/app-review
- Instagram Platform insights — https://developers.facebook.com/docs/instagram-platform/insights
- Create an Instagram app (now a pointer to the generic flow) — https://developers.facebook.com/docs/instagram-platform/create-an-instagram-app
- Update on Instagram Basic Display API (Sept 4, 2024; shutdown Dec 4, 2024) — https://developers.facebook.com/blog/post/2024/09/04/update-on-instagram-basic-display-api/
- User and media insights on Instagram API with Instagram Login (Mar 24, 2025) — https://developers.facebook.com/blog/post/2025/03/24/user-and-media-insights-on-instagram-api-with-instagram-login/
