FeedFusionDocs
Get started free

API Reference

GET /feeds/{username} returns your Instagram posts as a JSON array. Responses are cached at the edge, authenticated with a public-key query parameter, and work in any framework.

A single GET endpoint serves the cached feed for a connected Instagram account. The endpoint is CORS-open and authenticates with a public-key query parameter. Below is the full surface.

Endpoint

 
http
GET https://www.feed-fusion.com/api/feeds/{username}?publicKey={publicKey}

The username path segment is your Instagram handle (the same one shown on the feed page in your dashboard). The publicKey query parameter is a 32-character hex string from the same dashboard page. Both must match a single connected feed; mismatched pairs return 403.

Query parameters

PropTypeDefaultDescription
publicKeystringrequired32-character hex from your dashboard. Tied to the username path segment.
limitnumber (1 to 100)24Posts to return in this response. Out-of-range values clamp to the bounds.
offsetnumber (0 or greater)0Starting index of the slice. Use with limit for pagination.

Example response

 
json
{
  "username": "your-instagram-handle",
  "meta": {
    "tier": "free",
    "total": 28,
    "limit": 12,
    "offset": 0,
    "cacheTtl": 3600
  },
  "posts": [
    {
      "id": "18418647295121497",
      "timestamp": "2026-04-02T09:49:14+0000",
      "permalink": "https://www.instagram.com/p/DWn_VzyDB65/",
      "mediaType": "IMAGE",
      "mediaUrl": "https://scontent-iad3-1.cdninstagram.com/...",
      "thumbnailUrl": null,
      "caption": "..."
    }
  ]
}

Response fields

Top-level:

PropTypeDefaultDescription
usernamestringrequiredEchoes the username from the URL. Useful for logging.
metaobjectrequiredPagination + tier + cache info (see below).
postsPost[]requiredArray of post objects (see below). May be empty if the account has no posts yet.

meta object:

PropTypeDefaultDescription
tier"free" | "pro" | "agency"requiredThe subscription tier of the feed's owner. Use it to drive tier-aware client behaviour if needed.
totalnumberrequiredTotal posts available in the cached feed, before applying limit/offset. Use to detect when pagination ends.
limitnumberrequiredPosts actually returned in this response. Matches the limit query param after clamping.
offsetnumberrequiredStarting index of this slice. Matches the offset query param.
cacheTtlnumberrequiredEdge cache TTL in seconds (3600 at time of writing). Match your client-side cache to this for the most efficient setup.

post object:

PropTypeDefaultDescription
idstringrequiredInstagram post ID. Stable; use as React key.
timestampstringrequiredISO 8601 timestamp from Instagram (e.g. "2026-04-02T09:49:14+0000").
permalinkstringrequiredPublic Instagram URL for the post. Link to this on click.
mediaType"IMAGE" | "VIDEO" | "CAROUSEL_ALBUM"requiredType of post.
mediaUrlstringrequiredDirect URL to the media file. For VIDEO posts, this is the video file; for IMAGE posts, the image.
thumbnailUrlstring | nullrequiredCover image for VIDEO and CAROUSEL_ALBUM. null for plain IMAGE posts (use mediaUrl directly).
captionstring | nullrequiredPost caption. Can be null for posts without text.

Response headers

PropTypeDefaultDescription
X-Ratelimit-LimitnumberrequiredPer-minute rate limit cap for this publicKey (600 at time of writing).
X-Ratelimit-RemainingnumberrequiredRequests remaining in the current sliding-window minute.
X-Ratelimit-ResetnumberrequiredUnix timestamp (seconds) when the rate limit window resets.
Retry-AfternumberSeconds to wait before retrying. Only present on 429 responses.
Access-Control-Allow-OriginstringrequiredAlways *. CORS-open for browser-side widgets.
Access-Control-Expose-HeadersstringrequiredExposes the four X-Ratelimit-* and Retry-After headers to browser JavaScript.

Status codes

PropTypeDefaultDescription
200OKrequiredReturns the feed JSON. Rate-limit headers populated.
400Bad RequestrequiredMissing username or publicKey query parameter.
403ForbiddenrequiredUsername and publicKey don't match a connected feed. Returned without consuming rate-limit quota; invalid pairs are typically bots.
429Too Many RequestsrequiredEither the per-minute rate limit (600/min by publicKey) or the monthly plan view limit was exceeded. Retry-After header tells you when to retry.
500Internal Server ErrorrequiredDatabase error or other upstream failure. Captured in our error monitoring; retry with backoff.

Rate limits

The endpoint allows up to 600 requests per minute per publicKey, on a sliding window. That's more than enough for any normal site traffic; we built it to absorb traffic spikes without throttling the legitimate visitors.

Monthly view caps apply on top of per-minute rate limits:

PropTypeDefaultDescription
Freetierrequired10,000 widget views per month, 10 manual refreshes per month.
Protierrequired100,000 widget views per month, 100 manual refreshes per month.
AgencytierrequiredUnlimited views, unlimited manual refreshes.

Caching and CORS

Responses are cached at the edge for one hour (see meta.cacheTtl). The endpoint is fully CORS-open for browser embeds; you can call it from client-side JavaScript, server-side Node, mobile apps, anywhere.

Questions? hello@feed-fusion.com

Continue reading