100 free credits. No credit card required.Start building
Logo
Instagram logo
100 free credits. No credit card required

Instagram Post Stats API

Returns one post's engagement: likes, comments, and, on video posts only, the play count and the share count shown by the paper plane icon. Collab posts also list co-authors under ext.coauthors.

GET /v1/instagram/post/stats

Last updated November 2026Maintained by the SocialCrawl team

When to use the Instagram Post Stats API

Use it when you need the share count for a single post, or the co-author list of one collab post; views also come on post itself, and photo posts return both numbers as null.

From the API reference

Returns full engagement stats for a single Instagram post or reel: likes, comments, the view (play) count, and the share count (engagement.shares), which is the number shown next to the paper-plane Share icon in the app. The share count is a strong authenticity signal: unlike likes and comments, shares are hard to inflate, so it helps separate genuine reach from bought engagement. The standard /v1/instagram/post endpoint cannot return the share count. Metric availability depends on the media type: likes and comments populate on every post, but Instagram exposes a view (play) count and a share count only on video media (reels, videos, and carousels containing a video). On photo posts and photo-only carousels, engagement.views and engagement.shares are null, and because computed.estimated_reach and computed.engagement_rate derive from views, they are null there too. When Instagram's response for a reel includes the save count and the two-arrows Repost ("regram") counter, the plain call returns them at engagement.saves and post.ext.repost_count; Instagram includes them on some responses and not others, so do not rely on the plain call for them. Instagram publishes no save count and no share count on photos and carousels, so engagement.saves is null there on every call. Every post carries post.ext.media_type (image, video or carousel), a carousel carries its slide count at post.ext.carousel_count, and a reel carries Instagram's remix counter at post.ext.remix_count (how many reels were made from it). include=saves is the reliable way to get them: it asks a third source for a reel's save and repost count whenever the plain call came back without them, for 4 extra credits kept only when a save count comes back; a photo or carousel is never looked up. Use this endpoint for a single post; to get the share count for every reel or post across a whole feed in one call, use /v1/instagram/profile/reels/full or /v1/instagram/profile/posts/full. This endpoint also returns the post's collaborative-post co-authors under post.ext.coauthors ({ id, username, full_name, is_verified, profile_pic_url } per account, empty array when the post is not a collab): the standard /v1/instagram/post endpoint cannot, because its web source reports every post as having no co-authors. Pass the post url (a /p/, /reel/, or /tv/ link; story URLs are not accepted, list a user's active stories with /v1/instagram/stories instead).

Searching 69 platforms in parallel

·TikTok logoTikTok·Instagram logoInstagram·YouTube logoYouTube·Facebook logoFacebook·X logoX·LinkedIn logoLinkedIn·Reddit logoReddit·Threads logoThreads·Pinterest logoPinterest·Twitch logoTwitch·Truth Social logoTruth Social·Snapchat logoSnapchat·Kick logoKick·Bluesky logoBluesky·Kwai logoKwai·Rumble logoRumble·Spotify logoSpotify·Apple Music logoApple Music·TikTok Shop logoTikTok Shop·Amazon Shop logoAmazon Shop·Google Shopping logoGoogle Shopping·Trustpilot logoTrustpilot·TripAdvisor logoTripAdvisor·Yelp logoYelp·Linktree logoLinktree·Komi logoKomi·Pillar logoPillar·lnk.bio logolnk.bio·Facebook Ads logoFacebook Ads·Google Ads logoGoogle Ads·LinkedIn Ads logoLinkedIn Ads·Google Search logoGoogle Search·Google News logoGoogle News·Finance logoFinance·Polymarket logoPolymarket·Tavily logoTavily·Hacker News logoHacker News·GitHub logoGitHub·Perplexity logoPerplexity·Naver logoNaver·Utility logoUtility·Universal Search logoUniversal Search
·TikTok logoTikTok·Instagram logoInstagram·YouTube logoYouTube·Facebook logoFacebook·X logoX·LinkedIn logoLinkedIn·Reddit logoReddit·Threads logoThreads·Pinterest logoPinterest·Twitch logoTwitch·Truth Social logoTruth Social·Snapchat logoSnapchat·Kick logoKick·Bluesky logoBluesky·Kwai logoKwai·Rumble logoRumble·Spotify logoSpotify·Apple Music logoApple Music·TikTok Shop logoTikTok Shop·Amazon Shop logoAmazon Shop·Google Shopping logoGoogle Shopping·Trustpilot logoTrustpilot·TripAdvisor logoTripAdvisor·Yelp logoYelp·Linktree logoLinktree·Komi logoKomi·Pillar logoPillar·lnk.bio logolnk.bio·Facebook Ads logoFacebook Ads·Google Ads logoGoogle Ads·LinkedIn Ads logoLinkedIn Ads·Google Search logoGoogle Search·Google News logoGoogle News·Finance logoFinance·Polymarket logoPolymarket·Tavily logoTavily·Hacker News logoHacker News·GitHub logoGitHub·Perplexity logoPerplexity·Naver logoNaver·Utility logoUtility·Universal Search logoUniversal Search
·TikTok logoTikTok·Instagram logoInstagram·YouTube logoYouTube·Facebook logoFacebook·X logoX·LinkedIn logoLinkedIn·Reddit logoReddit·Threads logoThreads·Pinterest logoPinterest·Twitch logoTwitch·Truth Social logoTruth Social·Snapchat logoSnapchat·Kick logoKick·Bluesky logoBluesky·Kwai logoKwai·Rumble logoRumble·Spotify logoSpotify·Apple Music logoApple Music·TikTok Shop logoTikTok Shop·Amazon Shop logoAmazon Shop·Google Shopping logoGoogle Shopping·Trustpilot logoTrustpilot·TripAdvisor logoTripAdvisor·Yelp logoYelp·Linktree logoLinktree·Komi logoKomi·Pillar logoPillar·lnk.bio logolnk.bio·Facebook Ads logoFacebook Ads·Google Ads logoGoogle Ads·LinkedIn Ads logoLinkedIn Ads·Google Search logoGoogle Search·Google News logoGoogle News·Finance logoFinance·Polymarket logoPolymarket·Tavily logoTavily·Hacker News logoHacker News·GitHub logoGitHub·Perplexity logoPerplexity·Naver logoNaver·Utility logoUtility·Universal Search logoUniversal Search
·TikTok logoTikTok·Instagram logoInstagram·YouTube logoYouTube·Facebook logoFacebook·X logoX·LinkedIn logoLinkedIn·Reddit logoReddit·Threads logoThreads·Pinterest logoPinterest·Twitch logoTwitch·Truth Social logoTruth Social·Snapchat logoSnapchat·Kick logoKick·Bluesky logoBluesky·Kwai logoKwai·Rumble logoRumble·Spotify logoSpotify·Apple Music logoApple Music·TikTok Shop logoTikTok Shop·Amazon Shop logoAmazon Shop·Google Shopping logoGoogle Shopping·Trustpilot logoTrustpilot·TripAdvisor logoTripAdvisor·Yelp logoYelp·Linktree logoLinktree·Komi logoKomi·Pillar logoPillar·lnk.bio logolnk.bio·Facebook Ads logoFacebook Ads·Google Ads logoGoogle Ads·LinkedIn Ads logoLinkedIn Ads·Google Search logoGoogle Search·Google News logoGoogle News·Finance logoFinance·Polymarket logoPolymarket·Tavily logoTavily·Hacker News logoHacker News·GitHub logoGitHub·Perplexity logoPerplexity·Naver logoNaver·Utility logoUtility·Universal Search logoUniversal Search
Instagram API

What can you do with the Post Stats API?

The Post Stats endpoint gives you structured Instagram data with computed fields in a single request. No scraping infrastructure to build or maintain.

Example Request

# GET /v1/instagram/post/stats: Metered: holds 5 credits per call up front and refunds what the call does not use. Cache hits are free and failed calls are refunded.
# Check the price first for 0 credits: add dry_run=1 to the query. Nothing is fetched or charged.
# --max-time 10: this endpoint's measured p99 latency x 1.5.
# --retry 3: retries timeouts, 429 and 5xx, honoring Retry-After.
# -o response.json keeps only the final attempt's body.
# One Idempotency-Key per request, reused on every retry, so a retried call is never charged twice.
IDEMPOTENCY_KEY=$(od -An -N16 -tx1 /dev/urandom | tr -d ' \n')
curl -sS --max-time 10 --retry 3 -o response.json \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  "https://www.socialcrawl.dev/v1/instagram/post/stats?url=https%3A%2F%2Fwww.instagram.com%2Fp%2FCnpPou9hWqq%2F" && cat response.json
# GET /v1/instagram/post/stats: Metered: holds 5 credits per call up front and refunds what the call does not use. Cache hits are free and failed calls are refunded.
# Check the price first for 0 credits: add dry_run=1 to the query. Nothing is fetched or charged.
import os
import random
import time
import uuid

import requests

API_KEY = os.environ.get("SOCIALCRAWL_API_KEY", "YOUR_API_KEY")
TIMEOUT_S = 10  # this endpoint's measured p99 latency x 1.5.
MAX_RETRIES = 3
URL = "https://www.socialcrawl.dev/v1/instagram/post/stats"


def backoff(attempt):
    # Exponential backoff with jitter: about 1 s, 2 s, then 4 s.
    return 2 ** attempt * (0.5 + random.random() / 2)


def socialcrawl(params):
    # One Idempotency-Key per request, reused on every retry, so a retried call is never charged twice.
    idempotency_key = str(uuid.uuid4())
    for attempt in range(MAX_RETRIES + 1):
        try:
            res = requests.get(
                URL,
                params=params,
                headers={"x-api-key": API_KEY, "Idempotency-Key": idempotency_key},
                timeout=TIMEOUT_S,
            )
            body = res.json()
        except (requests.RequestException, ValueError):
            # A timeout, a dropped connection or a non-JSON gateway page: retry with the same key.
            if attempt == MAX_RETRIES:
                raise
            time.sleep(backoff(attempt))
            continue
        if body["success"]:
            return body
        error = body["error"]
        # Branch on error["type"], never on the message text.
        if error["type"] == "RESOURCE_NOT_FOUND":
            return None  # refunded: nothing to read
        retry_after = res.headers.get("Retry-After")
        # SERVICE_UNAVAILABLE without Retry-After is a withdrawn endpoint: permanent.
        permanent = error["type"] == "SERVICE_UNAVAILABLE" and retry_after is None
        if not error.get("retryable") or permanent or attempt == MAX_RETRIES:
            raise RuntimeError(f"{error['type']}: {error['message']} (request_id {body['request_id']})")
        # Retry-After (seconds) wins; otherwise back off.
        time.sleep(float(retry_after) if retry_after else backoff(attempt))


params = {
    "url": "https://www.instagram.com/p/CnpPou9hWqq/",
}
body = socialcrawl(params)
if body is not None:
    print(body["data"])
// GET /v1/instagram/post/stats: Metered: holds 5 credits per call up front and refunds what the call does not use. Cache hits are free and failed calls are refunded.
// Check the price first for 0 credits: add dry_run=1 to the query. Nothing is fetched or charged.
const API_KEY = process.env.SOCIALCRAWL_API_KEY ?? "YOUR_API_KEY";
const TIMEOUT_MS = 10_000; // this endpoint's measured p99 latency x 1.5.
const MAX_RETRIES = 3;

type Page = { next_cursor: string | null; has_more: boolean };
type SocialCrawlResponse =
  | { success: true; data: any; pagination?: Page; credits_used: number; request_id: string }
  | { success: false; error: { type: string; message: string; retryable: boolean }; request_id: string };

const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
// Exponential backoff with jitter: about 1 s, 2 s, then 4 s.
const backoffMs = (attempt: number) => 2 ** attempt * 1000 * (0.5 + Math.random() / 2);

async function socialcrawl(url: URL) {
  // One Idempotency-Key per request, reused on every retry, so a retried call is never charged twice.
  const idempotencyKey = crypto.randomUUID();
  for (let attempt = 0; ; attempt++) {
    let res: Response;
    let body: SocialCrawlResponse;
    try {
      res = await fetch(url, {
        headers: {
          "x-api-key": API_KEY,
          "Idempotency-Key": idempotencyKey,
        },
        signal: AbortSignal.timeout(TIMEOUT_MS),
      });
      body = (await res.json()) as SocialCrawlResponse;
    } catch (error) {
      // A timeout, a dropped connection or a non-JSON gateway page: retry with the same key.
      if (attempt >= MAX_RETRIES) throw error;
      await sleep(backoffMs(attempt));
      continue;
    }
    if (body.success) return body;
    // Branch on error.type, never on the message text.
    if (body.error.type === "RESOURCE_NOT_FOUND") return null; // refunded: nothing to read
    const retryAfter = res.headers.get("Retry-After");
    // SERVICE_UNAVAILABLE without Retry-After is a withdrawn endpoint: permanent.
    const permanent = body.error.type === "SERVICE_UNAVAILABLE" && retryAfter === null;
    if (!body.error.retryable || permanent || attempt >= MAX_RETRIES) {
      throw new Error(`${body.error.type}: ${body.error.message} (request_id ${body.request_id})`);
    }
    // Retry-After (seconds) wins; otherwise back off.
    await sleep(retryAfter ? Number(retryAfter) * 1000 : backoffMs(attempt));
  }
}

const url = new URL("https://www.socialcrawl.dev/v1/instagram/post/stats");
url.searchParams.set("url", "https://www.instagram.com/p/CnpPou9hWqq/");

const body = await socialcrawl(url);
if (body) console.log(body.data);

Parameters

ParameterRequiredDescription
urlYesURL of the Instagram post (a /p/, /reel/, or /tv/ link). A share link copied from the app (`instagram.com/share/...`) works too; a share link to a profile is refused at no charge with the handle to send, and a dead one is a free 404.
safe_urlNoWhen true, returns URL-safe media links suitable for embedding.
includeNoSet to `saves` (one token only) to ask a third source for a reel's save count (`post.engagement.saves`) and repost count (`post.ext.repost_count`) when the plain call returned without them. 4 extra credits, kept only when a save count comes back; a repeat within the cache window is 0. Photos and carousels are never looked up, because Instagram publishes no save count on them. Adds 3 to 6 seconds when a lookup runs; read `data.hydration` for the credits held and kept and the time. (saves)
Example Response

What does the Instagram Post Stats API return?

Every response follows one unified schema. Here is a real, unmodified response body, so you can see the exact fields you get back before spending a credit.

Example response
{
  "success": true,
  "platform": "instagram",
  "endpoint": "/v1/instagram/post/stats",
  "data": {
    "post": {
      "id": "3020013795029641898",
      "url": "https://www.instagram.com/reel/CnpPou9hWqq/",
      "content": {
        "text": "Mumbbongbbong😵‍💫🎺 \n\nJoin @sun_sim_ (Sunsim), a Maltese, and Deokseon, a bichon frise, on a magic carpet ride into the weekend. \n\n #WeeklyFluff \n\n Video by @sun_sim_",
        "media_urls": "https://scontent-lga3-1.cdninstagram.com/o1/v/t2/f2/m82/AQMvIsbCtot9atknWWicTQex1s4NvrA2i8kEYhdBwyu0FaHuOg_Z1IL35MbODe8c-J9__WU2-qMKRsFOs7wtFo-hX7fdOnauV45xI2Y.mp4?_nc_cat=111&_nc_sid=5e9851&_nc_ht=scontent-lga3-1.cdninstagram.com&_nc_ohc=ymhJ-pp52qAQ7kNvwE6Gs1b&efg=eyJ2ZW5jb2RlX3RhZyI6Inhwdl9wcm9ncmVzc2l2ZS5JTlNUQUdSQU0uQ0xJUFMuQzMuNzIwLmRhc2hfYmFzZWxpbmVfMV92MSIsInhwdl9hc3NldF9pZCI6MTM5OTA5MDMzMDgzNDc0MSwiYXNzZXRfYWdlX2RheXMiOjEzNTAsInZpX3VzZWNhc2VfaWQiOjEwMDk5LCJkdXJhdGlvbl9zIjoxMiwidXJsZ2VuX3NvdXJjZSI6Ind3dyJ9&ccb=17-1&vs=87b8f7dbb0b19011&_nc_vs=HBksFQIYT2lnX3hwdl9yZWVsc19wZXJtYW5lbnRfcHJvZC9GRjQzRDJDMEI0MUM2NjVCM0EzMEFDNkE2NDBDRTRBOV92aWRlb19kYXNoaW5pdC5tcDQVAALIARIAFQIYOnBhc3N0aHJvdWdoX2V2ZXJzdG9yZS9HQlZTZXhNSGI0amF5dEFFQUJZaEVIV0JuVHBMYnFfRUFBQUYVAgLIARIAKAAYABsCiAd1c2Vfb2lsATEScHJvZ3Jlc3NpdmVfcmVjaXBlATEVAAAm6tzsouOd_AQVAigCQzMsF0ApZmZmZmZmGBJkYXNoX2Jhc2VsaW5lXzFfdjERAHX-B2XmnQEA&_nc_gid=jUC2jCkUzsOf7fOsQnaz0g&_nc_ss=733ba&_nc_zt=28&oh=00_AQM8vihMXlqyWn76ZCVyfZI59SW3ZwtHcuM4UbzfVyF3dA&oe=6AC1B10C",
        "thumbnail_url": "https://scontent-lga3-2.cdninstagram.com/v/t51.71878-15/491414458_1934794933930942_6214267858142308860_n.jpg?stp=dst-jpg_e15_tt6&_nc_cat=101&ig_cache_key=MzAyMDAxMzc5NTAyOTY0MTg5OA%3D%3D.3-ccb7-5&ccb=7-5&_nc_sid=58cdad&efg=eyJ2ZW5jb2RlX3RhZyI6IkNMSVBTLnhwaWRzLjcyMC5zZHIudmlkZW9fZGVmYXVsdF9jb3Zlcl9mcmFtZS5DMyJ9&_nc_ohc=uGUD5PzbNQEQ7kNvwEH7szm&_nc_oc=Adri7HHQy1sirgBp5L6PrlCm3tNR7m-QBOmaN410XnkZZPRVlGnUs5Q7e4FCzg7YqgU&_nc_ad=z-m&_nc_cid=0&_nc_zt=23&_nc_ht=scontent-lga3-2.cdninstagram.com&_nc_gid=jUC2jCkUzsOf7fOsQnaz0g&_nc_ss=733ba&oh=00_AQM5jW80toSLVOnwaaCMoy7vBrwdF9qX4HuMRQi1RcU3Wg&oe=6AC58B6B",
        "duration_seconds": 12.7
      },
      "author": {
        "username": "instagram",
        "display_name": "Instagram",
        "avatar_url": "https://scontent-lga3-3.cdninstagram.com/v/t51.82787-19/550891366_18667771684001321_1383210656577177067_n.jpg?stp=dst-jpg_e0_s150x150_tt6&_nc_cat=1&ig_cache_key=GGbv1SApFvlLPVJCAOtF0XrDJjITbmNDAQAB1501500j-ccb7-5&ccb=7-5&_nc_sid=669407&efg=eyJ2ZW5jb2RlX3RhZyI6InByb2ZpbGVfcGljLnd3dy4xMDgwLkMzIn0%3D&_nc_ohc=_dBpg1akaE4Q7kNvwEzSMUO&_nc_oc=Adp9q_1Hrmtqt3yFS7bzLmqMIgR0CmP3FcRmB19tdTIu1Cfkhh3iiYM1aODNYACuWkQ&_nc_ad=z-m&_nc_cid=0&_nc_zt=24&_nc_ht=scontent-lga3-3.cdninstagram.com&_nc_gid=jUC2jCkUzsOf7fOsQnaz0g&_nc_ss=733ba&oh=00_AQNIpSLWw0UZdi6WlpjJ0nI7_alvrmUQ0w9uk4IU0vIufQ&oe=6AC59627",
        "verified": true
      },
      "engagement": {
        "views": 45016542,
        "likes": 1390842,
        "comments": 16381,
        "shares": 47,
        "saves": null
      },
      "flags": {
        "nsfw": null,
        "spoiler": null,
        "pinned": false,
        "deleted": false
      },
      "published_at": "2023-01-20T16:56:42.000Z",
      "ext": {
        "ig_play_count": 45016542,
        "repost_count": null,
        "media_type": "video",
        "remix_count": 197,
        "published_at_epoch": 1674233802,
        "coauthors": []
      }
    },
    "computed": {
      "engagement_rate": 0.031261,
      "language": "en",
      "content_category": "other",
      "estimated_reach": 54019850
    }
  },
  "credits_used": 5,
  "request_id": "req_example000000",
  "cached": false,
  "credits_remaining": 9999,
  "source": "captured",
  "captured_at": "2026-10-02T15:37:11.366Z",
  "redacted": true
}

Live sample illustrating the unified response shape. Field values reflect the record you query.

API Details

How does the Instagram Post Stats API work?

Send a GET request with your API key and get back clean, structured JSON in our unified schema. Supported computed fields are populated when the source provides the required inputs.

Method

GET

Response

JSON

Why SocialCrawl

Why use SocialCrawl for Instagram Post Stats data?

We handle the complexity of Instagram data extraction so you can focus on building. Unified schema, AI enrichment, and zero platform logic in your code.

Developer First

How do you scrape social media data in seconds?

The fastest social media scraping API for developers. Scrape profiles, posts, comments, and analytics from 69 platforms covering 10B+ monthly active users.

One schema, every platform

Query 69 platforms with identical response structures. Write your integration once.

Computed fields, not just scraped

When an endpoint supports these metrics and the source provides the required inputs, the normalized record includes engagement_rate, estimated_reach, content_category, and language. Ready to use.

See your data before you code

Visual Data Explorer. Paste any URL, get rich result cards, sortable tables, CSV export.

import requests

response = requests.get(
    'https://www.socialcrawl.dev/v1/tiktok/profile',
    params={'handle': 'charlidamelio'},
    headers={'x-api-key': 'sc_YOUR_API_KEY'}
)
data = response.json()
[ .JSON ]
{
  "success": true,
  "platform": "tiktok",
  "data": {
    "author": {
      "username": "charlidamelio",
      "followers": 152400000
    },
    "engagement": {
      "likes": 12400000000,
      "engagement_rate": 0.087
    },
    "metadata": {
      "language": "en",
      "content_category": "lifestyle"
    }
  }
}
+ 69 platforms
FAQ

Have a question? We got answers

Find answers to frequently asked questions about SocialCrawl's API, pricing, and capabilities.

Contact us
How do I get the share count for an Instagram post?
Send a GET request to /v1/instagram/post/stats with the post URL in the url parameter. The response returns likes and comments for any post, and on video media (reels, videos, carousels with a video) also engagement.shares (the number next to the paper-plane Share icon) and the view count. Photo posts have no public view or share count on Instagram, so those two fields are null there.
Why can't the standard post endpoint return share count?
The standard /v1/instagram/post endpoint reads a data source that does not carry the share number. This stats endpoint fans out to the source that exposes engagement.shares, which is why it returns the share count and the standard endpoint cannot.
Why does the share count matter for authenticity?
Shares are hard to inflate compared with likes and comments, so a healthy share count relative to reach is a strong authenticity signal when you are vetting an influencer or checking whether engagement is genuine.
Does it return the save count or the repost count?
On reels, yes, with include=saves: the save count arrives at engagement.saves and the two-arrows Repost counter at post.ext.repost_count. Instagram publishes no save count on photos and carousels, so engagement.saves is null there.
What post URLs and pricing does the endpoint use?
It accepts /p/, /reel/, and /tv/ links in the url parameter and costs 5 credits per call on the advanced tier. New accounts get 100 free credits with no card, so you can try it first.

Ask AI about SocialCrawl

Ready to scrape Instagram Post Stats data?

Get your API key and start pulling Instagram data in under 60 seconds.

Start for free

🤖 AI agent or LLM? Read this page as markdown