Skip to content

Read one post by URL, or many posts by identifier list

GET
/posts
curl --request GET \
--url 'https://atlas.aspire.io/api/v1/posts?url=https%3A%2F%2Fwww.instagram.com%2Fp%2FDEF456%2F&network=instagram' \
--header 'Authorization: Bearer <token>'

Two mutually exclusive forms — supplying both url and ids is a 400. url is a single read: returns the post document wrapped as { data: <post> } (200), a FetchingResponse (202), or an error envelope (404). ids is the batch form: always 200, the three-bucket envelope. A post read can take longer than an account read — it may walk the author’s recent media. Requires posts:read.

url
string

The post’s URL — the single-read identifier (a post identifier is a URL, unlike a creator’s clean network/handle segments). Exactly one of url or ids must be supplied.

Examples
Examplesomehandle
https://www.instagram.com/p/DEF456/
ids
string

Comma-separated identifiers, 1–100 — selects the batch form. Same identifier grammar as GET /creators?ids=. Exactly one of url or ids must be supplied.

network
string
default: instagram

Default network for BARE identifiers in ids (defaults to instagram). Never a filter — a qualified (instagram:handle) or URL identifier carries its own network.

include
string

ASP-1144 — comma-separated AI-enrichment fields to add to the returned analysis object (both the url and ids forms of GET /posts; not supported on POST /posts/batch). Each named field appears under analysis in the response ONLY when requested — an unrequested field’s key is entirely absent, never null-padded. Supported values: narration, transcript, overlayText, languages, aestheticTags, brandSafety, commercialAnalysis, emotionalAnalysis, productionAnalysis, vibeAnalysis, subjectAnalysis, commentSentimentLabel, commentSentimentScore, commentSentimentSummary, commentSentimentRationale, commentSentimentThemes, commentSentimentBreakdown, commentSentimentTotalCommentCount, commentSentimentRelevantCommentCount. An unrecognized value is a 400.

asOrg
string

Names a target Organization to act on, when it differs from your credential’s own organization — for a delegated agency/partner relationship.

asProfile
string

Attribution only — associates this read’s discovery/refresh work with one of your Profiles, resolved within your organization.

SinglePostResponse ({ data: <post> }) for the url form; PostsBatchResponse (the three-bucket envelope, Retry-After present iff fetching is non-empty) for the ids form.

Media typeapplication/json
One of:

Returned with HTTP 200: the document we hold, wrapped the same way a batch read’s data bucket wraps each entry.

object
data
required
object
network
required

The social network this post is on.

string
Allowed value: instagram
externalId
required

The post’s network-native identifier.

string | null
url
required

The post’s public permalink.

string | null
postedAt
required

ISO 8601 timestamp of when the post was published.

string | null
text
required

The post’s caption text.

string | null
mediaKind
required

The post’s media type — video, image, or carousel.

string | null
Allowed values: video image carousel
likeCount
required

Total like count.

number | null
commentCount
required

Total comment count.

number | null
viewCount
required

Total view count.

number | null
shareCount
required

Total share count.

number | null
saveCount
required

Total save count.

number | null
author
required

The post’s author — a thin, no-PII summary of the creator account.

object
accountId
required

The post author’s network-native account identifier.

string | null
username
required

The post author’s @handle.

string | null
followersCount
required

Total number of followers the post author has.

number | null
verified
required

Whether the post author’s identity is verified on the network.

boolean | null
country
required

The post author’s country.

string | null
instagram
required

The full Instagram-specific field set for this post — present with every field null/empty if not yet observed, never entirely absent.

object
igMediaId
required

Numeric media id for this post.

string | null
igUserId
required

The Instagram-scoped user id of the post’s author.

string | null
authorUsername
required

The post author’s @handle (core author.username is canonical).

string | null
shortcode
required

Short alphanumeric code for this post, as used in its permalink.

string | null
mediaType
required

The post’s raw media-type value (core mediaKind is the mapped video/image/carousel value).

string | null
mediaAudioType
required

The type of audio used in the media. Can be MUSIC or ORIGINAL_SOUND.

string | null
mediaProductType
required

Product-type classification for this media (e.g. feed post, reel, story).

string | null
isSharedToFeed
required

For Reels only. When true, the reel can appear in both the Feed and Reels tabs. When false, the reel can only appear in the Reels tab.

boolean | null
permalink
required

The post’s public URL — same value as core url.

string | null
caption
required

The post’s caption text — same value as core text.

string | null
organicLikeCount
required

Likes attributable to organic (non-paid) delivery only.

number | null
totalLikeCount
required

Total likes across organic and paid delivery — same value as core likeCount.

number | null
organicCommentCount
required

Comments attributable to organic delivery only.

number | null
totalCommentCount
required

Total comments across organic and paid delivery — same value as core commentCount.

number | null
organicViewCount
required

Views attributable to organic delivery only.

number | null
totalViewCount
required

Total views across organic and paid delivery — same value as core viewCount.

number | null
organicRepostCount
required

Reposts (reshares by other accounts) attributable to organic delivery.

number | null
organicSaveCount
required

Saves attributable to organic delivery only.

number | null
organicShareCount
required

Shares attributable to organic delivery only.

number | null
organicReach
required

Distinct accounts that organically saw this post.

number | null
organicTotalInteractions
required

Sum of organic likes, comments, saves, and shares on this post.

number | null
organicFollows
required

Accounts that started following the creator as a direct result of this post (organic only).

number | null
organicProfileVisits
required

Visits to the creator’s profile attributable to this post (organic only).

number | null
organicProfileActivity
required

The number of actions people took on the creator’s profile after visiting it from this post — bio link clicks, or taps on the call, direction, email, or text buttons (organic only, feed and story posts).

number | null
organicFacebookViews
required

Views of this post’s cross-posted copy on Facebook (organic only).

number | null
organicCrosspostedViews
required

Total number of times this post was played, aggregated across Instagram and Facebook (organic only, Reels only).

number | null
organicIgReelsAvgWatchTime
required

Average watch time per view, for Reels (organic only).

number | null
organicIgReelsVideoViewTotalTime
required

Total cumulative watch time across all views, for Reels (organic only).

number | null
organicLinkClicks
required

Clicks on a link included in this post (e.g. a Story link sticker), organic only.

number | null
organicNavigation
required

Total navigation actions taken while viewing this post — the sum of exits, taps forward, taps back, and advances to the next story (organic only, story posts).

number | null
organicReplies
required

Replies sent in response to this post (e.g. Story replies), organic only.

number | null
organicExits
required

Instances of a viewer exiting out of this post entirely (e.g. leaving a Story), organic only.

number | null
organicTapsForward
required

Taps to advance past this post (e.g. tapping forward through a Story), organic only.

number | null
organicTapsBack
required

Taps to go back and re-view this post (e.g. tapping back through a Story), organic only.

number | null
hashtags
required

Hashtags extracted from this post’s caption.

Array<string>
mentions
required

Accounts mentioned in this post — see PostMention fields above.

Array<object>
object
username
required

The @handle of the mentioned account.

string
type
required

How the mention occurred — TAG, CAPTION, STORY, COLLAB, or PAID_PARTNERSHIP.

string
Allowed values: TAG CAPTION STORY COLLAB PAID_PARTNERSHIP
resolved
required

Whether the mentioned username has been resolved to a known account in our system.

boolean
inviteStatus
required
string | null
updatedAt
required

ISO 8601 timestamp of when this post’s current snapshot was produced — how fresh this document is.

string | null
analysis

AI-generated (Gemini multimodal) enrichment preview — opt-in via ?include= (see the include query parameter), one key per requested field. Coverage and shape may change without notice.

object
narration

AI-generated (Gemini multimodal) narration of the video/audio content.

string | null
transcript

AI-generated (Gemini multimodal) transcript of spoken audio.

string | null
overlayText

AI-detected on-screen text overlays, in detection order.

Array<string> | null
languages

AI-detected spoken/on-screen languages, as free-text labels.

Array<string> | null
aestheticTags

AI-generated free-text aesthetic/style tags.

Array<string> | null
brandSafety

AI-judged brand-safety risk per GARM category — a judged VERDICT, not raw enrichment. null if not yet judged, or if the judged shape no longer matches the current GARM taxonomy.

object
adult_content
required
string
Allowed values: High Risk Medium Risk Low Risk
arms_ammunition
required
string
Allowed values: High Risk Medium Risk Low Risk
crime_harmful_acts
required
string
Allowed values: High Risk Medium Risk Low Risk
death_injury
required
string
Allowed values: High Risk Medium Risk Low Risk
online_piracy
required
string
Allowed values: High Risk Medium Risk Low Risk
hate_speech
required
string
Allowed values: High Risk Medium Risk Low Risk
obscenity_profanity
required
string
Allowed values: High Risk Medium Risk Low Risk
illegal_drugs
required
string
Allowed values: High Risk Medium Risk Low Risk
spam_harmful
required
string
Allowed values: High Risk Medium Risk Low Risk
terrorism
required
string
Allowed values: High Risk Medium Risk Low Risk
debated_sensitive_social_issue
required
string
Allowed values: High Risk Medium Risk Low Risk
misinformation
required
string
Allowed values: High Risk Medium Risk Low Risk
commercialAnalysis

AI-detected commercial signals — featured products/brands, calls to action, promo codes, and a 1-5 promotional-intent score.

object
featuredProducts
required
Array<string> | null
featuredBrands
required
Array<string> | null
callToActions
required
Array<string> | null
promoCodes
required
Array<string> | null
promotionalIntent
required
number | null
emotionalAnalysis

AI-judged primary emotion and tone.

object
primaryEmotion
required
string | null
tone
required
Array<string> | null
productionAnalysis

AI-judged production quality and technique signals.

object
productionQuality
required
number | null
cameraTechniques
required
Array<string> | null
audioStyle
required
string | null
lightingStyle
required
string | null
vibeAnalysis

Opaque AI-generated vibe classification — shape is not fixed; treat as untyped JSON.

subjectAnalysis

Opaque AI-generated subject classification — shape is not fixed; treat as untyped JSON.

commentSentimentLabel

AI-judged overall comment sentiment label.

string | null
Allowed values: positive neutral negative mixed
commentSentimentScore

AI-judged overall comment sentiment score.

number | null
commentSentimentSummary

AI-generated free-text summary of comment sentiment.

string | null
commentSentimentRationale

AI-generated free-text rationale for the sentiment judgment.

string | null
commentSentimentThemes

AI-generated free-text comment themes.

Array<string> | null
commentSentimentBreakdown

AI-judged comment sentiment split into positive/neutral/negative buckets, each a count and percentage of comments analyzed.

object
positive
required
object
count
required
number
percentage
required
number
neutral
required
object
count
required
number
percentage
required
number
negative
required
object
count
required
number
percentage
required
number
commentSentimentTotalCommentCount

Total comments considered in the sentiment judgment.

number | null
commentSentimentRelevantCommentCount

Comments judged relevant to the sentiment analysis — a subset of the total.

number | null
Examples
Examplesomehandle
{
"data": {
"network": "instagram",
"externalId": "media-def456",
"url": "https://www.instagram.com/p/DEF456/",
"postedAt": "2026-08-01T00:00:00.000Z",
"text": "a conformance caption",
"mediaKind": "image",
"likeCount": 12,
"commentCount": 1,
"viewCount": 110,
"shareCount": 3,
"saveCount": 2,
"author": {
"accountId": "ig-def456",
"username": "somehandle",
"followersCount": 1000,
"verified": true,
"country": "US"
},
"instagram": {},
"updatedAt": "2026-08-01T00:00:00.000Z"
}
}
x-request-id
string

On every response, success or failure. Quote it when contacting support — it’s the fastest way for Aspire to find exactly your request.

Retry-After
string

Present iff fetching is non-empty — delta-seconds until those entries are worth re-submitting (every fetching entry in one response shares the same instant).

We don’t hold this entity yet — THIS request just started (or joined) the work to get it. Wait Retry-After seconds and re-read the same URL: the read is the poll, there is no job resource. A read here is not free of side effects — reading an entity we don’t hold triggers discovery, and reading a stale one triggers a refresh. (url form only — the ids form expresses in-flight discovery as the fetching bucket inside a 200.)

Media typeapplication/json

Returned with HTTP 202: the entity isn’t held yet and THIS request just started (or joined) the work to get it. Always exactly one entry (the identifier just submitted) — an array for shape-parity with the batch envelope’s fetching bucket, not because a single read can return more than one. Wait Retry-After seconds, then re-read the same URL — the read is the poll; there is no job resource.

object
fetching
required
Array<object>
>= 1 items <= 1 items

A submitted identifier we don’t hold yet — this batch read started (or joined) discovery for it. Re-submit it after Retry-After.

object
id
required

The identifier exactly as submitted.

string
retryAfter
required

ISO 8601 instant — every fetching entry in one response shares the same instant, and the response’s Retry-After header (present iff this bucket is non-empty) is its delta-seconds twin.

string
Examplegenerated
{
"fetching": [
{
"id": "example",
"retryAfter": "example"
}
]
}
x-request-id
string

On every response, success or failure. Quote it when contacting support — it’s the fastest way for Aspire to find exactly your request.

Retry-After
string

Delta-seconds (RFC 9110 §10.2.3), always ≥ 1. The server controls the backoff — polling faster than this burns rate limit and gets the data no sooner.

A malformed request — e.g. a batch outside the 1–100 identifier cap, an unrecognized include value, url and ids supplied together, or an unparseable JSON body.

Media typeapplication/json

The one JSON shape every error response (any status other than 200/202) carries.

object
error
required

The one JSON shape every error response (any status other than 200/202) carries, wrapped under error in apiErrorResponseSchema.

object
code
required

The stable, machine-readable error code. Maps 1:1 to the HTTP status.

string
message
required

Human prose for logs and error screens. Never parse it.

string
details

Optional structured extras. Today’s one use: a read-miss 404’s reason (and retryable, when our fault) — see details.reason.

object
reason
required

Machine-readable, open vocabulary — same values a batch unavailable entry’s own reason carries.

string
retryable

Present (and true) only when the failure was on our side rather than a fact about the entity — retry after a few minutes. Absent means terminal: stop retrying.

boolean
Example
{
"error": {
"code": "invalid-input",
"message": "ids must contain between 1 and 100 identifiers, got 101"
}
}
x-request-id
string

On every response, success or failure. Quote it when contacting support — it’s the fastest way for Aspire to find exactly your request.

Missing, malformed, expired, or revoked credential.

Media typeapplication/json

The one JSON shape every error response (any status other than 200/202) carries.

object
error
required

The one JSON shape every error response (any status other than 200/202) carries, wrapped under error in apiErrorResponseSchema.

object
code
required

The stable, machine-readable error code. Maps 1:1 to the HTTP status.

string
message
required

Human prose for logs and error screens. Never parse it.

string
details

Optional structured extras. Today’s one use: a read-miss 404’s reason (and retryable, when our fault) — see details.reason.

object
reason
required

Machine-readable, open vocabulary — same values a batch unavailable entry’s own reason carries.

string
retryable

Present (and true) only when the failure was on our side rather than a fact about the entity — retry after a few minutes. Absent means terminal: stop retrying.

boolean
Example
{
"error": {
"code": "unauthorized",
"message": "invalid credential"
}
}
x-request-id
string

On every response, success or failure. Quote it when contacting support — it’s the fastest way for Aspire to find exactly your request.

Valid credential, but it lacks the <resource>:<action> permission this operation requires (stated in the operation description).

Media typeapplication/json

The one JSON shape every error response (any status other than 200/202) carries.

object
error
required

The one JSON shape every error response (any status other than 200/202) carries, wrapped under error in apiErrorResponseSchema.

object
code
required

The stable, machine-readable error code. Maps 1:1 to the HTTP status.

string
message
required

Human prose for logs and error screens. Never parse it.

string
details

Optional structured extras. Today’s one use: a read-miss 404’s reason (and retryable, when our fault) — see details.reason.

object
reason
required

Machine-readable, open vocabulary — same values a batch unavailable entry’s own reason carries.

string
retryable

Present (and true) only when the failure was on our side rather than a fact about the entity — retry after a few minutes. Absent means terminal: stop retrying.

boolean
Example
{
"error": {
"code": "forbidden",
"message": "token lacks creators:read permission"
}
}
x-request-id
string

On every response, success or failure. Quote it when contacting support — it’s the fastest way for Aspire to find exactly your request.

A read-miss (branch on details.reason — retry only if details.retryable is true, never on message prose), an unknown asProfile (deliberately indistinguishable from a nonexistent one, so slugs are not enumerable), or an unsupported network. details.reason is an open vocabulary (additions are non-breaking). Values today: account-not-discoverable (creators — terminal; a personal account and a nonexistent handle are indistinguishable), not-supported-on-network (the network isn’t supported yet — terminal until it ships), outside-recent-media-window (posts — terminal), author-unresolved (posts), unparseable-identifier, and internal-error with details.retryable: true (our fault — retry after a few minutes).

Media typeapplication/json

The one JSON shape every error response (any status other than 200/202) carries.

object
error
required

The one JSON shape every error response (any status other than 200/202) carries, wrapped under error in apiErrorResponseSchema.

object
code
required

The stable, machine-readable error code. Maps 1:1 to the HTTP status.

string
message
required

Human prose for logs and error screens. Never parse it.

string
details

Optional structured extras. Today’s one use: a read-miss 404’s reason (and retryable, when our fault) — see details.reason.

object
reason
required

Machine-readable, open vocabulary — same values a batch unavailable entry’s own reason carries.

string
retryable

Present (and true) only when the failure was on our side rather than a fact about the entity — retry after a few minutes. Absent means terminal: stop retrying.

boolean
Example
{
"error": {
"code": "not-found",
"message": "no creator found for instagram/somehandle",
"details": {
"reason": "account-not-discoverable"
}
}
}
x-request-id
string

On every response, success or failure. Quote it when contacting support — it’s the fastest way for Aspire to find exactly your request.

Over the per-principal request budget (fixed one-minute window; default 60 requests/minute, raisable per Service Account). Rejected requests still count against the window. Honour Retry-After.

Media typeapplication/json

The one JSON shape every error response (any status other than 200/202) carries.

object
error
required

The one JSON shape every error response (any status other than 200/202) carries, wrapped under error in apiErrorResponseSchema.

object
code
required

The stable, machine-readable error code. Maps 1:1 to the HTTP status.

string
message
required

Human prose for logs and error screens. Never parse it.

string
details

Optional structured extras. Today’s one use: a read-miss 404’s reason (and retryable, when our fault) — see details.reason.

object
reason
required

Machine-readable, open vocabulary — same values a batch unavailable entry’s own reason carries.

string
retryable

Present (and true) only when the failure was on our side rather than a fact about the entity — retry after a few minutes. Absent means terminal: stop retrying.

boolean
Example
{
"error": {
"code": "rate-limited",
"message": "rate limit exceeded (60 requests/minute for this principal)"
}
}
x-request-id
string

On every response, success or failure. Quote it when contacting support — it’s the fastest way for Aspire to find exactly your request.

Retry-After
string

Delta-seconds (RFC 9110 §10.2.3), always ≥ 1. The server controls the backoff — polling faster than this burns rate limit and gets the data no sooner.

Our fault. The message is deliberately generic — internal error detail is never exposed. Safe to retry with backoff.

Media typeapplication/json

The one JSON shape every error response (any status other than 200/202) carries.

object
error
required

The one JSON shape every error response (any status other than 200/202) carries, wrapped under error in apiErrorResponseSchema.

object
code
required

The stable, machine-readable error code. Maps 1:1 to the HTTP status.

string
message
required

Human prose for logs and error screens. Never parse it.

string
details

Optional structured extras. Today’s one use: a read-miss 404’s reason (and retryable, when our fault) — see details.reason.

object
reason
required

Machine-readable, open vocabulary — same values a batch unavailable entry’s own reason carries.

string
retryable

Present (and true) only when the failure was on our side rather than a fact about the entity — retry after a few minutes. Absent means terminal: stop retrying.

boolean
Example
{
"error": {
"code": "internal-error",
"message": "the request could not be completed"
}
}
x-request-id
string

On every response, success or failure. Quote it when contacting support — it’s the fastest way for Aspire to find exactly your request.

A dependency needed to verify the credential is unreachable — the credential was neither accepted nor rejected. Retry with backoff.

Media typeapplication/json

The one JSON shape every error response (any status other than 200/202) carries.

object
error
required

The one JSON shape every error response (any status other than 200/202) carries, wrapped under error in apiErrorResponseSchema.

object
code
required

The stable, machine-readable error code. Maps 1:1 to the HTTP status.

string
message
required

Human prose for logs and error screens. Never parse it.

string
details

Optional structured extras. Today’s one use: a read-miss 404’s reason (and retryable, when our fault) — see details.reason.

object
reason
required

Machine-readable, open vocabulary — same values a batch unavailable entry’s own reason carries.

string
retryable

Present (and true) only when the failure was on our side rather than a fact about the entity — retry after a few minutes. Absent means terminal: stop retrying.

boolean
Example
{
"error": {
"code": "unavailable",
"message": "temporarily unavailable"
}
}
x-request-id
string

On every response, success or failure. Quote it when contacting support — it’s the fastest way for Aspire to find exactly your request.