Read one creator by network and handle
const url = 'https://atlas.aspire.io/api/v1/creators/instagram/somehandle?include=posts';const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}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.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”The network to look up the creator on.
Examples
instagramThe creator’s handle on that network, without an @.
Examples
somehandleQuery Parameters
Section titled “Query Parameters”Comma-separated additive extras. posts attaches the creator’s recent posts (core fields only).
Example
postsNames a target Organization to act on, when it differs from your credential’s own organization — for a delegated agency/partner relationship.
Attribution only — associates this read’s discovery/refresh work with one of your Profiles, resolved within your organization.
Responses
Section titled “Responses”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.
Returned with HTTP 200: the document we hold, wrapped the same way a batch read’s data bucket wraps each entry.
object
object
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.
object
The social network this channel belongs to.
The channel’s network-native identifier (Instagram’s numeric user id), stable for the account’s lifetime.
The channel’s current @handle.
Total number of followers.
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.
The channel’s country.
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
The account’s display name (distinct from username).
The account’s bio text.
The website URL listed on the account’s profile.
URL of the account’s current profile picture.
Number of accounts this creator follows.
Total number of posts on this account.
The creator’s gender, when known. Common values are male, female, and unknown (undisclosed), though other values may appear over time.
The age range the creator belongs to (e.g. 18-24), or unknown when undisclosed. Other ranges may appear over time.
Whether the creator has been onboarded to the Creator Marketplace.
URL of the creator’s Portfolio.
Contact email on file for this creator. Not necessarily verified, and no format validation is applied.
Whether the creator has enabled paid partnership messages through the Instagram Creator Marketplace.
Whether the creator has branded content or partnership ads collaboration experience in the past year.
The brands the creator has collaborated with on branded content or partnership ads in the past year.
The badges of the creator. Meta does not publish a closed or confirmed set of possible values — treat as opaque strings, not an enum.
This account’s reach metric (distinct accounts that saw its content).
Whether the account currently has a profile picture set.
Whether the account is published.
Number of distinct accounts that engaged with this creator’s content.
Reels interaction rate, as a percentage of reel views (e.g. 7.2 means 7.2%).
Reels hook rate — the percentage of viewers who kept watching past the opening seconds (e.g. 42 means 42%).
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.
ISO 8601 timestamp of when this channel’s current snapshot was produced — how fresh this document is.
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.
object
The social network this post is on.
The post’s network-native identifier.
The post’s public permalink.
ISO 8601 timestamp of when the post was published.
The post’s caption text.
The post’s media type — video, image, or carousel.
Total like count.
Total comment count.
Total view count.
Total share count.
Total save count.
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
The post author’s network-native account identifier.
The post author’s @handle.
Total number of followers the post author has.
Whether the post author’s identity is verified on the network.
The post author’s country.
Examples
{ "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", "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" } ] }}Headers
Section titled “Headers”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.
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
A submitted identifier we don’t hold yet — this batch read started (or joined) discovery for it. Re-submit it after Retry-After.
object
The identifier exactly as submitted.
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.
Examplegenerated
{ "fetching": [ { "id": "example", "retryAfter": "example" } ]}Headers
Section titled “Headers”On every response, success or failure. Quote it when contacting support — it’s the fastest way for Aspire to find exactly your request.
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.
The one JSON shape every error response (any status other than 200/202) carries.
object
The one JSON shape every error response (any status other than 200/202) carries, wrapped under error in apiErrorResponseSchema.
object
The stable, machine-readable error code. Maps 1:1 to the HTTP status.
Human prose for logs and error screens. Never parse it.
Optional structured extras. Today’s one use: a read-miss 404’s reason (and retryable, when our fault) — see details.reason.
object
Machine-readable, open vocabulary — same values a batch unavailable entry’s own reason carries.
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.
Example
{ "error": { "code": "invalid-input", "message": "ids must contain between 1 and 100 identifiers, got 101" }}Headers
Section titled “Headers”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.
The one JSON shape every error response (any status other than 200/202) carries.
object
The one JSON shape every error response (any status other than 200/202) carries, wrapped under error in apiErrorResponseSchema.
object
The stable, machine-readable error code. Maps 1:1 to the HTTP status.
Human prose for logs and error screens. Never parse it.
Optional structured extras. Today’s one use: a read-miss 404’s reason (and retryable, when our fault) — see details.reason.
object
Machine-readable, open vocabulary — same values a batch unavailable entry’s own reason carries.
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.
Example
{ "error": { "code": "unauthorized", "message": "invalid credential" }}Headers
Section titled “Headers”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).
The one JSON shape every error response (any status other than 200/202) carries.
object
The one JSON shape every error response (any status other than 200/202) carries, wrapped under error in apiErrorResponseSchema.
object
The stable, machine-readable error code. Maps 1:1 to the HTTP status.
Human prose for logs and error screens. Never parse it.
Optional structured extras. Today’s one use: a read-miss 404’s reason (and retryable, when our fault) — see details.reason.
object
Machine-readable, open vocabulary — same values a batch unavailable entry’s own reason carries.
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.
Example
{ "error": { "code": "forbidden", "message": "token lacks creators:read permission" }}Headers
Section titled “Headers”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).
The one JSON shape every error response (any status other than 200/202) carries.
object
The one JSON shape every error response (any status other than 200/202) carries, wrapped under error in apiErrorResponseSchema.
object
The stable, machine-readable error code. Maps 1:1 to the HTTP status.
Human prose for logs and error screens. Never parse it.
Optional structured extras. Today’s one use: a read-miss 404’s reason (and retryable, when our fault) — see details.reason.
object
Machine-readable, open vocabulary — same values a batch unavailable entry’s own reason carries.
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.
Example
{ "error": { "code": "not-found", "message": "no creator found for instagram/somehandle", "details": { "reason": "account-not-discoverable" } }}Headers
Section titled “Headers”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.
The one JSON shape every error response (any status other than 200/202) carries.
object
The one JSON shape every error response (any status other than 200/202) carries, wrapped under error in apiErrorResponseSchema.
object
The stable, machine-readable error code. Maps 1:1 to the HTTP status.
Human prose for logs and error screens. Never parse it.
Optional structured extras. Today’s one use: a read-miss 404’s reason (and retryable, when our fault) — see details.reason.
object
Machine-readable, open vocabulary — same values a batch unavailable entry’s own reason carries.
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.
Example
{ "error": { "code": "rate-limited", "message": "rate limit exceeded (60 requests/minute for this principal)" }}Headers
Section titled “Headers”On every response, success or failure. Quote it when contacting support — it’s the fastest way for Aspire to find exactly your request.
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.
The one JSON shape every error response (any status other than 200/202) carries.
object
The one JSON shape every error response (any status other than 200/202) carries, wrapped under error in apiErrorResponseSchema.
object
The stable, machine-readable error code. Maps 1:1 to the HTTP status.
Human prose for logs and error screens. Never parse it.
Optional structured extras. Today’s one use: a read-miss 404’s reason (and retryable, when our fault) — see details.reason.
object
Machine-readable, open vocabulary — same values a batch unavailable entry’s own reason carries.
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.
Example
{ "error": { "code": "internal-error", "message": "the request could not be completed" }}Headers
Section titled “Headers”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.
The one JSON shape every error response (any status other than 200/202) carries.
object
The one JSON shape every error response (any status other than 200/202) carries, wrapped under error in apiErrorResponseSchema.
object
The stable, machine-readable error code. Maps 1:1 to the HTTP status.
Human prose for logs and error screens. Never parse it.
Optional structured extras. Today’s one use: a read-miss 404’s reason (and retryable, when our fault) — see details.reason.
object
Machine-readable, open vocabulary — same values a batch unavailable entry’s own reason carries.
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.
Example
{ "error": { "code": "unavailable", "message": "temporarily unavailable" }}Headers
Section titled “Headers”On every response, success or failure. Quote it when contacting support — it’s the fastest way for Aspire to find exactly your request.