API Documentation

One endpoint, 20 Instagram data operations. Generate a key from your dashboard and you're pulling data.

Authentication

Pass your API key as a bearer token on every request.

Authorization: Bearer YOUR_API_KEY

POST /v1/scrape

Every request has the same shape — an endpoint key from the table below, and itsparams.

FieldTypeDescription
endpointstringRequired. One of the endpoint keys below.
paramsobjectThe parameters for that endpoint — see "Params" column below.

Available endpoints

Grouped by category. Each one expands into its params and an example response — real Instagram payloads run into the hundreds of fields, so examples below are abbreviated to the ones you'll actually reach for.

User Profile

user_by_usernameGet a user's public profile by usernameexpand ▾

The usual entry point: resolve an @handle into a full public profile — bio, follower/following/media counts, verification and business/private status, avatar — plus the numeric id that every other user-scoped endpoint below needs. If you already have the numeric id, user_by_id is a faster round trip.

paramrequireddescription
usernameyesThe account's handle, without the "@" (e.g. "instagram").
safe_intnoReturn large integers (IDs, counts) as strings instead of numbers, so languages without native 64-bit ints don't lose precision.
Example response
{
  "pk": "25025320",
  "username": "instagram",
  "full_name": "Instagram",
  "is_private": false,
  "is_verified": true,
  "follower_count": 675000000,
  "following_count": 130,
  "media_count": 7600,
  "biography": "Bringing you closer to the people and things you love. ...",
  "profile_pic_url": "https://..."
  // + ~200 more fields
}
user_by_idGet a user's public profile by numeric IDexpand ▾

Same profile payload as user_by_username, keyed by numeric id instead of handle. Prefer this one once you've already resolved an id — it's a direct lookup rather than a username search.

paramrequireddescription
idyesThe account's numeric Instagram ID — not the @username. Resolve it first with user_by_username if you only have the handle.
safe_intnoReturn large integers (IDs, counts) as strings instead of numbers, so languages without native 64-bit ints don't lose precision.
Example response
{
  "pk": "25025320",
  "username": "instagram",
  "full_name": "Instagram",
  "is_private": false,
  "is_verified": true,
  "follower_count": 675000000
  // + ~200 more fields
}
user_aboutExtra account details (join date, account type, etc.)expand ▾

The "About this account" panel Instagram shows on a profile: verification status, the country the account was registered in, the date it was created, and any former usernames. Useful for lightweight account-authenticity checks without pulling the full profile payload.

paramrequireddescription
idyesThe account's numeric Instagram ID — not the @username. Resolve it first with user_by_username if you only have the handle.
Example response
{
  "is_verified": true,
  "country": "US",
  "date_joined": "2010-03-25T12:00:00Z",
  "former_usernames": ["old_handle"]
}
user_mediasA user's postsexpand ▾

A page of a user's feed posts (photos, videos, carousels — not reels or stories), newest first. Paginate with profile_grid_items_cursor from the previous response's cursor field.

paramrequireddescription
user_idyesThe account's numeric Instagram ID — not the @username. Resolve it first with user_by_username if you only have the handle.
profile_grid_items_cursornoPagination cursor from the previous page's response. Omit to get the first page.
flatnoReturn a flat array of posts instead of Instagram's grouped grid-section structure.
Example response
{
  "items": [
    { "id": "...", "code": "Cxxxxxxxxxx", "media_type": 1, "like_count": 4213, "comment_count": 87, "caption": { "text": "..." } }
  ],
  "cursor": "QVFB..."
}
user_clipsA user's reelsexpand ▾

A page of a user's Reels, newest first — same shape as user_medias but scoped to Reels only.

paramrequireddescription
user_idnoThe account's numeric Instagram ID — not the @username. Resolve it first with user_by_username if you only have the handle.
page_idnoPagination cursor from the previous page's response. Omit to get the first page.
safe_intnoReturn large integers (IDs, counts) as strings instead of numbers, so languages without native 64-bit ints don't lose precision.
Example response
{
  "items": [
    { "id": "...", "code": "Cxxxxxxxxxx", "media_type": 2, "play_count": 91234, "like_count": 5310, "video_duration": 14.7 }
  ],
  "page_id": "QVFB..."
}
user_storiesA user's currently active storiesexpand ▾

The account's currently-live story items. Empty once the last story expires (24h after posting) — there's no way to fetch expired stories through this endpoint.

paramrequireddescription
user_idyesThe account's numeric Instagram ID — not the @username. Resolve it first with user_by_username if you only have the handle.
forcenoPassed through to bypass any upstream cache and force a fresh fetch.
safe_intnoReturn large integers (IDs, counts) as strings instead of numbers, so languages without native 64-bit ints don't lose precision.
Example response
{
  "items": [
    { "id": "...", "media_type": 1, "taken_at": 1732000000, "expiring_at": 1732086400, "image_versions2": { "candidates": [{ "url": "https://..." }] } }
  ]
}
user_highlightsA user's story highlightsexpand ▾

The list of highlight reels pinned to a profile (cover image, title, item count) — not the story items inside them. Fetch a specific highlight's contents with highlight_by_id.

paramrequireddescription
user_idyesThe account's numeric Instagram ID — not the @username. Resolve it first with user_by_username if you only have the handle.
amountnoMaximum number of highlights to return.
page_idnoPagination cursor from the previous page's response.
forcenoPassed through to bypass any upstream cache and force a fresh fetch.
safe_intnoReturn large integers (IDs, counts) as strings instead of numbers, so languages without native 64-bit ints don't lose precision.
Example response
{
  "items": [
    { "id": "highlight:17900000000", "title": "Travel", "media_count": 12, "cover_media": { "url": "https://..." } }
  ]
}
user_followersA user's followers (paginated)expand ▾

A page of accounts following the given user, in the order Instagram returns them (not chronological). Private accounts you don't have visibility into will return a limited or empty list.

paramrequireddescription
user_idyesThe account's numeric Instagram ID — not the @username. Resolve it first with user_by_username if you only have the handle.
page_idnoPagination cursor from the previous page's response. Omit to get the first page.
Example response
{
  "users": [
    { "pk": "...", "username": "...", "full_name": "...", "is_private": false }
  ],
  "page_id": "QVFB..."
}
user_followingAccounts a user follows (paginated)expand ▾

A page of accounts the given user follows. Same pagination and visibility rules as user_followers.

paramrequireddescription
user_idyesThe account's numeric Instagram ID — not the @username. Resolve it first with user_by_username if you only have the handle.
page_idnoPagination cursor from the previous page's response. Omit to get the first page.
Example response
{
  "users": [
    { "pk": "...", "username": "...", "full_name": "...", "is_private": false }
  ],
  "page_id": "QVFB..."
}

Post Details

media_by_codePost details by shortcode (the id in a post URL)expand ▾

Full details for a single post (or carousel/reel) by its shortcode: caption, like/comment counts, media URLs, timestamps, and tagged users. Returns 404 for deleted or unavailable posts rather than a partial result. Note: usertags aren't returned for video media.

paramrequireddescription
codeyesThe shortcode from the post URL — the "Cxxxxxxxxxx" in instagram.com/p/Cxxxxxxxxxx/.
safe_intnoReturn large integers (IDs, counts) as strings instead of numbers, so languages without native 64-bit ints don't lose precision.
Example response
{
  "status": "ok",
  "num_results": 1,
  "items": [
    { "id": "...", "code": "Cxxxxxxxxxx", "media_type": 1, "like_count": 4213, "comment_count": 87, "caption": { "text": "..." } }
  ]
}
media_by_urlPost details by full Instagram URLexpand ▾

Same payload as media_by_code — use this one when you have the full post URL and don't want to parse the shortcode out of it yourself.

paramrequireddescription
urlyesThe full post URL, e.g. https://www.instagram.com/p/Cxxxxxxxxxx/.
safe_intnoReturn large integers (IDs, counts) as strings instead of numbers, so languages without native 64-bit ints don't lose precision.
Example response
{
  "status": "ok",
  "num_results": 1,
  "items": [
    { "id": "...", "code": "Cxxxxxxxxxx", "media_type": 1, "like_count": 4213, "comment_count": 87 }
  ]
}
media_commentsComments on a postexpand ▾

A page of top-level comments on a post, newest first, including each commenter's basic profile info and like count on the comment.

paramrequireddescription
idyesThe post's numeric media id (from media_by_code / media_by_url).
can_support_threadingnoWhether to return threaded (nested reply) comments if the client supports it.
safe_intnoReturn large integers (IDs, counts) as strings instead of numbers, so languages without native 64-bit ints don't lose precision.
page_idnoPagination cursor from the previous page's response.
Example response
{
  "comments": [
    { "pk": "...", "text": "...", "user": { "username": "..." }, "comment_like_count": 12, "created_at": 1732000000 }
  ],
  "page_id": "QVFB..."
}
media_likersAccounts that liked a postexpand ▾

The accounts that liked a post, most-recent-like first. For posts with like counts hidden by the poster, this can return an empty or partial list.

paramrequireddescription
idyesThe post's numeric media id (from media_by_code / media_by_url).
safe_intnoReturn large integers (IDs, counts) as strings instead of numbers, so languages without native 64-bit ints don't lose precision.
Example response
{
  "users": [
    { "pk": "...", "username": "...", "full_name": "...", "is_verified": false }
  ]
}

Stories

story_by_idA single story by IDexpand ▾

Details for one story item by its id (from user_stories). Returns nothing once the story has expired — Instagram doesn't retain expired stories server-side.

paramrequireddescription
idyesThe story item's numeric id (from user_stories).
safe_intnoReturn large integers (IDs, counts) as strings instead of numbers, so languages without native 64-bit ints don't lose precision.
Example response
{
  "id": "...",
  "media_type": 1,
  "taken_at": 1732000000,
  "expiring_at": 1732086400,
  "image_versions2": { "candidates": [{ "url": "https://..." }] }
}

Highlights

highlight_by_idA single highlight reel by IDexpand ▾

The story items inside one highlight reel (from user_highlights) — the archived stories a user has pinned to their profile, which don't expire.

paramrequireddescription
idyesThe highlight's id (from user_highlights, e.g. "highlight:17900000000").
safe_intnoReturn large integers (IDs, counts) as strings instead of numbers, so languages without native 64-bit ints don't lose precision.
Example response
{
  "id": "highlight:17900000000",
  "title": "Travel",
  "items": [
    { "id": "...", "media_type": 1, "image_versions2": { "candidates": [{ "url": "https://..." }] } }
  ]
}

Hashtags

hashtag_by_nameHashtag metadata (post count, etc.)expand ▾

Metadata for a hashtag: total post count, whether it's currently allowed to be followed, and related profile info Instagram surfaces for it.

paramrequireddescription
nameyesThe hashtag text, without the "#" (e.g. "sunset").
safe_intnoReturn large integers (IDs, counts) as strings instead of numbers, so languages without native 64-bit ints don't lose precision.
Example response
{
  "id": "...",
  "name": "sunset",
  "media_count": 128000000,
  "allow_following": true
}
hashtag_medias_topTop posts for a hashtagexpand ▾

A page of Instagram's algorithmically-ranked "Top posts" for a hashtag — not a chronological feed. There's no recency guarantee; use this for gauging what's currently ranking, not for exhaustive collection.

paramrequireddescription
nameyesThe hashtag text, without the "#".
page_idnoPagination cursor from the previous page's response.
safe_intnoReturn large integers (IDs, counts) as strings instead of numbers, so languages without native 64-bit ints don't lose precision.
Example response
{
  "items": [
    { "id": "...", "code": "Cxxxxxxxxxx", "media_type": 1, "like_count": 91234 }
  ],
  "page_id": "QVFB..."
}

Location

location_by_idLocation details by IDexpand ▾

Details for a geotag location: name, address, coordinates, and the numeric id used to look up posts tagged there.

paramrequireddescription
idyesThe location's numeric id, as seen on a geotagged post or in a location search result.
Example response
{
  "pk": "...",
  "name": "New York, New York",
  "lat": 40.7128,
  "lng": -74.006,
  "address": ""
}

Examples

curl
curl -X POST https://api.fairscrape.online/v1/scrape \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"endpoint": "user_by_username", "params": {"username": "instagram"}}'
Python
import requests

response = requests.post(
    "https://api.fairscrape.online/v1/scrape",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"endpoint": "user_by_username", "params": {"username": "instagram"}},
)
print(response.json())
JavaScript
const response = await fetch("https://api.fairscrape.online/v1/scrape", {
  method: "POST",
  headers: {
    Authorization: "Bearer YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    endpoint: "user_by_username",
    params: { username: "instagram" },
  }),
});
const data = await response.json();

Responses

Success (200):

{ "success": true, "data": { ... } }

Errors:

StatusMeaning
400Unknown endpoint, or missing a required param.
401Missing, invalid, or revoked API key.
402No active plan, expired plan, or insufficient wallet balance. Response includes current balance.
429Rate limit exceeded for your plan — slow down and retry. See pricing for each plan's requests/sec cap.
502Upstream call failed. You are not charged for this request.

Questions? support@fairscrape.online