# Instagram Graph API: Get Posts, Fields, and Pagination

Get Instagram posts with the Graph API: the /media edge, the fields worth asking for, carousel children, pagination, permissions, and whose posts you can read.

Canonical page: https://www.tryadeli.com/blog/instagram-api-get-posts
Last updated: 2026-10-26

By Mika Reyes, Co-founder, Adeli. Published 2026-10-26.

## The short answer

To get posts with the Instagram Graph API, call GET /{ig-user-id}/media with a fields list such as caption, media_type, media_url, permalink, and timestamp, then follow the paging cursors. It returns up to the 10,000 most recent posts of a professional account that authorized your app. Carousel items come from the children edge. Adeli lists posts from every connected account through one endpoint.

**To get posts with the Instagram Graph API, send `GET /{ig-user-id}/media` with the fields you want, then follow the paging cursors until there are no more pages.** Each item is an IG Media object with a caption, a media type, a media URL, a permalink, and a timestamp. Carousels need one extra call to their `children` edge.

Whose posts you can read is the limit. The endpoint only works for a **professional account that authorized your app**, which matters if you're building a product where your customers connect their own Instagram accounts. For the bigger picture, start with our [Instagram API](https://www.tryadeli.com/blog/instagram-api-guide) guide.

## Which Instagram accounts can you get posts from?

**The Instagram Graph API returns posts from Instagram professional accounts (Business or Creator) that granted your app access.** Three cases cover almost every "get posts by user" request:

| Whose posts | How to read them | What you get |
|---|---|---|
| **An account that authorized your app** | `GET /{ig-user-id}/media` | Every field below, up to the 10,000 most recent posts |
| **Another Business or Creator account** | `business_discovery` on your own IG user, by username | Public fields of that account's media |
| **A personal account, or any arbitrary public post** | Not possible | Nothing |

Business discovery is covered in our [Instagram followers count guide](https://www.tryadeli.com/blog/instagram-api-followers), which uses the same call. Meta shut down the old consumer API that read personal accounts. As Shravya Garlapati wrote on the [Meta for Developers blog](https://developers.facebook.com/blog/post/2024/09/04/update-on-instagram-basic-display-api) on September 4, 2024:

> "Starting on December 4th, 2024, Instagram Basic Display API will no longer be available."

**For you, that means "get public posts" has no official answer for personal accounts.** Tools that claim otherwise scrape Instagram outside the official API.

## Instagram Login or Facebook Login: which do you need to get posts?

**Both versions of the Instagram API can read an account's own posts; they differ in host, token, and permissions.** Pick Instagram Login unless you also need business discovery or hashtag search, which Meta documents for Facebook Login.

| | Instagram API with Instagram Login | Instagram API with Facebook Login |
|---|---|---|
| **Host** | `graph.instagram.com` | `graph.facebook.com` |
| **Token** | Instagram User access token | Facebook User access token |
| **Permission to read media** | `instagram_business_basic` | `instagram_basic` plus `pages_read_engagement` |
| **Facebook Page needed** | No | Yes, linked to the Instagram account |
| **Business discovery** | Not documented | Yes |

Source: Meta's [IG Media reference](https://developers.facebook.com/docs/instagram-platform/instagram-graph-api/reference/ig-media). With Facebook Login, a user who got their Page role through Business Manager also needs `ads_management` or `ads_read`. Our [Instagram API permissions](https://www.tryadeli.com/blog/instagram-api-permissions) post lists every scope and how Meta reviews it.

## How to get all posts from an Instagram user

**Call the media edge on the IG user ID with a `fields` parameter.** Without `fields`, Meta returns only each post's `id`. With Instagram Login:

```bash
curl -G "https://graph.instagram.com/v26.0/<IG_USER_ID>/media" \
  -H "Authorization: Bearer $IG_ACCESS_TOKEN" \
  --data-urlencode "fields=id,caption,media_type,media_url,thumbnail_url,permalink,timestamp,like_count,comments_count"
```

The response puts posts in `data` and cursors in `paging`:

```json
{
  "data": [
    {
      "id": "17895695668004550",
      "caption": "New drop this Friday",
      "media_type": "CAROUSEL_ALBUM",
      "media_url": "https://scontent.cdninstagram.com/...",
      "permalink": "https://www.instagram.com/p/.../",
      "timestamp": "2026-10-20T15:04:11+0000",
      "like_count": 120,
      "comments_count": 8
    }
  ],
  "paging": {
    "cursors": { "before": "QVFIU...", "after": "QVFIU..." },
    "next": "https://graph.instagram.com/v26.0/<IG_USER_ID>/media?after=QVFIU..."
  }
}
```

**To get all posts, request the `next` URL until the response has no `next`.** Meta's [media edge reference](https://developers.facebook.com/docs/instagram-platform/instagram-graph-api/reference/ig-user/media) caps the edge at **the 10,000 most recently created posts**, so very old posts on a large account are out of reach.

For a time window, the edge also supports **time-based pagination**: add `since` and `until` as Unix timestamps. A sync job that asks only for posts since its last run makes far fewer calls.

## Which post data can you request?

**IG Media fields cover the post itself, its engagement counts, and where it was published.** These are the ones most products need, per Meta's [IG Media reference](https://developers.facebook.com/docs/instagram-platform/instagram-graph-api/reference/ig-media):

| Field | What it returns | Watch out for |
|---|---|---|
| `caption` | The caption text | Not set on carousel children |
| `media_type` | `IMAGE`, `VIDEO`, or `CAROUSEL_ALBUM` | Reels come back as `VIDEO` |
| `media_product_type` | `FEED`, `STORY`, `REELS`, or `AD` | Tells a Reel apart from a feed video |
| `media_url` | The image or video file | Omitted for video with copyrighted or licensed audio |
| `thumbnail_url` | A cover image | `VIDEO` only |
| `permalink` | The post's public URL | Not available on carousel children |
| `timestamp` | Creation time, ISO 8601 in UTC | |
| `like_count` | Likes | Omitted when the owner hides like counts |
| `comments_count` | Comments, including replies | |
| `shortcode`, `username`, `alt_text` | Identifiers and accessibility text | |

**Treat `media_url` as optional.** Meta also omits it for Reels whose owner turned off downloads when you read someone else's media. Fall back to `thumbnail_url` or `permalink` in your UI. For reach, views, and saves, you need the insights edge, covered in our [Instagram insights API](https://www.tryadeli.com/blog/instagram-insights-api) guide.

## How do you get the images in a carousel post?

**Ask for the `children` edge, either nested in the media request or on the carousel's own ID.** A carousel's top-level `media_type` is `CAROUSEL_ALBUM`, and its `media_url` is only the first item. Field expansion gets every item in one call:

```bash
curl -G "https://graph.instagram.com/v26.0/<IG_USER_ID>/media" \
  -H "Authorization: Bearer $IG_ACCESS_TOKEN" \
  --data-urlencode "fields=id,media_type,permalink,children{id,media_type,media_url,thumbnail_url}"
```

Children carry their own `media_type` and `media_url`, but **no caption, no permalink, and no like or comment counts**. Those live on the parent. Our [Instagram carousel API](https://www.tryadeli.com/blog/instagram-carousel-api) post covers the publishing side.

## What are the limits when you get Instagram posts?

**The media edge has a few hard limits beyond the general Graph API call budget.**

- **10,000 posts.** The edge returns the most recent 10,000 posts and no older ones.
- **No Stories.** Stories aren't returned by `/media`. Use `GET /{ig-user-id}/stories` while they are live.
- **Live video.** Meta's reference says live video media is readable only while it's being broadcast.
- **Professional accounts only.** Meta's IG Media reference says data is returned only for professional accounts.
- **Call limits.** Every read counts toward the app's rate limit for that account. Our [Instagram API rate limit](https://www.tryadeli.com/blog/instagram-api-rate-limit) guide has the formula and the error codes.

Polling every account every few minutes is the fastest way to hit the rate limit. Use `since` to fetch only new posts, and use webhooks for comments rather than re-reading media to find them.

## How do you get Instagram posts for every customer with Adeli?

**Adeli's [List posts](https://www.tryadeli.com/docs/api/posts/list-posts) endpoint, `GET /api/v1/posts`, returns posts from every Instagram account connected to one of your user profiles, newest first.** Adeli holds the Meta developer app, carried Meta's review, and refreshes every connected account's tokens, so your code holds one API key:

```bash
curl -G "https://app.tryadeli.com/api/v1/posts" \
  -H "Authorization: Bearer $ADELI_API_KEY" \
  --data-urlencode "profileId=00000000-0000-4000-8000-000000000001" \
  --data-urlencode "platform=instagram"
```

What changes compared with calling Meta directly:

- **One shape for every network.** Each post comes back with `caption`, `media`, `permalink`, `engagement` (likes and comments), and `publishedAt`, the same shape as TikTok, YouTube, Facebook, and Bluesky posts.
- **No cursors to manage.** Adeli follows Instagram's pagination internally.
- **Your users' own accounts.** Each of your users connects their own Instagram account through Adeli's hosted connect flow.

If you're building analytics into a product, the [social media analytics API](https://www.tryadeli.com/social-media-analytics-api) page shows the rest of the read endpoints, and [Instagram on Adeli](https://www.tryadeli.com/product/instagram) covers publishing. Your first 2 user profiles are free on [pricing](https://www.tryadeli.com/pricing).

## Frequently asked questions

### Can the Instagram API get posts from any public account?

No. The Instagram Graph API reads posts from professional accounts that authorized your app. For other Business or Creator accounts, business discovery returns their public profile and media by username, using the Facebook Login version of the API. Personal accounts can't be read at all.

### How do I get the latest posts from an Instagram account?

Call the media edge without a cursor. Meta returns the most recently created posts first, so the first page is the latest posts. To get only posts from a time range, add the since and until parameters with Unix timestamps.

### Does the Instagram media endpoint return Stories?

No. Meta's reference says Story media isn't returned by the media edge and points to the stories edge on the same IG user instead. Stories expire after 24 hours, so read them while they are live.

### Why is media_url missing from some Instagram posts?

Meta omits media_url for videos that contain copyrighted or licensed audio, and for some Reels read from other accounts. Treat the field as optional and fall back to permalink or thumbnail_url.

## Related Adeli pages

- [Instagram API for Developers](https://www.tryadeli.com/product/instagram.md): Publish, schedule, and read analytics for Instagram through one API. Adeli owns the Instagram developer app, token refresh, and Meta review. Free to start.
- [Social Media Analytics API](https://www.tryadeli.com/social-media-analytics-api.md): Adeli's analytics API: Instagram, TikTok, Facebook Page, and YouTube insights endpoints, plus per-post engagement on every post an account has made.
- [Social Media and Ads API for AI Marketing Platforms](https://www.tryadeli.com/use-cases/ai-marketing-platforms.md): Run posting, analytics, inbox, and Meta ads for your customers' accounts through one API, without months of platform reviews.
- [All posts on the Adeli blog](https://www.tryadeli.com/blog.md)

## About the author

Mika Reyes is the CEO behind Adeli and a tech and AI content creator. She was previously co-founder and CEO of Parallax, which was acquired by Phantom, and a product lead at LinkedIn. She is a Forbes 30 Under 30 honoree.
