Skip to content

Read many posts in one call (request-body form)

POST
/posts/batch
curl --request POST \
--url https://atlas.aspire.io/api/v1/posts/batch \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{ "ids": [ "instagram:somehandle", "https://www.instagram.com/p/DEF456/" ], "network": "instagram" }'

Identical to GET /posts?ids= in every observable way — same buckets, same cap, same semantics — it exists only because an identifier list can outgrow a URL. Requires posts:read.

The POST twin of the GET ?ids= form — it exists only because an identifier list can outgrow a URL. ids follows the same 1–100 cap and three identifier forms; network, asOrg, and asProfile mean exactly what the query parameters of the same names mean.

Media typeapplication/json
object
ids
required

The identifiers to look up, 1–100 per request. Each is qualified (instagram:somehandle), a post/profile URL, or bare (resolved against network).

Array<string>
>= 1 items <= 100 items
network

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

string
asOrg

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

string
asProfile

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

string
Examples
Examplesomehandle
{
"ids": [
"instagram:somehandle",
"https://www.instagram.com/p/DEF456/"
],
"network": "instagram"
}

Always 200 — per-item outcomes are buckets, never per-item HTTP statuses.

Media typeapplication/json

The three-bucket batch envelope, returned with HTTP 200 always — per-item outcomes are buckets, never per-item HTTP statuses. Every submitted identifier appears in exactly one bucket. The response’s Retry-After header is present iff fetching is non-empty.

object
data
required

Documents we hold — same shape as the single read’s 200 body.

Array<object>
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
fetching
required
Array<object>

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
unavailable
required
Array<object>

A submitted identifier that resolved to ‘not obtainable’. Check reason (and retryable) — most values mean stop retrying.

object
id
required

The identifier exactly as submitted.

string
reason
required

Machine-readable, open vocabulary (additions are non-breaking). outside-recent-media-window and author-unresolved occur on posts only. internal-error means the failure was on our side — retryable is true.

string
retryable

Present, and always true, 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
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"
}
],
"fetching": [
{
"id": "https://www.instagram.com/p/FETCH1/",
"retryAfter": "2026-08-01T00:30:05.000Z"
}
],
"unavailable": [
{
"id": "https://www.instagram.com/p/GONE123/",
"reason": "outside-recent-media-window"
}
]
}
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).

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.