Instagram Posts Scraper API: Pull Any Profile's Posts in 2026
If you've tried to get another account's posts out of Instagram's official Graph API, you already know it's a no-go: Graph API only hands you your own posts, after a Business account link and app review. For competitor analysis, influencer vetting, or content research, that's a wall.
This endpoint is the way around it. Give it a public handle, get that profile's posts back as JSON, with captions, likes, comments, views, and media URLs. No OAuth, no review queue.
A quick honesty check before you build: this works on public profiles only (private accounts are off-limits, by design), and if you want stories you'll want the highlights endpoint instead. If those fit, here's everything you can pull.
What you get per post
| Field | What it is |
|---|---|
pk / id | Unique post ID |
code | Shortcode for the URL (instagram.com/p/{code}) |
caption.text | Full caption |
like_count | Likes |
comment_count | Comments |
play_count | Views (video/reel posts) |
media_type | 1 = photo, 2 = video, 8 = carousel |
video_versions | Video URLs at various qualities |
image_versions2 | Image URLs at various sizes |
taken_at | Unix timestamp |
usertags | Tagged users |
One thing worth knowing in 2026: Instagram removed view counts from the single Post/Reel Info endpoint. This posts endpoint is now the reliable place to get a reel's play_count, so if you were leaning on post-info for views, switch your lookups here.
The call
const res = await fetch(
"https://api.sociavault.com/v1/scrape/instagram/posts?handle=opi",
{ headers: { "x-api-key": process.env.SOCIAVAULT_API_KEY } },
);
const result = await res.json();
const posts = Object.values(result.data.items);
Add trim=true if you want a lighter response without the embedded media CDN payloads.
{
"success": true,
"data": {
"more_available": true,
"next_max_id": "3822431353875645727_270598518",
"items": {
"0": {
"code": "DUTZgACiaFr",
"media_type": 2,
"caption": { "text": "The next generation of icons has arrived. 馃拝" },
"like_count": 2531,
"comment_count": 62,
"play_count": 100404,
"taken_at": 1770137534
}
}
},
"credits_used": 1,
"endpoint": "instagram/posts"
}
Note the items object uses numeric string keys, not an array, so Object.values(result.data.items) is your friend.
What people actually build with it
Competitor content audits. Pull a rival's last few dozen posts, average the engagement, and surface the top performers, the single most common request we see:
const posts = Object.values((await getPosts("competitor")).data.items);
const avgLikes = posts.reduce((s, p) => s + p.like_count, 0) / posts.length;
const top = [...posts].sort((a, b) => b.like_count - a.like_count).slice(0, 10);
console.log(
"Avg likes:",
Math.round(avgLikes),
"Top posts:",
top.map((p) => p.code),
);
Posting-time analysis. Bucket taken_at by hour to find when an account actually posts:
const byHour = {};
posts.forEach((p) => {
const h = new Date(p.taken_at * 1000).getHours();
byHour[h] = (byHour[h] || 0) + 1;
});
Content-mix breakdown. Photos vs videos vs carousels, straight from media_type:
const TYPES = { 1: "photo", 2: "video", 8: "carousel" };
const mix = posts.reduce((a, p) => {
const t = TYPES[p.media_type] || "other";
a[t] = (a[t] || 0) + 1;
return a;
}, {});
Influencer vetting. Engagement rate from real posts beats a follower count every time. Pull the last 30 posts, compute likes-plus-comments over followers, and you have a defensible number to judge a creator on.
Getting a full post history
Each call returns ~12 posts. Page with next_max_id:
async function getAllPosts(handle) {
let all = [],
nextMaxId = null;
do {
const url = new URL("https://api.sociavault.com/v1/scrape/instagram/posts");
url.searchParams.set("handle", handle);
if (nextMaxId) url.searchParams.set("next_max_id", nextMaxId);
const result = await (
await fetch(url, {
headers: { "x-api-key": process.env.SOCIAVAULT_API_KEY },
})
).json();
all.push(...Object.values(result.data.items));
nextMaxId = result.data.more_available ? result.data.next_max_id : null;
} while (nextMaxId);
return all;
}
Each page costs 1 credit, so deep histories on big accounts add up, cache what you pull.
FAQ
Private accounts? No. Public only. Do I get the actual files? You get URLs to the media; download them if you need the bytes. How far back? A profile's full public history. Stories? Not here, those are ephemeral. Use highlights for saved story content.
Start pulling posts
Create an account for 50 free credits (no card), grab your sk_live_... key, and run the snippet above. Full reference in the Instagram Posts API docs.
Related: Instagram Profile Scraper 路 Instagram Reels API 路 Post/Reel Info 路 Scrape Instagram comments
Found this helpful?
Share it with others who might benefit
Ready to Try SociaVault?
Start extracting social media data with our powerful API. No credit card required.