Instagram Posts API — List an Account’s Posts
Documentation menu
FetchLayer FetchLayer API

List an account’s posts

The posts a public Instagram account has published, newest first, each with its short code, link, caption, hashtags, mentions, alt text and every rendition. Read this before you build on it: a grid carries no like count, no comment count and no posting date. Instagram does not publish them on a listing, the response says so in notes, and each post reports which shape produced it in fieldsFrom — so a null is never mistaken for a zero. Call post-detail for a post's counts and date, or user-reels, which is the one listing that does carry engagement. Instagram serves 12 posts per page whatever limit says, so a limit of 60 reads five pages and costs five credits. Up to 240 posts and 20 pages in one request. A private account returns no posts and says so in notes. Billing: 1 credit per page read.

POST /user-posts Accounts
https://api.fetchlayer.dev/instagram/user-posts
OpenAPI JSON

Headers

Authorization string required

Bearer token — your FetchLayer API key.

Parameters

username string required

A username with or without the leading @, or a profile URL.

limit integer optional

Maximum items returned, up to 240. Use -1 for the maximum. Instagram serves 12 per page, so a limit of 60 is read as five pages and costs five credits. (default: 12)

pages integer optional

Pages of results to read in one request, up to 20. Use -1 for the maximum. Instagram serves 12 items per page, each page read is one billable page, and the response reports how many were read as pagesFetched. (default: 1)

cursor string optional

Continue from a previous response’s nextCursor. Cursors belong to the route and the account that produced them — do not carry one between routes.

format string optional

json or markdown. Markdown returns a rendered summary instead of the structured record. (default: json)

timeoutMs integer optional

Time limit for each individual page read, in milliseconds (max 60000). It bounds one page, not the whole request.

Response Fields

user-posts

List an account’s posts

transport string

The upstream source. Always "instagram".

notes string[]

Caveats you can act on — a ceiling Instagram imposes, a counter it withholds, a list that stopped early. Several real limits are reported only here, so read them. An empty result always comes with a note explaining it, never as an unexplained empty array.

pagesFetched number

Pages of results read, which is what the request costs: one credit per page. resolve-url reports 0 and is not billed.

username string

The account the posts belong to.

posts object[]

The posts, newest first.

posts[].id string

Instagram’s numeric media id.

posts[].shortcode string

The code in the post URL. post-detail and post-comments both accept it.

posts[].url string

Canonical link to the post or reel.

posts[].kind string

image, video or carousel.

posts[].productType string

What Instagram calls the surface — "feed" for a grid post, "clips" for a reel — or null.

posts[].caption string

The author’s own written post body, or null. This is a caption, not a transcript: Instagram publishes no transcript of spoken audio to a signed-out reader.

posts[].createdAt string

ISO 8601 timestamp, or null. Null on a posts listing — Instagram does not publish a date on a grid.

posts[].likeCount number

Likes, or null where Instagram does not publish them (on a posts listing, or when countsHidden is true).

posts[].commentCount number

Comments, or null on a posts listing.

posts[].playCount number

Plays on a reel. user-reels is the only listing that carries it; a feed image has none.

posts[].countsHidden boolean

True when the account has turned like and view counts off. The counts are then absent rather than zero.

posts[].width number

Pixel width, or null on a listing.

posts[].height number

Pixel height, or null on a listing.

posts[].altText string

Instagram’s own auto-generated image description ("Photo by NASA on August 19, 2026. May be an image of text."), or null. Machine-written alt text, not a caption and not a transcript.

posts[].thumbnailUrl string

Preview frame, or null.

posts[].assets object[]

Ordered and de-duplicated renditions, each with kind, url, width, height and downloadUrl.

posts[].assets[].downloadUrl string

Pass it to GET /media to stream the bytes. Instagram’s own links are signed and expire; this one keeps working.

posts[].carousel object[]

One entry per frame of a carousel, each with its own renditions. Empty for a single image or video.

posts[].author object

id, username, fullName, profilePicUrl, verified, privateAccount and profileUrl. Fields Instagram does not publish on a listing are null.

posts[].coauthors object[]

Accounts credited as co-authors of a collab post.

posts[].taggedUsers object[]

Accounts tagged in the image.

posts[].location object

The place the post was tagged at, or null.

posts[].hashtags string[]

Without the #.

posts[].mentions string[]

Usernames without the @.

posts[].topics string[]

Instagram’s own subject labels for the post ("jwst", "star birth"), where it publishes them.

posts[].hasAudio boolean

Whether the video carries audio, or null.

posts[].fieldsFrom string

"listing" or "detail" — which shape produced this record, so a null count is never mistaken for a zero.

postCount number

How many items are in this response.

hasMore boolean

Whether more results exist beyond what was returned.

nextCursor string

Opaque value to pass back as cursor to continue. null when there is nothing further.

Request

curl -X POST "https://api.fetchlayer.dev/instagram/user-posts" \
  -H "Authorization: Bearer ss-your-key" \
  -H "Content-Type: application/json" \
  -d '{"username":"@nasa","limit":12}'

Response

{
  "transport": "instagram",
  "notes": [
    "Posts in a listing come without like counts, comment counts or posting dates; read a single post for those.",
    "More results are available. Continue with nextCursor."
  ],
  "pagesFetched": 1,
  "username": "nasa",
  "posts": [
    {
      "id": "3967213292204992434",
      "shortcode": "DcOX3hWFiey",
      "url": "https://www.instagram.com/p/DcOX3hWFiey/",
      "kind": "image",
      "productType": "feed",
      "caption": "With your powers combined…\n\nThis colorful picture of the cosmos is the product of teamwork between our @NASAHubble, @NASAWebb, and @NASAChandraXray telescopes. …",
      "createdAt": null,
      "likeCount": null,
      "commentCount": null,
      "playCount": null,
      "countsHidden": null,
      "width": null,
      "height": null,
      "altText": "Photo by NASA on August 19, 2026. May be an image of text.",
      "thumbnailUrl": "https://scontent-muc2-1.cdninstagram.com/v/t51.82787-15/...",
      "assets": [
        {
          "kind": "image",
          "url": "https://scontent-muc2-1.cdninstagram.com/v/t51.82787-15/...",
          "width": null,
          "height": null,
          "downloadUrl": "https://api.fetchlayer.dev/instagram/media?url=..."
        }
      ],
      "carousel": [],
      "author": {
        "id": "528817151",
        "username": null,
        "fullName": null,
        "profilePicUrl": null,
        "verified": null,
        "privateAccount": null,
        "profileUrl": null
      },
      "coauthors": [],
      "taggedUsers": [],
      "location": null,
      "hashtags": [],
      "mentions": [],
      "topics": [],
      "hasAudio": null,
      "fieldsFrom": "listing"
    }
  ],
  "postCount": 12,
  "hasMore": true,
  "nextCursor": "AQHT6ML6wCLtibE4BLFfMtyM6RwkyO"
}