# Instagram (/docs/instagram) Instagram [#instagram] Public Instagram data without a Meta app review: profiles and their whole feed, reels with view and share counts, comment threads, story trays and saved highlights, the follower and following graph, hashtag and location feeds, and the audio library. Most reads are 1 credit; the ones that need a heavier upstream are 5. Which is which is the main thing to learn on this platform. Base URL: `/v1/instagram/...` `/v1/instagram/post` does not carry a share count, and no cheap endpoint does. Share counts, follower lists, stories and comments all come from a 5-credit upstream — `/v1/instagram/post/stats` for one post, `/v1/instagram/profile/posts/full` or `/v1/instagram/profile/reels/full` for a whole feed. View counts are different: they stay on the 1-credit reads, with `post` , `profile/posts` and `profile/reels` all carrying them on video. Plan the call before you build the loop. Getting started [#getting-started] Every endpoint is a `GET` with query parameters and an `x-api-key` header. Handles never carry a leading `@`. ```bash # 1. The account curl "https://www.socialcrawl.dev/v1/instagram/profile?handle=instagram" \ -H "x-api-key: $SOCIALCRAWL_API_KEY" # 2. What it posted, cursor-paged on next_max_id curl "https://www.socialcrawl.dev/v1/instagram/profile/posts?handle=instagram" \ -H "x-api-key: $SOCIALCRAWL_API_KEY" # 3. One post in detail curl "https://www.socialcrawl.dev/v1/instagram/post?url=https://www.instagram.com/p/CnpPou9hWqq/" \ -H "x-api-key: $SOCIALCRAWL_API_KEY" ``` `GET /v1/instagram/profile/full?handle=instagram` collapses steps 1 and 2 into one flat 5-credit call and adds computed analytics on top — average engagement rate, posting cadence, top post, and the mix of formats. Set `posts` (1-100, default 25) to choose the window the averages cover, or `include=computed` to drop the raw posts array from the payload. If the posts leg fails the profile still comes back, with the post-dependent metrics null. Accounts [#accounts] `profile` is the snapshot: bio, the exact integer follower count on `author.followers`, following count, post count, avatar, verification. `/v1/instagram/basic-profile` is its minimal sibling for when all you hold is a numeric `userId` and you only need a name and picture. `/v1/instagram/engagement` does the arithmetic for you — an overall engagement rate, totals, and a per-post breakdown including likes and comments per hour. Three endpoints walk the graph, all 5 credits and all accepting either `handle` or `user_id`: `/v1/instagram/followers` and `/v1/instagram/following` for the two directions, and `/v1/instagram/similar` for the accounts Instagram itself suggests as comparable, which is a single fixed list with no pagination. `/v1/instagram/search` is Instagram's own mixed search box: accounts, hashtags, and places in one payload. Reach for `search/profiles`, `search/hashtag`, or `search/location` when you want one type already split. `/v1/instagram/search/popular` is the popular-posts feed for a keyword, distinct from `search/reels`. `/v1/instagram/search/profiles` finds accounts by bio or caption keyword. It reads Google's index of Instagram rather than Instagram's own account search, so treat it as discovery rather than a lookup. `/v1/instagram/username-suggestions` is unrelated despite the name: it invents available handle ideas from a keyword and does not look anything up. `/v1/instagram/user/embed` returns an embeddable HTML snippet for dropping a profile onto your own page. Posts, reels and share counts [#posts-reels-and-share-counts] `/v1/instagram/profile/posts` and `/v1/instagram/profile/reels` are the cheap feed pulls (1 credit each), and they return likes, comments and, on reels, views. Neither carries a share count, because the upstream that serves them does not expose one. When shares matter, `/v1/instagram/profile/posts/full` and `/v1/instagram/profile/reels/full` fan out to a second source and attach a per-item share count plus a `coverage` figure telling you what fraction of the items got one. Both are metered: they consume upstream pages of 12 items and bill 5 credits per page, from 5 up to 25 for a `limit=50` walk. Both need a `handle` for the share leg — a `user_id`-only call still returns views, likes and comments, with shares null and a partial refund. For a single post, `/v1/instagram/post` returns the caption, media, tagged users and the engagement numbers, including the play count on video. Instagram removed play counts from its public web pages in August 2026, so the API now fills the count from a second source inside the same call; you still make one request and pay one credit. `/v1/instagram/post/stats` adds the paper-plane share count on video. Photo posts return views and shares as null, which is Instagram's behaviour rather than a gap. `/v1/instagram/post/likers` returns who liked it, and `/v1/instagram/media/transcript` returns the spoken words in a video or reel. Comments [#comments] `/v1/instagram/post/comments` returns a post's comment section, ranked by Instagram's popularity order by default. Pass `sort=recent` whenever you intend to walk a whole thread: Instagram only ranks the most-liked head of the list, so a `top` walk starts repeating comments once you page past it. Page deeper with the `next_cursor` from each response. To open one comment's replies, use `/v1/instagram/post/comment/replies` with the same post `url` and that comment's `comment_id`. It is the thread, not a second copy of the section. `GET /v1/instagram/comment` resolves one specific comment you already know about, by permalink (`comment_url`) or by `post_url` plus `comment_id`. It can also search a post for comments by `author_username` or `text_contains`, returning up to `max` matches. It is a bounded server-side scan rather than a direct fetch, because Instagram exposes no fetch-one-comment read: it costs 5 credits, or 15 with `deep_scan` for comments buried deep in a large thread. Passing back the `lookup.position_hint` from an earlier call replays the last-known sort chain first, which makes re-checking a comment you have already found much cheaper. Stories and highlights [#stories-and-highlights] `/v1/instagram/stories` returns the tray a user has live right now — an account with nothing live returns an empty list rather than an error. `/v1/instagram/story/download` pulls one specific story's full-resolution media, taking the author's `user_id` together with the `story_id`. Highlights are the permanent version: `/v1/instagram/highlights` lists the saved collections on a profile, and `/v1/instagram/highlight/detail` opens one by id. Discovery [#discovery] * `/v1/instagram/search/hashtag` pulls a tag feed, with `type` selecting `top` (default), `recent`, or `clips` for reels only * `/v1/instagram/search/reels` searches reels by keyword or phrase, page-paginated, with an optional `date_posted` filter * `/v1/instagram/reels/trending` samples Instagram's public trending page; it takes no parameters, sends a small batch per call, and repeats items, so call again to see more * `/v1/instagram/search/location` turns a place name into a `location_id`, which `/v1/instagram/location/posts` then uses to return what was posted there * `/v1/instagram/tagged` returns posts other people tagged an account in, which is a different question from what that account posted itself Reel search ordering is relevance, not a stable list [#reel-search-ordering-is-relevance-not-a-stable-list] `/v1/instagram/search/reels` returns Instagram's own relevance ranking for the keyword, and that ranking is live: the same query re-run minutes later can come back with a different, partially overlapping set of reels, and pages can overlap at their boundaries. There is no parameter that pins an ordering, and `date_posted` narrows the window rather than sorting it. Build on that rather than against it. Rank on `engagement.views` in your own code instead of trusting result order, deduplicate by `post.id` across pages and across runs, and if you need a stable view of a keyword over time, accumulate results into your own store across repeated runs rather than expecting one call to be reproducible. For a creator's complete back catalogue in a fixed order, walk `/v1/instagram/profile/reels` instead — a profile listing is stable in a way a relevance search cannot be. Follower counts next to search results [#follower-counts-next-to-search-results] `/v1/instagram/search/reels` rows carry the creator's identity on every row: `post.author.username` and `post.ext.author_id`, the numeric user id. `post.ext.author_followers` is historical — Instagram stripped follower counts out of its search payload in August 2026, so the field is null on every row and no source can restore it. Resolve follower counts from the creator's username instead. The current count lives on `author.followers` via `GET /v1/instagram/profile?handle=` (1cr, the exact integer, cached for 15 minutes) — every row's `post.author.username` is the join key. For a crawl, deduplicate creators across the whole run, then resolve them through `POST /v1/prism/profiles`: up to 50 handles per call at 1 credit per resolved profile, failed rows refunded, never served from cache, and one call can mix platforms, so TikTok and Instagram creators resolve together. Match rows to your input by each row's `index`. ```bash curl "https://www.socialcrawl.dev/v1/instagram/profile?handle=nasa" \ -H "x-api-key: sc_your_api_key_here" ``` Audio [#audio] `/v1/instagram/search/music` finds a track by name and `/v1/instagram/music/trending` returns whatever is popular right now with no parameters at all. Both return an audio id, and `/v1/instagram/audio/reels` takes that `audio_id` — the number in an `instagram.com/reels/audio/{audio_id}/` URL — and returns the reels using that sound, cursor-paged. That chain is how you measure a sound's spread rather than its chart position. Endpoints [#endpoints] Read this before you build [#read-this-before-you-build] **Media URLs expire.** The `media_urls` on any post are short-lived signed CDN links. For archiving, call `post` with `download_media=true` and read the durable links from `data.post.ext.download_media_urls`, each entry carrying `post_id`, `cdn_url`, `type` and `cached`. It adds a few seconds of latency while the media is fetched. **Likers are capped at roughly 100.** `post/likers` returns a sample regardless of how many likes the post has; the full like *count* is in the same response, but the list is not complete. Instagram does not expose more. **`safe_url=true` where you are embedding.** Several endpoints accept it, and it returns URL-safe profile picture and media links suitable for dropping straight into a page. **Carousels return every slide.** A sidecar post's `media_urls` is the full array, not just the cover image. Notes [#notes] * All endpoints use `GET` with query parameters * Authentication via the `x-api-key` header * Responses follow the unified SocialCrawl schema * Handles are passed without the `@`; where an endpoint accepts `user_id` as well, it is the faster of the two * `trim=true` on the profile and feed endpoints returns a slimmed-down payload Official Instagram Resources [#official-instagram-resources] * [Instagram Graph API](https://developers.facebook.com/docs/instagram-api/) — Official Meta developer documentation * [Instagram Basic Display API](https://developers.facebook.com/docs/instagram-basic-display-api/) — Basic profile and media access