Building your own Instagram feed with the Instagram API: what’s involved

If you have a developer on your team, building your own Instagram feed can look like a small job: call an API, get some photos, put them in a grid. The rendering part really is small. Most of the work sits around it: a Meta app, access levels and possibly App Review, a login flow, tokens that expire, caching, rate limits and upkeep. This article walks through each part using Meta’s own documentation, so you can estimate the effort honestly and decide whether to build or use a hosted widget.

Updated October 12, 2026

The short answer

Building a feed of your own Instagram account’s posts is entirely possible. Meta documents the whole path, and for an account you own or manage you do not need App Review. You will need a Meta developer account, an app of the Business type, a server-side component that keeps your app secret and tokens away from visitors, a job that refreshes the token before it expires every 60 days, a cache so you do not call Instagram on every page view, and someone who notices when the connection breaks.

If the feed will serve Instagram accounts that you do not own or manage, such as your clients’ accounts or your customers’, the project grows: Meta requires Advanced Access, which means App Review and Business Verification.

Which API you would use

The old Instagram Basic Display API, which many tutorials still describe, no longer works. Our article on the Basic Display API shutdown explains what changed. Today Meta offers two setups for professional accounts:

Instagram API with Instagram LoginInstagram API with Facebook Login
How people sign inWith their Instagram credentialsWith Facebook, through a Facebook Page linked to the Instagram account
Facebook Page neededNoYes
Accounts supportedInstagram professional accounts (Business or Creator)Instagram professional accounts linked to a Page
Typical fit for a website feedSimplest path for showing your own postsUseful if you already work with Pages and Facebook Login

For a website feed, the Instagram Login setup is usually the simpler choice, because it does not require a linked Facebook Page. The rest of this article follows it. Our explainer on Instagram API with Instagram Login covers the permissions in plain English. Personal accounts are not supported by either setup; Meta’s media reference states that only media owned by Instagram professional accounts is returned. If your account is personal, see switching to a professional account.

What you need before you start

  1. An Instagram professional account whose posts you want to show.
  2. A Meta developer account and access to the Meta App Dashboard.
  3. A Meta app of the Business type. Meta’s getting-started guide says that if your app is not a Business type app, you need to create a new one and choose Business during creation.
  4. Server-side code. Token requests include your app secret, and Meta says requests for long-lived tokens must be made in server-side code. A purely static site cannot do this part on its own; you need a server, a serverless function or a scheduled job somewhere.
  5. A privacy policy URL and a way to request data deletion. Meta requires apps that access user data to give people a way to request deletion of their data, either with an instructions page or with a callback URL set in the app’s basic settings.

Step 1: create and configure the Meta app

In the App Dashboard you create the app, add the Instagram product, and open the section Meta calls “API setup with Instagram business login”. Two things there matter for a feed.

First, the dashboard can generate a token for testing. Meta’s getting-started guide describes a “Generate token” button: you log in with the Instagram account, and the dashboard gives you a token that lasts 60 days. That is handy for a first prototype, because you can call the API before you build any login flow.

Second, the Business login settings hold your OAuth redirect URIs: the addresses Instagram may send people back to after they approve your app. Meta notes that the redirect URI in a request must exactly match one of the URIs in this list, and that the dashboard may add trailing slashes, so copy it carefully. A mismatch is one of the most common reasons a first login attempt fails.

Step 2: access levels and App Review

Every Meta app starts with Standard Access. Meta describes it as the default access level that limits the data your app can get, intended for apps used by people who have a role on the app. Advanced Access is required when your app serves professional accounts that you do not own or manage.

Your situationAccess levelApp ReviewBusiness Verification
Your own business’s account, used by people with roles on the appStandard AccessNot requiredNot required
Accounts of other businesses (clients, customers, anyone without a role)Advanced AccessRequiredRequired

If you only show your own account, add the people who manage that account to the app’s roles and stay on Standard Access. If you need Advanced Access, plan for the App Review submission. According to Meta’s Instagram App Review page, for each permission you request you:

  1. Upload a screencast showing the end-to-end user experience for that permission, with English as the interface language if possible, and captions where parts are not self-explanatory.
  2. Describe step by step how your app uses the permission, and agree to comply with its allowed usage.
  3. Give reviewers instructions, and test credentials if needed, so they can log in and test your app. Meta warns that if reviewers cannot access your app, the whole submission is rejected.
  4. Make at least one successful API call with the permission before requesting Advanced Access for it.
  5. Provide your privacy policy URL.

Meta also says that requesting permissions your app does not use, or uses outside the allowed usage, leads to rejection. For a feed, that means asking only for what reading your posts requires: in this setup, the instagram_business_basic permission. Business Verification, which Meta requires for Advanced Access, is completed in Business Manager by an admin of your business and asks for documents about the business. Meta does not publish a fixed review time, so leave room in your schedule.

Step 3: the login flow and tokens

Even for your own account, you need a way to get a long-lived token and to get a new one when it is cancelled. Meta’s Business Login for Instagram works in four moves:

  1. Send the account owner to Instagram. The App Dashboard gives you an embed URL to put behind a button. The person signs in and approves your app.
  2. Receive an authorization code at your redirect URI. Meta says this code is valid for one hour and can be used only once.
  3. Exchange the code for a short-lived token with a POST request to Instagram’s token endpoint, from your server. Meta describes short-lived tokens as valid for one hour.
  4. Exchange the short-lived token for a long-lived one, again from your server. Meta says the long-lived token is valid for 60 days.
# 3. Code -> short-lived token (server side)
POST https://api.instagram.com/oauth/access_token
  client_id, client_secret, grant_type=authorization_code,
  redirect_uri, code

# 4. Short-lived -> long-lived token (server side)
GET https://graph.instagram.com/access_token
  ?grant_type=ig_exchange_token
  &client_secret=APP_SECRET
  &access_token=SHORT_LIVED_TOKEN

Store the long-lived token on the server, never in your page’s HTML or JavaScript. Anyone who can see the token can read what it allows, and the app secret must never reach a browser or an app binary at all. This is why a “just fetch it in the browser” approach does not work for a public website.

Step 4: fetch the posts

With a token, the requests themselves are simple. Meta’s getting-started guide first asks for the account’s ID and username from /me, then lists media from the account’s /media edge. Each media object can return the fields a feed needs:

GET https://graph.instagram.com/me
  ?fields=user_id,username,profile_picture_url,media_count
  &access_token=TOKEN

GET https://graph.instagram.com/IG_ID/media
  ?fields=id,media_type,media_url,thumbnail_url,permalink,
          caption,timestamp,children{media_type,media_url,thumbnail_url}
  &access_token=TOKEN

A few details from Meta’s media reference shape the front end:

FieldWhat to know
media_typeIMAGE, VIDEO or CAROUSEL_ALBUM. Carousels need their children fetched to show more than one image.
media_urlOmitted when the media contains copyrighted material, for example Reels with copyrighted audio. Your code must handle a post without it.
thumbnail_urlOnly available on VIDEO media. Use it as the tile image and poster for videos.
permalinkThe link to the post on Instagram. Not available on carousel children.
like_countOmitted if the owner has hidden like counts.
timestampISO 8601 in UTC. Convert before showing dates or filtering by period.

The response is paginated with cursors. If you filter posts, for example leaving out videos, fetch more than you plan to show so that a filter does not leave your grid half empty.

Step 5: refresh tokens and handle broken connections

A long-lived token lasts 60 days. Meta’s refresh endpoint extends it by another 60 days from the refresh date, with two conditions: the token must be at least 24 hours old, and it must not have expired yet. An expired token cannot be refreshed; the owner has to sign in again.

GET https://graph.instagram.com/refresh_access_token
  ?grant_type=ig_refresh_token
  &access_token=LONG_LIVED_TOKEN

In practice you schedule a job that refreshes the token well before day 60 and saves the new expiry date. A cron job that runs weekly is enough. Then you plan for the case a refresh cannot fix: a token cancelled early. Meta’s error reference lists code 190 for an expired token, with subcodes such as “Password Changed” and “Expired” for tokens that were revoked or are invalid. When that happens:

  1. Keep showing the last good copy of the feed for a while, or hide the section, rather than showing a broken box.
  2. Alert a person: an email or a message to whoever can sign in to the Instagram account.
  3. Give that person a simple reconnect button that runs the login flow from Step 3 again.

The most common trigger is an ordinary password change. Our article on why a password change can disconnect a website feed explains the account owner’s side, and Instagram access token expired covers the 60-day lifecycle.

Step 6: caching and rate limits

Do not call Instagram on every page view. Fetch on your server, store the result, and serve the stored copy. This keeps your token private, makes the feed faster, and keeps you well inside Meta’s limits.

Meta’s rate-limiting documentation describes the Instagram limit as a rolling 24-hour window for each app and app user pair, calculated as “Calls within 24 hours = 4800 * Number of Impressions”, where impressions are the number of times content from the account appeared on someone’s screen in the past 24 hours. Calls that count against this limit return an X-Business-Use-Case-Usage header with usage percentages and an estimated time to regain access, and going over returns error code 80002. Generic throttling errors use codes 4 and 17, which Meta tells you to handle by waiting and retrying.

For a feed that shows a handful of new posts a week, a cache that refreshes every few hours is plenty, and you will rarely come near the limit. Two practical rules:

  1. Refresh the cache on a schedule or on demand, not on the first visitor after expiry, so that no visitor waits for Instagram.
  2. Do not treat media URLs as permanent. Images and videos are served from Instagram’s servers, and Meta’s media reference does not document how long a given URL stays valid. Fetch fresh data regularly rather than storing URLs for months, and read Meta’s developer terms before copying media files to your own storage.

Step 7: build the front end

This is the part most people picture, and it is still more than a grid. A feed that works well on a real website needs:

  1. A responsive layout that changes columns at phone widths and keeps tiles square.
  2. Reserved space, so the page does not jump when images arrive. See avoiding layout shift from social widgets.
  3. Lazy loading for images below the fold, covered in lazy loading an Instagram feed.
  4. Video and carousel handling, using thumbnails for tiles and a viewer or a link for playback.
  5. Accessibility basics: meaningful link text, keyboard focus, and text alternatives. The API offers an alt_text field, but many posts have none, so decide how you describe images when it’s missing. Our article on Instagram alt text discusses the options.
  6. A Content Security Policy update, if your site uses one, so Instagram’s image hosts are allowed. See CSP and Instagram widgets.

Step 8: keep it running

After launch, a feed you built is a small product you maintain. Meta versions its Graph API and retires old versions and permissions over time. The Basic Display API shutdown is the best-known example, and Meta also replaced the older business_basic scope values with instagram_business_basic and set a deprecation date for the old ones. Someone needs to watch Meta’s changelog, answer notices about your app in the App Dashboard, handle data deletion requests, and fix the feed when something changes.

The effort at a glance

PartOne-time workOngoing work
Meta app and settingsDeveloper account, Business app, Instagram product, redirect URIsRespond to Meta notices and policy updates
Access and reviewRoles for Standard Access, or App Review and Business Verification for Advanced AccessKeep permissions in line with actual use
Login and tokensLogin button, code exchange, long-lived token, secure storageScheduled refresh; reconnect flow for cancelled tokens
Fetching and cachingMedia request, pagination, filtering, cache storageMonitor errors and rate-limit headers
Front endLayout, lazy loading, video, accessibility, CSPDesign tweaks as the site changes
CompliancePrivacy policy, data deletion instructions or callbackHandle deletion requests; follow API version changes

When building your own makes sense

Building is a good choice when the feed is part of something larger. For example, when you already run a Meta app for other Instagram features such as publishing or comments, when Instagram data feeds into your own systems, when your design needs something no widget offers, or when company policy requires that every request to third parties goes through your own servers. In those cases the setup work is shared with other features, and the control is worth it.

It also makes sense as a learning project. Meta’s documentation is thorough, and the token and caching patterns carry over to many other APIs.

When a hosted widget makes sense

If the goal is simply to show your latest posts on your website, a hosted widget takes over the parts that are not about your website: the Meta app, the review, the token handling and the upkeep. That is the trade-off any hosted service offers, and it suits small teams, agencies who want the same setup across many client sites, and sites built on platforms where adding a server is not an option.

Here is how Social Feed by grip space handles the parts described above:

PartSocial Feed by grip space
Meta app and reviewOperated by us. You sign in with Instagram and approve read access to your profile and posts.
TokensStored on our servers, never in your page. Renewed automatically before the 60-day expiry; the dashboard tells you if Instagram cancels one early.
Caching and updatesFree plan: posts on your site update once a day. Paid plans: posts are read when the feed loads.
EmbedOne script tag. The feed renders next to it, without an iframe, and the widget sets no cookies.
Layout and optionsGrid or slider, columns, post count, spacing, width, account header, Follow button, lightbox, and filters for Reels, carousels, videos, period and caption keywords.

The Free plan includes 1 widget with up to 16 posts and 3,000 views a month, with a “Powered by Social Feed” credit. Paid plans raise those limits; see plans and pricing. Hosted widgets have limits too: Social Feed shows the posts of the accounts you connect yourself, one account per feed, and does not offer hashtag feeds, Stories, or alt text for images. If you need one of those, building your own or another tool may suit you better. Our Instagram feed widget comparison lays out several options side by side.

And if you only want to show one or two specific posts, Instagram’s own embed may be all you need. See embedding a single Instagram post.

Frequently asked questions

Can I call the Instagram API directly from JavaScript in the browser? Not safely. The token exchange needs your app secret, which Meta says must stay in server-side code, and a long-lived token placed in a page can be copied by any visitor. A server, serverless function or build step has to sit in between.

Do I need App Review to show my own posts? According to Meta’s App Review page, not for an app used only for a business you own or manage, under Standard Access. App Review is needed for Advanced Access, which is required to serve accounts you do not own or manage.

Do I need a Facebook Page? Not with the Instagram API with Instagram Login. The Facebook Login setup requires a Page linked to the Instagram account.

Can I show a personal account? No. Meta returns media only for Instagram professional accounts, Business or Creator.

Can I generate the token once and forget it? No. Long-lived tokens last 60 days and must be refreshed while still valid. Even with refreshes, a token can be cancelled early, for example by a password change, and then someone must sign in again.

Can a static site generator do it at build time? Yes, if the build runs on a server you control and keeps the token there. You then rebuild on a schedule to pick up new posts and still need the refresh job.

Related reading

For the bigger picture on placing feeds without plugins, read adding an Instagram feed without a plugin. To compare loading behavior, see Instagram embed vs widget speed. If you decide on a hosted widget, learn what Social Feed by grip space is or sign up for free.

Sources

  1. Meta for Developers, “Instagram API with Instagram Login”: https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/
  2. Meta for Developers, Instagram Platform “Overview”: https://developers.facebook.com/docs/instagram-platform/overview/
  3. Meta for Developers, “Get Started” (Instagram API with Instagram Login): https://developers.facebook.com/documentation/instagram-platform/instagram-api-with-instagram-login/get-started.md
  4. Meta for Developers, “Business Login for Instagram”: https://developers.facebook.com/docs/instagram-platform/instagram-api-with-instagram-login/business-login
  5. Meta for Developers, Instagram Platform “App Review”: https://developers.facebook.com/documentation/instagram-platform/app-review.md
  6. Meta for Developers, “Business Verification”: https://developers.facebook.com/docs/development/release/business-verification/
  7. Meta for Developers, “Refresh Access Token”: https://developers.facebook.com/docs/instagram-platform/reference/refresh_access_token/
  8. Meta for Developers, “IG Media” reference: https://developers.facebook.com/docs/instagram-platform/reference/instagram-media/
  9. Meta for Developers, Graph API “Rate Limits”: https://developers.facebook.com/docs/graph-api/overview/rate-limiting/
  10. Meta for Developers, Graph API “Error Handling”: https://developers.facebook.com/docs/graph-api/guides/error-handling/
  11. Meta for Developers, “Get Started” (Instagram API with Facebook Login): https://developers.facebook.com/documentation/instagram-platform/instagram-api-with-facebook-login/get-started.md
  12. Meta for Developers, “Data Deletion Callback”: https://developers.facebook.com/docs/development/create-an-app/app-dashboard/data-deletion-callback/

Get your embed code in a few minutes. The Free plan needs no credit card.

Sign up free