Skip to content

Read one creator by network and handle

GET
/creators/{network}/{handle}
curl --request GET \
--url 'https://atlas.aspire.io/api/v1/creators/instagram/somehandle?include=posts' \
--header 'Authorization: Bearer <token>'

Resolves to exactly one of three outcomes: 200 (we hold the document, wrapped as { data: <creator> } — a creator is expressed as its channels, always at least one, unordered), 202 (discovery just started — a fetching bucket entry; re-read after Retry-After), or 404 (not obtainable — an error envelope; branch on details.reason). Requires creators:read.

network
required
string
Allowed values: instagram

The network to look up the creator on.

Examples
Examplesomehandle
instagram
handle
required
string

The creator’s handle on that network, without an @.

Examples
Examplesomehandle
somehandle
include
string
Allowed values: posts

Comma-separated additive extras. posts attaches the creator’s recent posts (core fields only).

Example
posts
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.

We hold the data (and it’s fresh enough). The creator document is wrapped as { data: <creator> }data.channels carries this creator’s channels (always at least one, unordered — do not read position as significance; today this is always exactly one channel, multi-channel hydration is not yet implemented), and data.posts is present only when requested via include=posts.

Media typeapplication/json

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
channels
required

This creator’s channels. Always at least one. UNORDERED — carries no meaningful index; do not read position as significance. Intended to eventually return every channel a creator owns, not only the ones a search filter matched — today this is always exactly one channel; multi-channel hydration is not yet implemented.

Array<object>
>= 1 items
object
network
required

The social network this channel belongs to.

string
Allowed value: instagram
externalId
required

The channel’s network-native identifier (Instagram’s numeric user id), stable for the account’s lifetime.

string | null
username
required

The channel’s current @handle.

string | null
followersCount
required

Total number of followers.

number | null
verified
required

Whether the network has verified this channel’s identity. Sourced only from a successful Instagram Creator Marketplace lookup — null for a brand/business account (Creator Marketplace doesn’t cover them) or when Creator Marketplace credentials aren’t configured for the org.

boolean | null
country
required

The channel’s country.

string | null
instagram
required

The Instagram-specific field set for this channel (see below) — every field is null if not yet observed, except audienceDemographics, which is absent unless we hold a live audience-insights grant.

object
name
required

The account’s display name (distinct from username).

string | null
biography
required

The account’s bio text.

string | null
website
required

The website URL listed on the account’s profile.

string | null
profilePictureUrl
required

URL of the account’s current profile picture.

string | null
followsCount
required

Number of accounts this creator follows.

number | null
mediaCount
required

Total number of posts on this account.

number | null
gender
required

The creator’s gender, when known. Common values are male, female, and unknown (undisclosed), though other values may appear over time.

string | null
ageBucket
required

The age range the creator belongs to (e.g. 18-24), or unknown when undisclosed. Other ranges may appear over time.

string | null
onboardedStatus
required

Whether the creator has been onboarded to the Creator Marketplace.

boolean | null
portfolioUrl
required

URL of the creator’s Portfolio.

string | null
email
required

Contact email on file for this creator. Not necessarily verified, and no format validation is applied.

string | null
isPaidPartnershipMessagesEnabled
required

Whether the creator has enabled paid partnership messages through the Instagram Creator Marketplace.

boolean | null
hasBrandPartnershipExperience
required

Whether the creator has branded content or partnership ads collaboration experience in the past year.

boolean | null
pastBrandPartnershipPartners
required

The brands the creator has collaborated with on branded content or partnership ads in the past year.

Array<string> | null
badges
required

The badges of the creator. Meta does not publish a closed or confirmed set of possible values — treat as opaque strings, not an enum.

Array<string> | null
reach
required

This account’s reach metric (distinct accounts that saw its content).

number | null
hasProfilePic
required

Whether the account currently has a profile picture set.

boolean | null
isPublished
required

Whether the account is published.

boolean | null
creatorEngagedAccounts
required

Number of distinct accounts that engaged with this creator’s content.

number | null
reelsInteractionRate
required

Reels interaction rate, as a percentage of reel views (e.g. 7.2 means 7.2%).

number | null
reelsHookRate
required

Reels hook rate — the percentage of viewers who kept watching past the opening seconds (e.g. 42 means 42%).

number | null
audienceDemographics

Engaged-audience demographics, present only for accounts we hold a live grant with audience-insights scope for. Its internal shape is NOT part of the v1 compatibility promise (D19) — Meta’s own payload, passed through opaquely. Meta returns 5 breakdown dimensions: country, city, gender, age, and the combined age,gender. Results may not be exhaustive.

updatedAt
required

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

string | null
posts

This creator’s recent posts, included only when the request asked for ?include=posts. Absent (not empty) when not requested. Posts are not nested per channel — to attribute a post back to one of channels, match its author.accountId against that channel’s externalId.

Array<object>
object
network
required

The social network this post is on.

string | null
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
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. author.accountId is the only way to attribute a post back to one of Creator.channels — match it against that channel’s externalId.

object
accountId
required

The post author’s network-native account identifier.

string
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
Examples
Examplesomehandle
{
"data": {
"channels": [
{
"network": "instagram",
"externalId": "17841400000000000",
"username": "somehandle",
"followersCount": 12345,
"verified": false,
"country": "US",
"instagram": {
"name": "Some Handle",
"biography": "Creator bio goes here.",
"website": "https://example.com",
"profilePictureUrl": "https://example.com/pic.jpg",
"followsCount": 200,
"mediaCount": 350,
"gender": "female",
"ageBucket": "25-34",
"onboardedStatus": true,
"portfolioUrl": "https://example.com/portfolio",
"email": "[email protected]",
"isPaidPartnershipMessagesEnabled": true,
"hasBrandPartnershipExperience": true,
"pastBrandPartnershipPartners": [
"brand-a",
"brand-b"
],
"badges": [
"top-creator"
],
"reach": 8500,
"hasProfilePic": true,
"isPublished": true,
"creatorEngagedAccounts": 1362,
"reelsInteractionRate": 7.2,
"reelsHookRate": 42
},
"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.

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.

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.