Instagram Graph API
Max 27min read

Instagram Graph API: Complete Developer Guide for 2026

Reviewed
By Editorial Staff
Mar 29, 2026

Summarize with:

ChatGPT Icon Grok AI Icon Claude AI Icon Google AI Mode

If you’ve worked with Instagram APIs before, the year 2024 must have been stressful. The Basic Display API was shut down on  4th December. No extensions, no fallback. Tokens stopped working, and apps relying on personal account data just broke.

Now, the Instagram Graph API is the only way to access Instagram data in 2026. If you’re building anything that connects with Instagram, this is what you’ll be working with.

This guide covers what actually matters: authentication, access tokens, rate limits, key endpoints, and common errors. It will also help you migrate from older setups if needed.

Whether you’re building a tool, dashboard, or eCommerce integration, this will help you get started without confusion.

TL;DR

  • The Instagram Graph API is Meta’s official API that lets developers read data, publish content, manage comments, and access analytics from Instagram programmatically
  • It is now the only supported way to access Instagram data after the Basic Display API shutdown
  • Only Business and Creator accounts are supported, so personal accounts must be converted before integration
  • Every request requires a valid Instagram access token, obtained through proper authentication flows
  • There are two main authentication methods: Instagram Business Login (simpler) and Facebook Login for Business (more powerful)
  • Rate limits are strict at 200 calls per hour per account, so inefficient requests can quickly cause failures
  • Use techniques like batching, caching, and requesting only required fields to reduce API usage
  • Webhooks are the preferred way to handle real-time events instead of polling endpoints repeatedly
  • Core endpoints cover media, comments, insights, hashtags, and more, but advanced use cases need additional APIs
  • Features like messaging, ads, and shopping require separate APIs within the Meta ecosystem
  • Migrating from the Basic Display API involves changes in accounts, authentication, endpoints, and permissions
  • If you’re using WordPress, WP Social Ninja can handle authentication, data fetching, and display without manual API setup

What is the Instagram graph API (and who is it for)?

The Instagram Graph API is Meta’s main interface for accessing Instagram data programmatically. It’s built for developers who need to interact with Instagram at scale, whether that’s reading media, publishing content, managing comments, or pulling analytics.

One thing to be clear about: it only works with Instagram Business and Creator accounts. Personal accounts don’t have API access anymore.

In most cases, the Instagram account also needs to be connected to a Facebook Page. This setup is required for authentication and for features like advanced insights and Instagram Shopping.

If you’ve gone through the Instagram API documentation, you’ll notice that this structure is not optional. It’s part of how the API graph is designed, especially for apps that need consistent data access and permissions.

Who actually needs to use the Instagram Graph API the most?

If you’re building anything that connects with Instagram programmatically, the Instagram Graph API is where you start. Especially if you work with:

  • Social media management platforms that publish content, schedule posts, and track engagement across multiple accounts
  • Analytics and reporting tools that pull data into dashboards for performance tracking
  • Agencies handling multiple client accounts and needing centralized access
  • Content teams and creators are automating publishing workflows and measuring results
  • Customer support tools that bring Instagram messages into helpdesk systems
  • Data-focused teams analyzing Instagram trends through hashtags and public content

How do different types of Instagram Graph API authentication work

Before making any requests with the Instagram Graph API, you need a valid Instagram access token. The API supports two authentication methods- Instagram Business Login and Facebook Login for Business.

Here’s a quick comparison of these two authentication methods:

FeatureInstagram Business LoginFacebook Login for Business
Setup complexityModerateHigher
Best forSingle account tools, creator apps, simple integrationsMulti-account platforms, agencies, and SaaS tools
Login experienceDirect Instagram loginFacebook login required
Facebook account neededNoYes
Facebook Page requiredNoYes
Token sourceInstagram OAuthFacebook Page access token
Account accessOne account per loginMultiple accounts via Pages
Permissions requiredInstagram-specific scopesFacebook + Instagram scopes
Implementation effortEasier to set up and maintainMore complex flow and setup
Advanced featuresLimited access to some featuresFull access to the Meta ecosystem features
Instagram Shopping supportNot fully supportedFully supported
Cross-platform integrationLimitedSupports Facebook + Instagram workflows
Token lifespan60 days (long-lived)60 days (long-lived)
Ideal use caseLightweight apps, creator tools, quick integrationsScalable products, dashboards, enterprise tools

Method 1: Instagram Business Login (Direct OAuth)

This method lets users log in directly with their Instagram account. No Facebook account or Page connection is required.

Here is how the standard OAuth 2.0 flows work and return access tokens:

  • Redirect the user to Meta’s authorization endpoint with your app ID, redirect URI, and requested scopes
  • The user authenticates with Instagram and approves permissions
  • Instagram redirects back to your URI with an authorization code
  • You exchange that code for a short-lived access token
  • You exchange the short-lived token for a long-lived token

Here’s what the authorization URL looks like:

https://api.instagram.com/oauth/authorize
  ?client_id={app-id}
  &redirect_uri={redirect-uri}
  &scope=instagram_business_basic,instagram_business_manage_messages
  &response_type=code

Once you have the authorization code, exchange it for a short-lived token:

curl -X POST https://api.instagram.com/oauth/access_token \
  -F client_id={app-id} \
  -F client_secret={app-secret} \
  -F grant_type=authorization_code \
  -F redirect_uri={redirect-uri} \
  -F code={auth-code}

The response gives you a short-lived token (valid for 1 hour). Immediately exchange it for a long-lived token (valid for 60 days).

Here’s an exchanged long-lived token:

curl -X GET "https://graph.instagram.com/access_token
  ?grant_type=ig_exchange_token
  &client_secret={app-secret}
  &access_token={short-lived-token}"

Key scopes for Instagram Business Login:

  • instagram_business_basic: read profile and media
  • instagram_business_manage_media: create, publish, and delete media
  • instagram_business_manage_comments: read and reply to comments
  • instagram_business_manage_insights: access account and media insights
  • instagram_business_manage_messages: send and receive DMs

When you should use the Instagram Business Login flow: 

  • Building single-account tools or creator-focused apps
  • When you want a simple login without Facebook
  • Mobile or consumer-facing applications

This flow is easier to implement, but some advanced features still require the Facebook-based setup.

​​Method 2: Facebook Login for Business

This method uses Facebook Login and works through a connected Facebook Page. It’s more complex but gives access to deeper features in the Instagram API and Meta ecosystem.

Here’s how the OAuth flow works for Facebook login at a high level:

  • User logs in with Facebook and grants your app the necessary Instagram permissions
  • You retrieve the user’s Page Access Token for the relevant Facebook Page
  • From the Page, you fetch the connected Instagram Business Account ID
  • You use that IG User ID along with the Page Access Token (or a derived token) to make Graph API calls

Here’s how fetching the connected Instagram account ID looks like:

curl -X GET "https://graph.facebook.com/v22.0/{page-id}
  ?fields=instagram_business_account
  &access_token={page-access-token}"

Key scopes for Facebook Login for business:

  • pages_show_list: list Pages the user manages
  • instagram_basic: read basic IG account info
  • instagram_manage_insights: access insights
  • instagram_content_publish: publish media
  • instagram_manage_comments: manage comments
  • pages_read_engagement: read Page engagement data

When you should use Facebook Login flow:

  • Multi-account platforms like agencies or social media tools
  • Apps that manage accounts through Facebook Pages
  • Use cases involving Instagram Shopping or advanced analytics

This is the required approach if your app depends on Facebook Page connections.

Token refresh logic for Instagram Graph API

Long-lived tokens in the Instagram Graph API expire after 60 days, but you can refresh them before they expire to keep your integration active.

curl -X GET "https://graph.instagram.com/refresh_access_token
  ?grant_type=ig_refresh_token
  &access_token={long-lived-token}"

Each refresh resets the 60-day validity from the time of the request. So as long as you refresh tokens on time, you don’t need users to log in again.

In practice, it’s safer to refresh tokens every 30 to 45 days instead of waiting until the last moment. Store the expiry time along with the token so your system can handle this automatically.

If a token does expire, the only option is to send the user through the authentication flow again to generate a new token. It’s better to notify users in advance so this doesn’t interrupt your app.

Instagram Graph API rate limits explained

Rate limits are where most Instagram Graph API integrations run into issues. The limits are stricter than they look, and if you don’t plan around them, you’ll start seeing 429 errors when your app is actively in use.

The core limit: 200 calls per hour per account

The Instagram API uses a Business Use Case (BUC) model. The main limit is 200 API calls per hour per Instagram Business account.

This limit is applied per account, not per app or per user. So if multiple users or systems are connected to the same account, they all share the same pool of requests.

It also works on a rolling window. Requests made in the last 60 minutes are continuously counted, not reset at the top of the hour.

Every request counts toward this quota, including:

  • Pagination calls
  • Insights and metadata requests
  • Even failed requests that return a valid API response

There’s no free request type. Everything uses the same pool.

DM-specific limits for Instagram Graph API

If your integration includes messaging, there are additional limits:

  • Up to 200 automated DMs per hour per account
  • A 24-hour messaging window, meaning you can only message users who contacted you within the last 24 hours

These limits apply alongside the main BUC limit. A single DM request counts toward both limits. If your app relies heavily on messaging, this overlap can reduce your available API calls faster than expected.

How to read Instagram Graph API usage data

The Instagram API documentation provides rate limit usage through response headers. The key one is: X-Business-Use-Case-Usage

Here’s a sample of how the snippet should look like:

"X-Business-Use-Case-Usage": {
  "{ig-user-id}": [
    {
      "call_count": 28,
      "total_cputime": 10,
      "total_time": 20,
      "type": "INSTAGRAM",
      "estimated_time_to_regain_access": 0
    }
  ]
}

The call_count shows how much of your quota is used. For example, 28 means around 28% of your hourly limit. Once usage reaches around 80 to 90 percent, it’s a good idea to slow down requests. At 100 percent, the API starts returning 429 errors.

If you’re building for scale, log these headers and track them. This helps you identify accounts that are close to hitting limits before they actually do.

What you can do with 200 requests per hour

The limit might seem restrictive at first, but it depends on how efficiently you use the Instagram Graph API rate limits. A few examples:

  • Fetching a list of 50 recent media items: 1 call (with fields parameter)
  • Fetching insights for 10 media items individually: 10 calls
  • Fetching insights for 10 media items via batch: 1 call
  • Checking 20 comment threads: up to 20 calls
  • Refreshing an access token: 1 call

For simple use cases like displaying a feed or updating a dashboard, 200 requests per hour is usually enough. For heavier use cases like comment monitoring or analytics tools, efficiency becomes critical.

What most developers get wrong about rate limits

Understanding limits is one thing. Designing around them is where most integrations fail.

  • Treating limits as global instead of per account. Each account has its own quota. If multiple systems connect to the same account, they all share it.
  • Re-fetching the same data repeatedly. Calling the same endpoints frequently without changes wastes your quota.
  • Not using batch requests or field expansion. Fetching data one item at a time quickly increases API usage.
  • Ignoring pagination costs. Each page is a new request. Large datasets can drain your quota faster than expected.
  • Not tracking usage in real time. If you’re not monitoring headers, you only notice problems after hitting limits.
  • Sending too many parallel requests. High concurrency can spike usage and trigger limits faster.

Designing around Instagram Graph API rate limits

To work reliably with the Instagram Graph API, you need to design your system with limits in mind. A few patterns from our experience that work well:

  • Handle requests per account, not globally
  • Use caching to avoid repeated calls
  • Reduce polling and rely on webhooks where possible
  • Queue or throttle high-frequency operations
  • Prioritize critical requests over background updates

Instead of trying to avoid limits, build your system assuming they exist.

Pro Tips: The Instagram Graph API rate limits are strict but predictable. Most issues don’t come from the limits themselves, but from inefficient request patterns. If you batch requests, cache responses, and plan per account, you can handle even complex use cases without running into problems.

Key Instagram Graph API endpoints and what they do

The Instagram Graph API is built around different endpoints, each designed for a specific type of data or action. Once you understand how these are grouped, it becomes much easier to build features.

Media management

The / {ig-user-id} /media endpoint returns all media for a Business or Creator account.

curl -X GET "https://graph.facebook.com/v22.0/{ig-user-id}/media
  ?fields=id,media_type,media_url,thumbnail_url,caption,timestamp,like_count,comments_count
  &limit=25
  &access_token={token}"

You can control the response using the fields parameter. This helps reduce unnecessary data and keeps responses faster. Media types include:

  • IMAGE
  • VIDEO
  • CAROUSEL_ALBUM
  • REELS

Each type supports different fields. For example:

  • thumbnail_url is only available for video and reels
  • children is used for carousel posts

Publishing content

Publishing works through a two-step container process.

Step 1: Create container

curl -X POST "https://graph.facebook.com/v22.0/{ig-user-id}/media" \
  -d "image_url=https://example.com/photo.jpg" \
  -d "caption=Your caption here" \
  -d "access_token={token}"

Step 2: Publish

curl -X POST "https://graph.facebook.com/v22.0/{ig-user-id}/media_publish" \
  -d "creation_id={container-id}" \
  -d "access_token={token}"

For videos and reels, the container needs time to process. You have to check its status before publishing:

GET /{container-id}?fields=status_code

Only publish when the status is FINISHED. If you try earlier, the request will fail.

Comments

To fetch comments:

curl -X GET "https://graph.facebook.com/v22.0/{ig-media-id}/comments
  ?fields=id,text,timestamp,username,like_count,replies{id,text,timestamp,username}
  &access_token={token}"

To reply to a comment:

curl -X POST "https://graph.facebook.com/v22.0/{ig-media-id}/comments" \
  -d "message=Thanks for your comment!" \
  -d "access_token={token}"

For nested replies, use:

POST /{ig-comment-id}/replies

You can also:

  • Hide comments: POST /{ig-comment-id}?hide=true
  • Delete comments: DELETE /{ig-comment-id}

Insights and analytics

Insights are available at both media and account levels.

Media-level insights:

curl -X GET "https://graph.facebook.com/v22.0/{ig-media-id}/insights
  ?metric=impressions,reach,likes,comments,shares,saved
  &access_token={token}"

Account-level insights:

curl -X GET "https://graph.facebook.com/v22.0/{ig-user-id}/insights
  ?metric=impressions,reach,profile_views,follower_count
  &period=day
  &since=1710000000
  &until=1710604800
  &access_token={token}"

Important note: Some metrics were removed in newer API versions. Always check the version you’re using (v22.0 as of 2026). Calling deprecated metrics can lead to missing data or errors.

Hashtag search

To search for a hashtag, first get its ID:

curl -X GET "https://graph.facebook.com/v22.0/ig_hashtag_search
  ?user_id={ig-user-id}
  &q=photography
  &access_token={token}"

Then fetch media:

curl -X GET "https://graph.facebook.com/v22.0/{hashtag-id}/recent_media
  ?user_id={ig-user-id}
  &fields=id,media_type,media_url,caption,timestamp
  &access_token={token}"

There’s a key limitation here: You can query up to 30 unique hashtags per week per account. So it’s better to cache hashtag IDs instead of requesting them repeatedly.

Business discovery

This endpoint lets you fetch public data from other Business or Creator accounts.

curl -X GET "https://graph.facebook.com/v22.0/{ig-user-id}
  ?fields=business_discovery.fields(username,name,biography,followers_count,media_count,website)
  &access_token={token}"

This only works for:

  • Public accounts
  • Business or Creator profiles

Personal or private accounts are not accessible.

Mentions and tags

To fetch posts where your account is mentioned:

curl -X GET "https://graph.facebook.com/v22.0/{ig-user-id}
  ?fields=mentioned_media.fields(caption,media_url,media_type,timestamp)
  &access_token={token}"

For comment mentions: Use mentioned_comment

This is useful for:

  • Brand monitoring
  • Engagement tracking

Stories

Stories are available through: /{ig-user-id}/stories

But there are limitations:

  • Only accessible for 24 hours
  • Fewer fields compared to regular posts

Insights for stories, like impressions, reach, exits, and replies, are available through the standard / {ig-media-id} /insights endpoint while the story is still live.

Key takeaway for the Instagram Graph API endpoint

The Instagram Graph API endpoints are structured, but not always intuitive at first. Once you understand:

  • Which endpoint handles what
  • How data is structured
  • and where limits apply

you can combine them to build almost any Instagram-based feature.

How to use Instagram Graph API efficiently in real use cases

Knowing the endpoints is one thing. Using them efficiently is where most of the real work happens. These are the patterns that show up most often when building with the Instagram Graph API.

Fetching media with insights in one pass

A common mistake is fetching media first, then looping through each item to request insights separately. This quickly increases your API usage and can hit Instagram Graph API rate limits.

Instead, use field expansion to request both media and insights in a single call:

curl -X GET "https://graph.facebook.com/v22.0/{ig-user-id}/media
  ?fields=id,caption,media_type,timestamp,like_count,comments_count,
    insights.metric(impressions,reach,saved){data}
  &limit=10
  &access_token={token}"

This reduces multiple requests into one. For example, instead of making 11 calls (1 for media + 10 for insights), you only make 1.

Batch requests

The Instagram API supports batch requests through the Facebook Graph API. This allows you to combine up to 50 requests into a single HTTP call:

curl -X POST "https://graph.facebook.com/v22.0" \
  -d 'access_token={token}' \
  -d 'batch=[
    {"method":"GET","relative_url":"{ig-media-id-1}/insights?metric=impressions,reach"},
    {"method":"GET","relative_url":"{ig-media-id-2}/insights?metric=impressions,reach"},
    {"method":"GET","relative_url":"{ig-media-id-3}/insights?metric=impressions,reach"}
  ]'

The response returns a JSON array, with one result per request. Batch requests count as a single call against your rate limit, which makes them one of the most effective ways to reduce API usage.

Reading and replying to comments

For comment moderation, you can fetch comments along with replies in one request:

curl -X GET "https://graph.facebook.com/v22.0/{ig-media-id}/comments
  ?fields=id,text,timestamp,username,like_count,replies{id,text,timestamp,username}
  &filter=stream
  &access_token={token}"

The filter=stream parameter returns only top-level comments, without nesting replies inside them.

To reply to a comment:

curl -X POST "https://graph.facebook.com/v22.0/{ig-comment-id}/replies" \
  -d "message=@{username} Thanks for reaching out!" \
  -d "access_token={token}"

If you’re building a system that monitors comments at scale, using webhooks is more efficient than polling repeatedly. This is covered in the next section.

Publishing content via container workflow

Publishing content through the Instagram Graph API follows a container-based process.

Step 1: Create the container

curl -X POST "https://graph.facebook.com/v22.0/{ig-user-id}/media" \
  -d "media_type=REELS" \
  -d "video_url=https://example.com/video.mp4" \
  -d "caption=Check out this reel! #trending" \
  -d "share_to_feed=true" \
  -d "access_token={token}"

Save the container ID from the response, then check its status:

curl -X GET "https://graph.facebook.com/v22.0/{container-id}?fields=status_code&access_token={token}"

Wait until the status_code is FINISHED.

Step 2: Publish

curl -X POST "https://graph.facebook.com/v22.0/{ig-user-id}/media_publish" \
  -d "creation_id={container-id}" \
  -d "access_token={token}"

For carousels, the process is slightly different:

  • Create containers for each item
  • Create a parent container referencing those items
  • Publish the parent container

Key takeaway for Instagram Graph API use cases

Most performance issues with the Instagram Graph API don’t come from the API itself, but from how requests are structured.

You can reduce API usage significantly and stay within limits if you:

  • combine requests
  • avoid unnecessary loops
  • and use batching or field expansion

How to work with Instagram Graph API webhooks properly

Polling endpoints to check for new comments or mentions can quickly consume your Instagram Graph API rate limits, even when nothing has changed. Webhooks solve this by switching the flow. Instead of your app asking for updates, Instagram sends events to your server when they happen.

To use Instagram Graph API webhooks, you need to set up:

  • A publicly accessible HTTPS endpoint that can handle both GET (for verification) and POST (for incoming events)
  • Subscription to Instagram webhook topics through the App Dashboard or API

The Verification step of webhook: When you configure the webhook, Meta sends a GET request with hub.mode=subscribe, hub.challenge, and hub.verify_token. Your endpoint must return the hub.challenge value to confirm.

You can subscribe to the following types of events using webhooks, depending on your use case:

  •  mentions: when your account is @mentioned in a comment or caption
  •  comments: new comments on your media
  •  messages: incoming DMs (via Messenger Platform)
  •  story_insights: story metrics 24 hours after posting
  •  feed: new media posts from connected accounts

A webhook POST payload for a new comment looks like:

{
  "object": "instagram",
  "entry": [
    {
      "id": "{ig-user-id}",
      "time": 1710000000,
      "changes": [
        {
          "value": {
            "from": { "id": "123456", "username": "user" },
            "media": { "id": "{media-id}" },
            "text": "Great photo!",
            "id": "{comment-id}"
          },
          "field": "comments"
        }
      ]
    }
  ]
}

Security Check: Always validate the X-Hub-Signature-256 header using your app secret before processing webhook data. This step ensures that the request actually came from Meta and not from a spoofed source.

How to optimize Instagram Graph API performance and usage

Staying within Instagram Graph API rate limits while keeping your integration responsive requires a bit of planning. In this section, we will discuss the patterns that make the biggest difference in real use cases.

Request only the fields you need

By default, API responses include a broad set of fields. These are designed for general use, not your specific needs. Instead of fetching everything, use the fields parameter to request only what you need:

# Instead of this:
/v22.0/{ig-user-id}/media

# Do this:
/v22.0/{ig-user-id}/media?fields=id,media_type,timestamp,like_count

Smaller responses mean:

  • faster API calls
  • less data to process
  • better overall performance

Use caching based on data update frequency

Not all data changes at the same rate. If you treat everything the same, you’ll end up making unnecessary API calls. A better approach is to cache based on how often the data changes:

  • Captions and media URLs: cache for hours or days
  • Like and comment counts: cache for 15 to 30 minutes
  • Follower counts: cache for 1 to 4 hours
  • Story insights: cache until 24 hours after posting
  • Access tokens: store and refresh before expiration (around 45 days)

Using an in-memory store like Redis works well here. Set different TTL values based on data type and refresh only when needed.

Use cursor-based pagination efficiently

Most list endpoints in the Instagram API use cursor-based pagination. Each response includes a cursor that you use to fetch the next page.

# First request
/v22.0/{ig-user-id}/media?limit=25&access_token={token}

# Next page
/v22.0/{ig-user-id}/media?limit=25&after={after-cursor}&access_token={token}

Each page request counts as a separate API call.

To reduce total requests:

  • Use the highest reasonable limit value
  • Avoid fetching more pages than necessary

Fetching 100 items in one call is more efficient than making multiple smaller requests.

Handle rate limit errors with exponential backoff

When you hit a 429 error, retrying immediately usually makes things worse. Instead, use exponential backoff to space out retries.

async function callWithBackoff(apiFn, maxRetries = 5) {
  let delay = 1000;
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    try {
      return await apiFn();
    } catch (err) {
      if (err.code === 429 && attempt < maxRetries - 1) {
        await new Promise(resolve => setTimeout(resolve, delay));
        delay *= 2;
        delay += Math.random() * 500;
      } else {
        throw err;
      }
    }
  }
}

The small random delay (jitter) helps avoid multiple processes retrying at the same time, which can create spikes and trigger limits again.

Common Instagram API Errors and how to fix them

The Instagram Graph API returns structured error objects. Here’s what a typical error response looks like:

{
  "error": {
    "message": "Invalid OAuth access token.",
    "type": "OAuthException",
    "code": 190,
    "error_subcode": 460,
    "fbtrace_id": "AbCdEf123456"
  }
}

The most common error codes you’ll encounter:

Code TypeMeaningAction
190OAuthExceptionInvalid or expired tokenRefresh token or re-authenticate user
200 – 299OAuthExceptionMissing permissionsRequest required scope from user
100GraphMethodExceptionInvalid parameter or requestCheck your request structure
17OAuthExceptionRate limit hitBack off and retry
368OAuthExceptionAccount blocked or restrictedContact Meta support
10OAuthExceptionPermission denied (app-level)App not approved for permission

The error_subcode field provides more granular context within a top-level code. Code 190 with subcode 460 means the password was changed after the token was issued; subcode 467 means the token expired. Use subcodes for specific handling logic.

Save the fbtrace_id in your logs; it’s Meta’s internal trace ID and is required when filing support tickets about specific API errors.

A robust error handling wrapper in practice:

async function callGraphAPI(endpoint, params) {
  const response = await fetch(`https://graph.facebook.com/v22.0/${endpoint}`, {
    params: { ...params, access_token: getToken() }
  });
  const data = await response.json();
  
  if (data.error) {
    const { code, error_subcode, fbtrace_id } = data.error;
    logError({ code, error_subcode, fbtrace_id, endpoint });
    
    if (code === 190) {
      await refreshOrReauthenticate();
      return callGraphAPI(endpoint, params); // One retry after refresh
    }
    if (code === 17 || response.status === 429) {
      throw new RateLimitError(data.error);
    }
    throw new APIError(data.error);
  }
  
  return data;
}

How to migrate from Instagram Basic Display API to Graph API

If you have any integrations still running on the Basic Display API infrastructure, or built before December 2024, this section is for you. The migration isn’t optional: the API is gone, and old tokens have been invalid since December 4, 2024.

What changed from Basic Display API to Instagram Graph API

The Basic Display API provided access to personal Instagram accounts with minimal setup. You could read a user’s media feed, profile info, and basic metadata without requiring a Business account or Facebook Page connection. That’s all gone.

The Instagram Graph API replacement requires:

  • Instagram Business or Creator account (not personal)
  • Facebook Page connection (for most features)
  • App review for permissions beyond basic read access
  • Stricter token scoping and permission declarations

Migration steps from Basic Display API to Instagram Graph API

Follow these steps below to migrate from Basic Display API to Instagram Graph API:

  • Step 1: Audit your existing integrations. List every integration point: what data you were fetching, which accounts were connected, and what your app was doing with that data. Map each use case to an equivalent in the Instagram Graph API.
  • Step 2: Convert accounts. Every personal Instagram account your integration was accessing needs to be converted to a Business or Creator account. Users can do this in the Instagram app under Account Settings → Switch to Professional Account. There’s no API method for this.
  • Step 3: Connect to a Facebook Page. Each Instagram Business account needs to be linked to a Facebook Page for most API features. This is done in the Instagram app under Account Settings → Linked Accounts → Facebook. Creator accounts have more flexibility, but Business accounts typically require this connection.
  • Step 4: Update your OAuth flow. Replace the Basic Display API authorization endpoint with either Instagram Business Login or Facebook Login for Business. Update all scopes as well, since older scopes like user_profile and user_media are no longer supported.
  • Step 5: Update your endpoints. Replace endpoints like graph.instagram.com/me/media with graph.facebook.com/v22.0/{ig-user-id}/media. You’ll also need to update field names and request structures, as some responses have changed.
  • Step 6: Submit for app review. If your app is used by external users, you’ll need to go through Meta’s app review process. This includes providing a use case, a privacy policy, and details on how your app handles user data.

Common pitfalls while migrating from the Basic Display API

A common mistake is assuming you can just replace the base URL and keep everything else the same. In reality:

  • ID formats are different
  • Field names may not match
  • Pagination works differently
  • Response structures have changed

You’ll need to review each integration point instead of doing a quick swap.

WP Social Ninja Newsletter Subscription
Subscribe to Our Newsletter

Get exclusive social media marketing tips and tutorials in your inbox!

Blog subscribe form

Advanced Instagram APIs for specialized use cases

The Instagram Graph API covers most core use cases, but some features like messaging, ads, and shopping are handled through separate APIs. You’ll need these when your integration goes beyond content and analytics.

Instagram Messaging API (via Messenger Platform)

The Instagram Messaging API works through the Messenger platform and is used for handling DMs programmatically. It’s commonly used in support systems, chat automation, and lead handling tools.

It allows you to:

  • Receive messages in real time using webhooks
  • Reply to users with text, media, and structured messages
  • Manage conversations across multiple users

There are two important limits to keep in mind:

  • You can only reply to users who message you first
  • You can only respond within 24 hours of their last message

DM limits, like 200 automated messages per hour, also apply alongside general Instagram API rate limits.

Instagram Ads API (via Marketing API)

The Ads API is part of Meta’s Marketing API and is used for managing Instagram ad campaigns.

With this API, you can:

  • Create and manage campaigns targeting Instagram users
  • Track performance metrics like reach, clicks, and conversions
  • Control budgets and bidding strategies programmatically

This is mainly useful for agencies, marketing platforms, and businesses running ads at scale. It also requires additional permissions and approval from Meta.

Instagram Shopping API

The Instagram Shopping API is used for eCommerce integrations. It allows you to connect a product catalog and tag products directly in posts and stories.

Product tagging happens during media creation:

curl -X POST "https://graph.facebook.com/v22.0/{ig-user-id}/media" \
  -d "image_url=https://example.com/product-photo.jpg" \
  -d "caption=Shop the look" \
  -d 'product_tags=[{"product_id":"123456","merchant_id":"789","x":0.5,"y":0.5}]' \
  -d "access_token={token}"

This setup relies on a Facebook Product Catalog connected to your Instagram account.

The easiest way to add Instagram feeds to WordPress

If you’re an agency or WordPress developer, building Instagram features with the Instagram Graph API can get complex and time consuming. WP Social Ninja removes that overhead so you can deliver working integrations without handling the backend.

WP Social Ninja's Instagram Feed integration landing page

WP Social Ninja is a complete WordPress Instagram plugin that connects directly with the Instagram Graph API and handles everything in the background.

You can display feeds, videos, and hashtag content on your site with full control over layout and behavior. It’s built to be simple to set up, flexible to customize, and reliable in performance.

Key features of WP Social Ninja that you will like:

  • Display multiple feeds from different Instagram accounts
  • Filter feeds by hashtag, keyword, or content type
  • Create shoppable feeds by linking posts to product pages
  • Use ready-made templates for faster setup
  • Customize layouts, headers, and profile sections
  • Show posts in popups or redirect users to Instagram
  • Built-in caching for better performance
  • Image optimization and local storage for faster loading
  • GDPR-compliant setup for user privacy
  • No-code configuration with an easy dashboard

Most importantly, you can start for free with WP Social Ninja to embed Instagram feeds. To access its advanced features, you’ll need to upgrade to its pro version that starts from $44 per year after discount.

And if you need to visualize how far you can customize an Instagram feed on WordPress, feel free to check the demo page.

Win your customers’ hearts with exceptional features

Discover how WP Social Ninja can assist you in designing outstanding customer experiences.

Demo image

Wrapping up

The Instagram Graph API is now the standard way to build on Instagram. With the Basic Display API gone, everything runs through Business and Creator accounts, structured authentication, and defined permissions.

To use it effectively, you need to understand how authentication, rate limits, endpoints, and webhooks work together. Once you apply batching, caching, and field filtering, managing the API becomes much easier.

If you don’t want to handle all that complexity, tools like WP Social Ninja simplify the process. Otherwise, the key is simple: design around the limits and structure your requests properly.

SocialNinja Subscribe

Subscribe To Get

Weekly Email Newsletter

Blog subscribe form

Connect, Customize, and Display Social Feeds, Reviews, and Chat widgets

Social Ninja feed reviews and chat
trending posts

Trending Posts

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *