Social media aggregator API: How to build a unified social feed for your app
How to build a unified social media feed that pulls content from Instagram, X, LinkedIn, TikTok, YouTube, and Facebook into one view — the read-side aggregation landscape, native API challenges, and how to pair it with write-side publishing.
Two feeds, one screen
You are building a dashboard for an agency. Or a content hub for a brand. Or a customer portal that shows social proof. The requirement is always the same: pull content from multiple social platforms and display it in one place.
Instagram posts, X threads, LinkedIn articles, TikTok videos, YouTube Shorts, Facebook updates — all rendered in a single chronological feed inside your application. No switching between tabs. No asking users to log into five different platforms.
This is a social media aggregator. And on the surface, it sounds like a solved problem. Every platform has an API. You call each one, merge the results, render the feed. Ship it.
In practice, it is an integration project that keeps growing. Each platform returns content in a different shape. Authentication models diverge. Rate limits collide. Pagination schemes conflict. Media URLs expire. And that is just the read side — pulling content in. When your users need to respond, schedule, or publish from the same interface, you are building a second integration layer on top of the first.
The read side: pulling feeds from each platform
Instagram (Graph API)
Instagram exposes user media through the Graph API. Business and Creator accounts can retrieve their feed via GET /{user-id}/media:
curl "https://graph.facebook.com/v21.0/{user-id}/media?fields=id,caption,media_type,media_url,thumbnail_url,timestamp,permalink&access_token={token}"Returns up to 25 posts per page with cursor-based pagination. Media types include IMAGE, VIDEO, and CAROUSEL_ALBUM. For carousels, you need a second call to GET /{media-id}/children to retrieve individual cards.
Key constraints: Short-lived tokens expire in 1 hour and must be exchanged for long-lived tokens (60 days), which must be refreshed before expiry. media_url links expire — you need to either cache media assets or re-fetch URLs before rendering. Rate limits are shared across all Graph API calls for the same app, not isolated per endpoint.
X / Twitter (API v2)
User timelines are available via GET /2/users/{id}/tweets:
curl "https://api.x.com/2/users/{user-id}/tweets?tweet.fields=created_at,public_metrics,attachments&expansions=attachments.media_keys&media.fields=url,preview_image_url,type&max_results=100" \ -H "Authorization: Bearer {token}"Returns tweet text, metrics, and media attachments. Threads require following conversation_id references to reconstruct the full chain.
Key constraints: The Free tier is almost unusable for aggregation — 1 request per 15-minute window and only your own tweets. Basic ($200/month) gives you 15,000 tweet reads per month. Media attachments are returned as separate objects linked by media_keys, not inline with the tweet — you need to join them in your code.
LinkedIn (Community Management API)
Organization posts are available through the Posts API:
curl "https://api.linkedin.com/rest/posts?author=urn:li:organization:12345&q=author&count=20" \ -H "Authorization: Bearer {token}" \ -H "LinkedIn-Version: 202401"Returns post text, media references, creation timestamp, and distribution metadata. Personal profile posts require the r_member_social scope, which is restricted to approved LinkedIn partners.
Key constraints: LinkedIn requires a versioned header on every request. The response format uses URN-based identifiers (urn:li:share:123456) that look nothing like other platforms. Image and video assets are referenced by URN, not URL — you need a second API call to resolve the actual media URL. Rate limits are not publicly documented in detail and vary by application approval level.
TikTok (Content Posting API)
TikTok’s Video Query endpoint returns published videos:
curl "https://open.tiktokapis.com/v2/video/list/?fields=id,title,video_description,create_time,cover_image_url,share_url,duration,like_count,comment_count,share_count,view_count" \ -H "Authorization: Bearer {token}"Returns video metadata, engagement metrics, and cover images. Pagination uses a cursor parameter.
Key constraints: Only videos published through TikTok’s API or by the authenticated user are queryable. Access requires approval through TikTok’s developer portal, which can take weeks. Video files themselves are not returned — you get cover images and share URLs, not embeddable video streams.
YouTube (Data API v3)
Channel videos are available via the search or playlistItems endpoint:
curl "https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=CHANNEL_ID&type=video&order=date&maxResults=50&key={api_key}"Returns video IDs, titles, descriptions, thumbnails, and publish dates. For detailed stats, you need a second call to GET /youtube/v3/videos?part=statistics.
Key constraints: Each search request costs 100 quota units from a daily budget of 10,000. That means 100 searches per day on the free tier. Listing uploads via the channel’s uploads playlist is cheaper (1 unit per call) but requires knowing the playlist ID. Shorts and long-form videos are returned together with no API-level filter to separate them.
Facebook (Graph API)
Page feed retrieval mirrors Instagram’s pattern:
curl "https://graph.facebook.com/v21.0/{page-id}/feed?fields=id,message,full_picture,created_time,permalink_url,attachments&access_token={token}"Returns posts with text, attachments, and timestamps. Shared links include preview metadata. Video posts include source URLs.
Key constraints: Same Meta token lifecycle as Instagram. The feed endpoint returns both your posts and posts by others on your page — you need to filter by from.id to isolate your own content. Permissions require app review and business verification.
Why aggregation is harder than it looks
Reading the section above, you might think: six API calls, merge the results, done. Here is why it takes longer than expected.
Content normalization
An Instagram post object looks nothing like an X tweet. A LinkedIn URN bears no resemblance to a YouTube video ID. To render them in a single feed, you need a common schema:
interface SocialPost { id: string; platform: 'instagram' | 'twitter' | 'linkedin' | 'tiktok' | 'youtube' | 'facebook'; author: { name: string; avatar_url: string; profile_url: string; }; content: { text: string; media: Array<{ type: 'image' | 'video' | 'carousel'; url: string; thumbnail_url?: string; width?: number; height?: number; }>; }; metrics: { likes: number; comments: number; shares: number; views?: number; }; published_at: string; // ISO 8601 permalink: string;}Then you write a transformer for each platform:
function normalizeInstagramPost(raw: any): SocialPost { return { id: raw.id, platform: 'instagram', author: { name: raw.username, avatar_url: raw.profile_picture_url, profile_url: `https://instagram.com/${raw.username}` }, content: { text: raw.caption || '', media: raw.media_type === 'CAROUSEL_ALBUM' ? raw.children.data.map(child => ({ type: child.media_type === 'VIDEO' ? 'video' : 'image', url: child.media_url, thumbnail_url: child.thumbnail_url })) : [{ type: raw.media_type === 'VIDEO' ? 'video' : 'image', url: raw.media_url, thumbnail_url: raw.thumbnail_url }] }, metrics: { likes: raw.like_count, comments: raw.comments_count, shares: 0 // Instagram does not expose share count via API }, published_at: raw.timestamp, permalink: raw.permalink };}Multiply that by six platforms. Now maintain it when Instagram changes like_count to likes in a new API version, or when X adds a field, or when LinkedIn shifts from one API surface to another.
Pagination across sources
Each platform paginates differently:
| Platform | Pagination style | Token format |
|---|---|---|
| Cursor-based | after / before with opaque cursor string | |
| X | Token-based | pagination_token with next_token / previous_token |
| Start/count offset | start=0&count=20 | |
| TikTok | Cursor-based | cursor integer |
| YouTube | Token-based | pageToken with nextPageToken |
| Cursor-based | after with opaque cursor string |
Building a unified “load more” experience means maintaining separate pagination state per platform and merging results chronologically. When your Instagram cursor returns posts from March 12-15 and your X cursor returns posts from March 10-14, you need to interleave them correctly — and know when to fetch the next page from which source.
class AggregatedFeed { private cursors: Map<string, string | null> = new Map(); private buffer: SocialPost[] = [];
async loadMore(count: number): Promise<SocialPost[]> { // Fetch next page from each platform that still has content const fetches = [];
for (const platform of this.activePlatforms) { const cursor = this.cursors.get(platform); if (cursor !== 'exhausted') { fetches.push(this.fetchPlatform(platform, cursor)); } }
const results = await Promise.allSettled(fetches);
// Merge new posts into buffer, sorted by published_at for (const result of results) { if (result.status === 'fulfilled') { this.buffer.push(...result.value.posts); this.cursors.set(result.value.platform, result.value.nextCursor || 'exhausted'); } }
this.buffer.sort((a, b) => new Date(b.published_at).getTime() - new Date(a.published_at).getTime() );
return this.buffer.splice(0, count); }}Rate limits that collide
You are not making one API call per platform. You are making multiple — one for the feed, one for media details, one for metrics, one to resolve URNs. Across six platforms, your aggregator can easily hit 20-30 API calls per feed refresh.
Rate limit windows differ per platform. Instagram shares its limit pool with Facebook. YouTube burns quota units on a 24-hour cycle. X resets every 15 minutes. You need per-platform rate limiting with different window sizes:
| Platform | Rate limit | Window | Shared with |
|---|---|---|---|
| 200 calls/hr | Rolling 1 hour | Facebook (same app) | |
| X | 15,000 reads/mo (Basic) | Monthly cap | — |
| ~100 calls/day (varies) | Rolling 24 hours | — | |
| TikTok | Per-endpoint, documented | Rolling window | — |
| YouTube | 10,000 units/day | Calendar day (Pacific) | — |
| 200 calls/hr | Rolling 1 hour | Instagram (same app) |
Expiring media URLs
Instagram and Facebook media_url fields return CDN links that expire. If you cache feed data and render it hours later, images are broken. You either re-fetch URLs periodically, proxy media through your own CDN, or download and store assets — each with its own cost and latency trade-offs.
Authentication maintenance
Six platforms means six OAuth flows, six token types, six refresh schedules, and six possible revocation states. When your user’s Instagram token expires at 2 AM on a Sunday, your feed breaks silently. Token refresh logic needs to run on a schedule, handle failures gracefully, and notify someone when a token cannot be refreshed.
Dedicated aggregator APIs
If building all of this yourself sounds like a lot, that is because it is. Several services exist to handle the read side:
Juicer
Juicer aggregates feeds from 15+ platforms into a single API. You configure sources (an Instagram account, a Twitter handle, a YouTube channel), and Juicer returns a unified JSON feed:
curl "https://www.juicer.io/api/feeds/your-feed-name?per=20&page=1"Returns normalized posts with text, images, links, and source metadata. Moderation tools let you filter spam and off-brand content. Free tier includes 2 sources with 24-hour refresh. API access starts at $59/month (Business plan).
Best for: Marketing teams and agencies that need social walls, UGC galleries, or website embeds.
Curator.io
Curator takes a similar approach — connect sources, get a unified feed. REST API returns JSON with consistent formatting across platforms. Free tier includes 3 sources. Paid plans start at $25/month.
Best for: Developers who want a lightweight, embeddable social feed without building aggregation logic.
Flockler
Flockler aggregates from 13+ platforms and returns unified JSON. Their API uses an API key plus site UUID for authentication — no OAuth complexity for your application. Pricing starts at $129/month with API access.
Best for: Content hubs and digital signage where the display format matters as much as the data.
Taggbox
Taggbox focuses on UGC campaigns — collecting and displaying user-generated content from social platforms. AI-powered moderation, rights management, and analytics. No free tier; pricing starts at $79/month billed annually.
Best for: Brands running UGC campaigns or building social proof galleries.
The limitation
All of these tools solve the read side. They pull content in and display it. But the moment your user needs to respond to a comment, schedule a follow-up post, or cross-publish content to other platforms, you are back to building a separate integration.
An agency dashboard that only shows content but cannot publish from the same interface is half a product. A customer portal that displays social proof but cannot let the team schedule new posts requires two tools where one should suffice.
Read plus write: the full aggregator stack
The developer who searches for “social media aggregator API” usually needs both directions. They are building an application where users:
- View a unified feed of content across platforms (read side)
- Respond to comments, mentions, or trends (write side)
- Publish new content to multiple platforms from one interface (write side)
- Track how published content performs across platforms (analytics)
The read side pulls data in. The write side pushes content out. Most aggregator tools only do one.
Architecture: aggregator + publishing API
A practical architecture separates the two concerns. Your application sits in the middle. On the read side, it pulls content from an aggregator service (Juicer, Curator, Flockler) or directly from native platform APIs, normalizes it, and renders a unified feed. On the write side, it sends publish, schedule, and analytics requests to Postproxy, which handles delivery to Instagram, X, LinkedIn, TikTok, YouTube, Threads, Facebook, and Pinterest. Two integrations — one inbound, one outbound — instead of twelve.
The read side can be a dedicated aggregator service or direct API calls to each platform — whatever fits your budget and coverage needs. The write side uses Postproxy to publish across Instagram, X, LinkedIn, TikTok, YouTube, Threads, Facebook, and Pinterest through a single API.
Publishing from an aggregated view
When a user views the aggregated feed and wants to respond or cross-post, the flow stays within your application:
// User sees a trending post in the aggregated feed and wants to// cross-post a response to their own channels
async function crossPostResponse(originalPost, responseText, targetPlatforms) { const response = await fetch('https://api.postproxy.dev/api/posts', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ post: { body: responseText }, profiles: targetPlatforms // ['twitter', 'linkedin', 'threads'] }) });
const result = await response.json(); // Returns per-platform outcomes — which platforms succeeded, which failed return result;}One API call replaces six platform-specific publishing integrations.
Scheduling from the aggregated view
An agency manager reviews the aggregated feed, drafts three posts for the week, and schedules them — all from the same interface:
async function schedulePost(content, platforms, publishAt) { const response = await fetch('https://api.postproxy.dev/api/posts', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ post: { body: content, scheduled_at: publishAt // ISO 8601: "2026-03-25T14:00:00Z" }, profiles: platforms }) });
return response.json();}Tracking performance of published content
After publishing, the same interface can display how content performs. Postproxy’s stats endpoint returns normalized engagement data across all platforms:
curl "https://api.postproxy.dev/api/posts/stats?post_ids=post_abc123" \ -H "Authorization: Bearer YOUR_API_KEY"One request returns impressions, likes, comments, and platform-specific metrics for every platform the post was published to. No per-platform analytics integration required. See the analytics API deep dive for the full breakdown of what each platform exposes.
Multi-tenant aggregation for agencies and SaaS
If you are building for agencies or as a SaaS product, each of your customers manages their own social accounts. The aggregator needs to isolate data per customer — Client A’s feed should never leak into Client B’s dashboard.
On the read side, this means separate API credentials or source configurations per customer. On the write side, Postproxy handles this with profile groups and scoped API keys:
// Each client gets their own scoped API key// The key itself restricts which profiles are accessible —// no application-layer filtering needed
const clientAKey = 'pp_key_clientA_xxxxx';const clientBKey = 'pp_key_clientB_yyyyy';
// Client A can only publish to their own profilesawait fetch('https://api.postproxy.dev/api/posts', { method: 'POST', headers: { 'Authorization': `Bearer ${clientAKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ post: { body: 'Update from Client A' }, profiles: ['twitter', 'instagram'] })});The scoped key model means you do not need to build access control logic in your application. The API enforces the boundary. This pairs well with read-side aggregator tools that support multi-tenant configurations — Juicer and Curator both allow creating separate feeds per client.
Free APIs and what they actually get you
The keyword “social media api free” has 150 monthly searches. Developers want to know what they can build without paying. Here is the honest answer:
| Platform | Free API access | What you get | What you don’t get |
|---|---|---|---|
| Yes (with app review) | Own media, basic insights | Other users’ feeds, keyword search | |
| X | Yes (extremely limited) | 1 tweet read/15 min, own tweets only | Useful aggregation at any scale |
| Yes (with partner approval) | Own org posts | Personal profiles, search, analytics | |
| TikTok | Yes (with developer approval) | Own published videos | Other users, search, historical data |
| YouTube | Yes (10K units/day) | Search, channel videos, stats | High-volume aggregation (quota burns fast) |
| Yes (with app review) | Own page feed, insights | Cross-page search, user feeds |
The pattern: Every platform gives you free access to your own content. Aggregating across accounts, searching other users’ content, and operating at scale almost always requires paid tiers or third-party tools.
For a prototype or personal project, native APIs are enough. For a production SaaS serving multiple clients, you will outgrow free tiers quickly — either through rate limits (X), quota costs (YouTube), or access restrictions (LinkedIn, TikTok).
On the write side, Postproxy’s free tier includes 2 profile groups and 10 posts per month — enough to build and test your integration before scaling.
Common architectures
Agency dashboard
An agency managing 20 clients needs:
- Per-client aggregated feed showing all their social content
- Ability to schedule and publish posts per client
- Cross-platform analytics per client
Read side: Juicer or Curator feeds per client, or direct API calls cached in your database. Write side: Postproxy with scoped API keys per client. One integration handles publishing to all 8 platforms.
Content hub / social proof wall
An e-commerce brand wants to display user-generated content on their product pages:
- Pull Instagram posts tagged with their branded hashtag
- Pull X mentions
- Display in a grid on the website
Read side: Dedicated aggregator (Taggbox or Curator) with moderation and rights management. Write side: Postproxy for the brand’s own publishing schedule — post product launches, respond to UGC, and cross-promote to all channels.
Customer portal
A SaaS product gives users a “social” tab in their dashboard:
- View recent posts across connected platforms
- Schedule new posts
- See basic engagement metrics
Read side: Direct native API calls per platform, cached and normalized in your database. Aggregator services may be overkill for “show my own content” use cases. Write side: Postproxy handles scheduling, publishing, and analytics through a single API. The heavy integration work is on the write side — publishing to 8 platforms from one call — so offloading it saves the most development time.
Practical considerations
Cache aggressively. Social feeds do not change every second. A 5-minute cache on read-side data cuts your API call volume by 90% and keeps you well within rate limits. Serve from cache, refresh in the background.
Handle platform outages gracefully. If Instagram’s API returns a 500, your aggregated feed should still show content from the other five platforms. Use Promise.allSettled, not Promise.all:
const results = await Promise.allSettled([ fetchInstagramFeed(token), fetchXFeed(token), fetchLinkedInFeed(token), fetchYouTubeFeed(apiKey), fetchFacebookFeed(token), fetchTikTokFeed(token)]);
// Merge only the successful responsesconst posts = results .filter(r => r.status === 'fulfilled') .flatMap(r => r.value) .sort((a, b) => new Date(b.published_at) - new Date(a.published_at));Normalize timestamps immediately. Instagram returns ISO 8601. X returns ISO 8601. YouTube returns ISO 8601 with different precision. LinkedIn returns millisecond Unix timestamps. Parse everything to a consistent format on ingest, not at render time.
Proxy media assets. Do not render platform CDN URLs directly in your UI. They expire, they get rate-limited, they change format between API versions. Download to your own storage or proxy through a CDN on first access.
Monitor token health. A single expired token breaks one-sixth of your feed. Run a daily health check that verifies each platform token is valid and alerts your team before users notice missing content.
The aggregator you actually need to build
Most developers searching for a social media aggregator API are looking for a single service that handles everything — read and write, all platforms, one integration. That service does not exist, because the read and write sides have fundamentally different architectures, authentication models, and platform restrictions.
The practical approach: choose a read-side tool that matches your coverage needs and budget (or build it with native APIs if you only need your own content). Then pair it with a write-side API that handles the publishing, scheduling, and analytics layer.
Postproxy covers the write side — one API to publish across Instagram, X, LinkedIn, TikTok, YouTube, Threads, Facebook, and Pinterest, with scheduling, draft workflows, per-platform outcomes, and normalized analytics. The read-side tool feeds your display. Postproxy feeds your actions.
Start building with the Postproxy API and connect it to your aggregated feed.
Postproxy
One API for every social platform
Publish to Instagram, X, LinkedIn, TikTok, YouTube and more with a single request. Free plan, no credit card required.