Skip to content
truescrape

Instagram API

The TrueScrape Instagram API exposes 19 public endpoints covering Reels using a sound and Replies under one comment. Every call is a GET against public, logged-out pages and returns the same unified schema as every other platform here. Calls cost 1 credit each. A cache hit is free, and a failed or empty response is never charged.

Endpoints

EndpointReturnsCreditsCacheableBatchable
/v1/instagram/audio-reelsReels using a sound1yesyes
/v1/instagram/comment-repliesReplies under one comment1yesno
/v1/instagram/hashtag-postsPosts under a hashtag1yesyes
/v1/instagram/highlightStories inside a highlight1yesyes
/v1/instagram/popular-searchTop posts for a keyword1yesyes
/v1/instagram/postPost or reel details1yesyes
/v1/instagram/post-commentsComments on a post or reel1yesyes
/v1/instagram/profileProfile details1yesyes
/v1/instagram/profile-post-countPost count for a profile1yesyes
/v1/instagram/profile-searchSearch accounts1yesyes
/v1/instagram/reels-searchSearch reels by keyword1yesyes
/v1/instagram/searchSearch accounts, hashtags and places1yesyes
/v1/instagram/transcriptReel or video transcript1yesyes
/v1/instagram/trending-reelsReels trending on Explore1yesno
/v1/instagram/user-embedProfile via the public embed card1yesyes
/v1/instagram/user-highlightsStory highlight covers1yesyes
/v1/instagram/user-postsPosts and reels from a profile1yesyes
/v1/instagram/user-reelsReels from a profile1yesyes
/v1/instagram/user-tagged-postsPosts a profile is tagged in1yesyes

Reference

GET/v1/instagram/audio-reels1 creditcacheablebatchable

Reels using a sound

Reels built on one audio track, the "N reels using this audio" list. Takes the numeric audio id or a /reels/audio/ URL. Falls back to the public audio page, which lists its first grid of reels only once rendered, as links and cover images.

ParameterTypeRequiredDescription
audio_idstringyesNumeric audio id, or a /reels/audio/<id>/ URL
cursorstringnopagination.cursor from a previous response
countnumbernoReels per page, 1-50. Default 12.

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Post in data.items.

Fields
FieldTypePresentDescription
platformone of 47 stringsalways
idstringalways
typevideo | short | image | carousel | text | live | story | reel | audio | album | episode | unknownalwaysWhat kind of post this is. `short` and `reel` are short-form video formats, `live` is a live stream or a recording of one, `carousel` holds several images or videos, `audio` is a music track, `album` is an album, `episode` is a podcast episode, and `unknown` covers anything else.
urlstring | nullalways
titlestring | nullalways
textstring | nullalwaysThe post's text: a caption, a description or the message body.
authorIdstring | nullalways
authorHandlestring | nullalways
authorNamestring | nullalways
thumbnailUrlstring | nullalways
mediaUrlsstring[]always
durationSecondsnumber | nullalways
viewCountnumber | nullalwaysViews. Null means the platform did not expose a count, which is not the same as zero.
likeCountnumber | nullalwaysLikes, or the platform's nearest equivalent. Null means not exposed, not zero.
commentCountnumber | nullalwaysComments. Null means not exposed, not zero.
shareCountnumber | nullalwaysShares, reposts, or the platform's nearest equivalent. Null means not exposed, not zero.
hashtagsstring[]alwaysHashtags or the platform's own topic tags, without the leading #.
mentionsstring[]alwaysHandles mentioned in the post text, without the leading @.
taggedUsersstring[]may be absentUsernames tagged in the media itself, as distinct from `mentions`, which come from the caption text. Absent when the platform does not report tags; an empty array means it reports none.
isSponsoredboolean | nullalwaysWhether the platform labels the post as an ad, promoted content or a paid partnership.
publishedAtstring | nullalwaysWhen the post was published. Usually an ISO 8601 timestamp; some platforms expose only a date or relative text such as "3 days ago".
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/instagram/audio-reels?audio_id=%3Caudio_id%3E&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  audio_id: '<audio_id>',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/instagram/audio-reels?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/instagram/audio-reels",
    params={
        "audio_id": "<audio_id>",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or rate_limited (hourly calls to servers you named outside our known list). Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_schema_drift. Not charged
503upstream_unavailable. We could not get this from the platform. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/instagram/audio-reels
Open the full playground
GET/v1/instagram/comment-replies1 creditcacheable

Replies under one comment

The full reply thread under a single comment. Take comment_id from data.items[].id on /v1/instagram/post-comments; the post URL is still required because Instagram addresses replies through the media that carries them.

ParameterTypeRequiredDescription
urlstringyesPost, reel or IGTV URL, or a bare shortcode
comment_idstringyesdata.items[].id from /v1/instagram/post-comments
cursorstringnopagination.cursor from a previous response
countnumbernoReplies per page, 1-50. Default 24.

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Comment in data.items.

Fields
FieldTypePresentDescription
platformone of 47 stringsalways
idstringalways
postIdstring | nullalways
parentIdstring | nullalwaysId of the comment this one replies to. Null on a top-level comment.
textstringalways
authorIdstring | nullalways
authorHandlestring | nullalways
authorNamestring | nullalways
authorAvatarUrlstring | nullalways
likeCountnumber | nullalways
replyCountnumber | nullalways
isPinnedboolean | nullalways
isAuthorReplyboolean | nullalwaysWhether the comment was written by the author of the post.
publishedAtstring | nullalwaysWhen the comment was posted. Usually an ISO 8601 timestamp; some platforms expose only relative text such as "2 days ago".
curl
curl "$API/v1/instagram/comment-replies?url=8XkPqR2nLvE&comment_id=%3Ccomment_id%3E&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  url: '8XkPqR2nLvE',
  comment_id: '<comment_id>',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/instagram/comment-replies?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/instagram/comment-replies",
    params={
        "url": "8XkPqR2nLvE",
        "comment_id": "<comment_id>",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or rate_limited (hourly calls to servers you named outside our known list). Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_schema_drift. Not charged
503upstream_unavailable. We could not get this from the platform. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/instagram/comment-replies
Open the full playground
GET/v1/instagram/hashtag-posts1 creditcacheablebatchable

Posts under a hashtag

Posts carrying a hashtag. tab=top is Instagram's ranking (one fixed page, no cursor); tab=recent is chronological and paginates. Falls back to the server-rendered tag page when the JSON surface declines, which returns the top grid only. Set extra_fetch=true to fill each post's publish date, like and comment counts and caption from its own page: 1 credit per item fetched, up to the page size.

ParameterTypeRequiredDescription
hashtagstringyesHashtag (#nasa or nasa), or an /explore/tags/ URL
tabtop | recentnoInstagram's ranking, or chronologicaldefaults to top
cursorstringnopagination.cursor from a previous response. recent only
extra_fetchbooleannoWhen true, fetches each item's own page to fill fields the list page leaves null. Costs 1 extra credit per page fetched, up to the page size.

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Post in data.items.

Fields
FieldTypePresentDescription
platformone of 47 stringsalways
idstringalways
typevideo | short | image | carousel | text | live | story | reel | audio | album | episode | unknownalwaysWhat kind of post this is. `short` and `reel` are short-form video formats, `live` is a live stream or a recording of one, `carousel` holds several images or videos, `audio` is a music track, `album` is an album, `episode` is a podcast episode, and `unknown` covers anything else.
urlstring | nullalways
titlestring | nullalways
textstring | nullalwaysThe post's text: a caption, a description or the message body.
authorIdstring | nullalways
authorHandlestring | nullalways
authorNamestring | nullalways
thumbnailUrlstring | nullalways
mediaUrlsstring[]always
durationSecondsnumber | nullalways
viewCountnumber | nullalwaysViews. Null means the platform did not expose a count, which is not the same as zero.
likeCountnumber | nullalwaysLikes, or the platform's nearest equivalent. Null means not exposed, not zero.
commentCountnumber | nullalwaysComments. Null means not exposed, not zero.
shareCountnumber | nullalwaysShares, reposts, or the platform's nearest equivalent. Null means not exposed, not zero.
hashtagsstring[]alwaysHashtags or the platform's own topic tags, without the leading #.
mentionsstring[]alwaysHandles mentioned in the post text, without the leading @.
taggedUsersstring[]may be absentUsernames tagged in the media itself, as distinct from `mentions`, which come from the caption text. Absent when the platform does not report tags; an empty array means it reports none.
isSponsoredboolean | nullalwaysWhether the platform labels the post as an ad, promoted content or a paid partnership.
publishedAtstring | nullalwaysWhen the post was published. Usually an ISO 8601 timestamp; some platforms expose only a date or relative text such as "3 days ago".
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/instagram/hashtag-posts?hashtag=%3Chashtag%3E&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  hashtag: '<hashtag>',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/instagram/hashtag-posts?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/instagram/hashtag-posts",
    params={
        "hashtag": "<hashtag>",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or rate_limited (hourly calls to servers you named outside our known list). Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_schema_drift. Not charged
503upstream_unavailable. We could not get this from the platform. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/instagram/hashtag-posts
Open the full playground
GET/v1/instagram/profile-search1 creditcacheablebatchable

Search accounts

Accounts matching a query, as unified Creators. The follower counts on a search result are Instagram's own summary and are thinner than /v1/instagram/profile. Fetch that for one account you care about. One page only; this surface has no cursor.

ParameterTypeRequiredDescription
querystringyesHandle or name to search for

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Creator in data.items.

Fields
FieldTypePresentDescription
platformone of 47 stringsalways
idstringalwaysThe platform's own id for the account, such as a channel id or a numeric user id, always as a string.
handlestring | nullalwaysThe account handle without the leading @. Null when the platform has no handles.
displayNamestring | nullalways
biostring | nullalways
avatarUrlstring | nullalways
bannerUrlstring | nullalways
urlstring | nullalways
verifiedboolean | nullalwaysWhether the platform shows a verification badge on the account. Null where the platform has no public badge or does not expose it.
followerCountnumber | nullalwaysFollowers, subscribers, or the platform's nearest equivalent. Null when the account hides the count or the platform does not expose it.
followingCountnumber | nullalways
postCountnumber | nullalwaysPosts, videos, tracks, repositories, or the platform's nearest equivalent that the account has published.
viewCountnumber | nullalwaysLifetime views across the account, where the platform exposes a total.
likeCountnumber | nullmay be absentTotal likes received across all of the creator's posts. Distinct from `viewCount`. Absent when the platform does not expose it.
isPrivateboolean | nullalways
isBusinessboolean | nullalwaysWhether the platform classifies the account as a business or organisation rather than a person or creator. Null where the platform draws no such line or does not expose it. On Facebook every Page counts, including Pages for public figures.
categorystring | nullalwaysA label the platform attaches to the account, such as a business category, a genre or an account type. What it holds varies by platform.
locationstring | nullalwaysLocation as the platform shows it: a city, a country, a region code or an address, depending on the platform.
externalLinksstring[]alwaysLinks the account lists on its profile, such as a website or other social accounts.
createdAtstring | nullalwaysWhen the account was created. Usually an ISO 8601 timestamp; some platforms expose only the date as shown on the profile.
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/instagram/profile-search?query=ai%20agents&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  query: 'ai agents',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/instagram/profile-search?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/instagram/profile-search",
    params={
        "query": "ai agents",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or rate_limited (hourly calls to servers you named outside our known list). Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_schema_drift. Not charged
503upstream_unavailable. We could not get this from the platform. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/instagram/profile-search
Open the full playground
GET/v1/instagram/reels-search1 creditcacheablebatchable

Search reels by keyword

Reels matching a keyword, from Instagram's own keyword search rather than its hashtag index. The two return genuinely different sets, so this never quietly substitutes one for the other. Results are whatever Instagram ranked for the query at that moment.

ParameterTypeRequiredDescription
querystringyesKeyword to search for
cursorstringnopagination.cursor from a previous response

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Post in data.items.

Fields
FieldTypePresentDescription
platformone of 47 stringsalways
idstringalways
typevideo | short | image | carousel | text | live | story | reel | audio | album | episode | unknownalwaysWhat kind of post this is. `short` and `reel` are short-form video formats, `live` is a live stream or a recording of one, `carousel` holds several images or videos, `audio` is a music track, `album` is an album, `episode` is a podcast episode, and `unknown` covers anything else.
urlstring | nullalways
titlestring | nullalways
textstring | nullalwaysThe post's text: a caption, a description or the message body.
authorIdstring | nullalways
authorHandlestring | nullalways
authorNamestring | nullalways
thumbnailUrlstring | nullalways
mediaUrlsstring[]always
durationSecondsnumber | nullalways
viewCountnumber | nullalwaysViews. Null means the platform did not expose a count, which is not the same as zero.
likeCountnumber | nullalwaysLikes, or the platform's nearest equivalent. Null means not exposed, not zero.
commentCountnumber | nullalwaysComments. Null means not exposed, not zero.
shareCountnumber | nullalwaysShares, reposts, or the platform's nearest equivalent. Null means not exposed, not zero.
hashtagsstring[]alwaysHashtags or the platform's own topic tags, without the leading #.
mentionsstring[]alwaysHandles mentioned in the post text, without the leading @.
taggedUsersstring[]may be absentUsernames tagged in the media itself, as distinct from `mentions`, which come from the caption text. Absent when the platform does not report tags; an empty array means it reports none.
isSponsoredboolean | nullalwaysWhether the platform labels the post as an ad, promoted content or a paid partnership.
publishedAtstring | nullalwaysWhen the post was published. Usually an ISO 8601 timestamp; some platforms expose only a date or relative text such as "3 days ago".
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/instagram/reels-search?query=ai%20agents&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  query: 'ai agents',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/instagram/reels-search?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/instagram/reels-search",
    params={
        "query": "ai agents",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or rate_limited (hourly calls to servers you named outside our known list). Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_schema_drift. Not charged
503upstream_unavailable. We could not get this from the platform. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/instagram/reels-search
Open the full playground
GET/v1/instagram/transcript1 creditcacheablebatchable

Reel or video transcript

The caption track Instagram published for a reel or video, as one text block plus timed cues. This is Instagram's own track, never a transcription of the audio, so a transcript here is what the platform published rather than what a model guessed. Instagram has published no caption track on any reel checked so far, so most requests return empty_result, which is free.

ParameterTypeRequiredDescription
urlstringyesReel, post or IGTV URL, or a bare shortcode

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns one Transcript.

Fields
FieldTypePresentDescription
platformone of 47 stringsalways
postIdstringalways
urlstring | nullalways
languagestring | nullalwaysThe transcript's language as the platform labels it, usually a language code such as `en`.
isAutoGeneratedboolean | nullalwaysWhether the platform generated the captions automatically, by speech recognition or machine translation, rather than a person writing them.
textstringalwaysThe full transcript as a single block of text.
cuesobject[]alwaysTimed segments of the transcript.
cues[].startnumberalwaysSeconds from the start of the media.
cues[].endnumber | nullalwaysSeconds from the start of the media. Null when the platform gives no end time.
cues[].textstringalways
durationSecondsnumber | nullalways
sourcecaptions | asr | nullalwaysWhere the transcript came from. `captions`: the platform's own caption track, whether a person wrote it or the platform generated it (see `isAutoGenerated`). `asr`: produced by speech recognition on the audio. Null when this cannot be told.
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/instagram/transcript?url=8XkPqR2nLvE&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  url: '8XkPqR2nLvE',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/instagram/transcript?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/instagram/transcript",
    params={
        "url": "8XkPqR2nLvE",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or rate_limited (hourly calls to servers you named outside our known list). Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_schema_drift. Not charged
503upstream_unavailable. We could not get this from the platform. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/instagram/transcript
Open the full playground
GET/v1/instagram/user-tagged-posts1 creditcacheablebatchable

Posts a profile is tagged in

Public posts by other accounts that tagged this user (the "Tagged" tab). Note this is other people's content: authorHandle is the poster, not the tagged account. Users can hide the tab, which returns empty_result. **Required:** Pass either handle or user_id.

ParameterTypeRequiredDescription
handlestringnoHandle (@nike), or a full instagram.com profile URL. Optional if user_id is given.
user_idstringnoNumeric user id. Skips a lookup. Take it from data.items[].authorId.
cursorstringnopagination.cursor from a previous response
countnumbernoPosts per page, 1-50. Default 12.

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Post in data.items.

Fields
FieldTypePresentDescription
platformone of 47 stringsalways
idstringalways
typevideo | short | image | carousel | text | live | story | reel | audio | album | episode | unknownalwaysWhat kind of post this is. `short` and `reel` are short-form video formats, `live` is a live stream or a recording of one, `carousel` holds several images or videos, `audio` is a music track, `album` is an album, `episode` is a podcast episode, and `unknown` covers anything else.
urlstring | nullalways
titlestring | nullalways
textstring | nullalwaysThe post's text: a caption, a description or the message body.
authorIdstring | nullalways
authorHandlestring | nullalways
authorNamestring | nullalways
thumbnailUrlstring | nullalways
mediaUrlsstring[]always
durationSecondsnumber | nullalways
viewCountnumber | nullalwaysViews. Null means the platform did not expose a count, which is not the same as zero.
likeCountnumber | nullalwaysLikes, or the platform's nearest equivalent. Null means not exposed, not zero.
commentCountnumber | nullalwaysComments. Null means not exposed, not zero.
shareCountnumber | nullalwaysShares, reposts, or the platform's nearest equivalent. Null means not exposed, not zero.
hashtagsstring[]alwaysHashtags or the platform's own topic tags, without the leading #.
mentionsstring[]alwaysHandles mentioned in the post text, without the leading @.
taggedUsersstring[]may be absentUsernames tagged in the media itself, as distinct from `mentions`, which come from the caption text. Absent when the platform does not report tags; an empty array means it reports none.
isSponsoredboolean | nullalwaysWhether the platform labels the post as an ad, promoted content or a paid partnership.
publishedAtstring | nullalwaysWhen the post was published. Usually an ISO 8601 timestamp; some platforms expose only a date or relative text such as "3 days ago".
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/instagram/user-tagged-posts?cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/instagram/user-tagged-posts?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/instagram/user-tagged-posts",
    params={
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or rate_limited (hourly calls to servers you named outside our known list). Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_schema_drift. Not charged
503upstream_unavailable. We could not get this from the platform. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/instagram/user-tagged-posts
Open the full playground

Questions

How much does the Instagram API cost?
Calls cost 1 credit each. Every endpoint is cacheable, and a cache hit costs nothing. A failed request and an empty result are both free, on every endpoint.
Does the Instagram API need a login or cookies?
No. Every endpoint reads public, logged-out pages only — no account, no cookies, no session. An API key identifies your own TrueScrape account and nothing else.
Can I fetch many Instagram targets in one request?
Yes. 17 of 19 are batchable: one POST to /v1/jobs/batch takes many targets and returns a job id to poll.
Can I watch Instagram endpoints for changes?
Yes, 12 of 19. A subscription polls on your schedule and fires your webhook only when the content changed; the rest carry x-subscribable: false in the spec.