Some are essential for FeedFusion to work. Others help us see how the product gets used. Pick what you're okay with.
FeedFusion is an Instagram API layer I started building in September 2024 because I wanted to understand the Instagram Graph API space properly, and the only way to really understand it was to build something with it. It went live first on hospitality client sites in Portugal, behind the scenes, before becoming a public product. Today it is an API and widget you can use to add an Instagram feed to your website in about three minutes.
Honestly? Because I had a bunch of client sites that all wanted the same thing: an Instagram feed on their website. The problem isn't building it once, it's keeping it alive. Tokens expire every 60 days, Meta changes the rules on its own timeline, and feeds can quietly go dark on a Friday night while nobody's looking. So instead of dealing with that mess site by site, I built one tool to handle all of them. Twenty months later, it's running on hospitality and creative sites across Portugal.
There are two ways to use it, depending on how much control you want.
The JSON API returns your Instagram feed as clean, structured data. You call an endpoint, you get JSON back with post IDs, captions, permalinks, media types, media URLs, and timestamps. You render it however you want, in whatever framework or design system you already use. This path is for developers who want full control over the output, or who are working in a framework where a pre-built widget won't integrate cleanly.
The embeddable widget is for when you just want the feed on the page without writing a custom component. One script tag, one container element. The feed renders client-side, styled via CSS classes you can override. This path works for anyone who can paste HTML, whether you're a developer, a freelancer, or a business owner managing your own site.
In both cases, you connect your Instagram account once through an OAuth flow. After that, FeedFusion handles token generation and the 60-day refresh cycle in the background. The feed keeps serving content. You don't think about it again.
The people FeedFusion works best for are developers and small agencies building websites for clients. If you're managing two or more sites that need Instagram feeds, the per-site token maintenance overhead adds up fast. FeedFusion handles that overhead once, across all your feeds, from a single account.
It also works for independent business owners who manage their own website and want their Instagram feed embedded without needing to call a developer every time an access token expires.
I want to be equally clear about who it is not for. If you need a no-code editor to design widget templates visually, FeedFusion doesn't have that. The widget styling is CSS-based, not drag-and-drop. If you're running an enterprise team that needs white-label resale or a fully customized dashboard under your own brand, that's not what FeedFusion is built for either.
The honest positioning: FeedFusion is a developer-first managed API with a widget option. It fits well when you want reliability and API access without building and maintaining the infrastructure yourself. It doesn't fit when you need a visual builder or an enterprise-grade platform.
There are two paths: the widget embed and the JSON API. Pick the one that fits your project.
Step 1. Sign up and connect your Instagram account
Create a free account at feed-fusion.com/sign-up. In your dashboard, connect your Instagram account through the OAuth flow. This is a one-time step. After connecting, you get two values you'll use in the embed: your Instagram username (the one tied to the account you just connected) and a public key (a non-secret token FeedFusion generates so the widget knows the feed is yours).
Step 2. Paste the snippet into your page
Add this to the page where you want the feed:
Replace YOUR_INSTAGRAM_USERNAME and YOUR_PUBLIC_KEY with the values from your dashboard. data-feedfusion-columns and data-feedfusion-gap are optional. They default to 3 columns and 1rem gap if you leave them out.
That's it. When the page loads, the widget calls the FeedFusion API, fetches your feed, and renders the grid client-side. The script picks up every element with a data-feedfusion-username attribute, so you can render multiple feeds on the same page if you need to.
To restyle the output, target the CSS classes the widget applies. .feed-fusion-feed on the grid container, .feed-fusion-post on each cell, .feed-fusion-media on each image or video thumbnail. Standard CSS overrides everything.
Step 1. Sign up and get your username and public key
Same starting point: feed-fusion.com/sign-up. Connect your Instagram account. From the dashboard, copy your username and public key.
Step 2. Fetch the endpoint
The feed endpoint returns your Instagram posts as a JSON object. The public key goes in the URL as a query parameter, not in a header. That's by design, so you can call this from the browser without exposing a server-side secret:
Step 3. Render however you want
Map over data.posts and build whatever component fits your stack. A basic React example:
Note mediaType values from the Instagram API: IMAGE, VIDEO, CAROUSEL_ALBUM. For VIDEO posts, the production widget uses thumbnailUrl as the displayed image so the grid stays consistent across media types. optimizedMediaUrl is FeedFusion's CDN-mirrored copy of the asset when available, falling back to Instagram's CDN otherwise. The example above mirrors that pattern.
For Next.js Server Components specifically, you can fetch server-side in the page component and pass posts down as props. A future post covers that pattern in detail.
The JSON API is available on the free tier. You don't need a paid plan to build with it. Full reference (response schema, query options, rate limits) is in the API docs.
Three tiers. All start on the free tier, no credit card required.
Free, €0/month. One feed. 10,000 views per month. Full JSON API access. Widget embed included. Attribution badge ("Powered by FeedFusion") on the widget. Good for testing, personal projects, and single-client setups.
Pro, €5/month (or €48/year, save 20%). Five feeds. 100,000 views per month. JSON API and widget embed. Attribution badge removed. Email support with 48-hour response. The right fit for developers managing 2-5 client sites.
Agency, €15/month (or €144/year, save 20%). Unlimited feeds. No view cap. Attribution badge removed. Priority email support with 24-hour response. One account covers every client site you will ever manage.
All plans include automatic token rotation. There is no plan where you manage tokens manually.
Yes. Instagram access tokens expire every 60 days. FeedFusion rotates each token before it reaches expiry, so feeds never silently go dark between your check-ins. You connect your Instagram account once during setup and never touch the token again.
Yes, in two ways. The widget exposes CSS classes on the feed container and individual post elements, so you can control layout, grid columns, image sizing, and hover states through standard CSS. The JSON API gives you the raw post data and leaves rendering entirely up to you, in your own component and your own markup.
The Agency plan is built for that. Unlimited feeds, one account, one dashboard where every client's Instagram connection is visible and managed. When a new client site needs a feed, you add it in the dashboard, copy the embed snippet (or the username and public key for the JSON API), and paste it in. Adding a new feed takes about three minutes. The Pro plan supports up to five feeds if you're managing a smaller number of client sites.
FeedFusion caches feed data from the Instagram API to serve it reliably and within API rate limits. It doesn't store your Instagram credentials. The OAuth flow uses Instagram's official authentication; FeedFusion holds the resulting access token (to perform refreshes) but not your password or account login. Full details are in the Privacy Policy.
If Instagram revokes access (for example, after a password change or a manual permissions review), the feed will stop updating. Reconnecting is the same OAuth flow as the initial setup: go to your dashboard, reconnect the affected feed, and follow the prompt. Your username and public key stay the same, so nothing needs to change on your site.
JSON API reference, widget customisation, framework integrations.
Read the docs<script src="https://www.feed-fusion.com/widget.js" defer></script>
<div data-feedfusion-username="YOUR_INSTAGRAM_USERNAME"
data-feedfusion-public-key="YOUR_PUBLIC_KEY"
data-feedfusion-columns="3"
data-feedfusion-gap="1rem"></div>const response = await fetch(
`https://www.feed-fusion.com/api/feeds/YOUR_INSTAGRAM_USERNAME?publicKey=YOUR_PUBLIC_KEY`
);
const data = await response.json();
// data.username: the connected Instagram username
// data.meta: { tier, total, limit, offset, cacheTtl }
// data.posts: array of Instagram post objects
// Each post: { id, timestamp, permalink, mediaType, mediaUrl, thumbnailUrl, optimizedMediaUrl, caption }export default function InstagramFeed({ posts }) {
return (
<ul className="instagram-grid">
{posts.map(post => {
const fallback = post.mediaType === 'VIDEO'
? (post.thumbnailUrl || post.mediaUrl)
: post.mediaUrl
const src = post.optimizedMediaUrl || fallback
return (
<li key={post.id}>
<a href={post.permalink} target="_blank" rel="noopener noreferrer">
<img
src={src}
alt={post.caption ?? 'Instagram post'}
loading="lazy"
/>
</a>
</li>
)
})}
</ul>
);
}