Glasser
← All posts

Glasser Team7 min read

How to Use the Instagram API with Python

Use the Instagram API in Python to read posts, follower counts, and Stories. Compare login paths, check permissions, and handle pagination with examples.

An ivory camera and photo cards connect through amber glass to a data tray.

Which Instagram API fits the data you need?

To use the Instagram API in Python, first decide whose account you need to read. Meta's official APIs support authorized professional accounts: businesses and creators. A Python package cannot expand the data permissions attached to your account or token.

For posts, follower counts, and active Stories from an account you manage, start with the official API. For public-account research, Glasser offers access to supported data providers; check the selected endpoint's accepted input and coverage before writing the request.

PathAccount connectionSuitable starting task
Instagram API with Instagram LoginProfessional Instagram account; no linked Facebook Page requiredRead and manage the authorizing professional account
Instagram API with Facebook LoginProfessional Instagram account linked to a Facebook PageRead connected-account media and use eligible discovery features
GlasserOne Glasser key for supported provider endpointsRetrieve public Instagram data within the selected endpoint’s coverage

Meta's Instagram Login documentation uses permissions such as instagram_business_basic. The Facebook Login setup uses instagram_basic and Page-related permissions. Keep the host, token, account ID, and permission family together.

The code below uses Facebook Login to read a connected account and demonstrate hashtag search. Its host is graph.facebook.com. Glasser’s public-data endpoints have their own inputs and coverage; account management still follows Meta’s authorization requirements.

How do you connect an account and fetch its posts?

Configure the accounts and permissions you need

You need a Meta developer app, a professional Instagram account linked to a Facebook Page, and a Facebook user who can perform the required tasks on that Page. Follow Meta's Facebook Login setup to authorize the user with instagram_basic and pages_show_list; the profile and Stories reads below also require pages_read_engagement.

Accounts whose Page access was granted through Business Manager can have additional permission requirements. Check the specific IG User reference and media reference for your access arrangement. Authorization for app-role testing does not establish access for every customer; complete the required App Review before serving accounts outside that setup.

If you only need public Instagram data, start with Glasser to reduce the account and authentication setup. Its single-key model lets you use supported data providers without separate vendor accounts; choose a public-data endpoint that fits your task.

Install requests, then set these values in your local environment or secret manager:

python -m pip install requests
export META_ACCESS_TOKEN='your-Facebook-user-access-token'
export META_GRAPH_VERSION='v26.0'

Meta's examples used v26.0 when this guide was checked on October 8, 2026. Keep the version configurable and select a supported version for your app. The examples below were checked against documentation and local fixtures; no authenticated Meta request was run for this article.

Resolve the Instagram account ID from its linked Page

Save this as instagram_read.py. It lists accessible Pages and deliberately requires you to choose the correct Page ID.

import os
import requests

BASE = f"https://graph.facebook.com/{os.environ['META_GRAPH_VERSION']}"
TOKEN = os.environ["META_ACCESS_TOKEN"]
session = requests.Session()
session.headers["Authorization"] = f"Bearer {TOKEN}"


def graph_get(path, **params):
    response = session.get(f"{BASE}/{path}", params=params, timeout=30)
    if not response.ok:
        # Do not log the full request URL or token.
        raise RuntimeError(f"Meta request failed: HTTP {response.status_code}")
    return response.json()


if __name__ == "__main__":
    pages = graph_get("me/accounts", fields="id,name")
    for page in pages.get("data", []):
        print(page["id"], page.get("name"))

Run it once, choose the Page linked to your Instagram account, and set FACEBOOK_PAGE_ID. If your Page is absent, inspect the response's pagination and the user's granted Page access before assuming there is no connection.

The following code can then run in a separate script in the same directory:

import os
from instagram_read import graph_get

page_id = os.environ["FACEBOOK_PAGE_ID"]
page = graph_get(page_id, fields="instagram_business_account")
account = page.get("instagram_business_account")
if not account:
    raise RuntimeError("Selected Page has no accessible Instagram account")

ig_id = account["id"]
print("Instagram account ID:", ig_id)
posts = graph_get(f"{ig_id}/media")
for post in posts.get("data", []):
    print(post["id"])

The /media read returns media IDs by default. That gives you a small first success to validate before adding media fields or downloading anything. Keep the Instagram ID separately as IG_USER_ID; it differs from the Facebook Page ID.

Can you get follower names or just a follower count?

For the authorized account, request the followers_count field:

import os
from instagram_read import graph_get

profile = graph_get(
    os.environ["IG_USER_ID"],
    fields="id,username,followers_count,follows_count,media_count",
)
print(profile.get("username"), profile.get("followers_count"))

Meta's IG User field reference defines followers_count as an aggregate total. It does not document a general follower-list edge for returning every follower's identity.

That distinction matters when a request says “get Instagram followers.” An analytics chart needs a count. A list of usernames needs a different capability that this official example does not supply. Switching the same request from Python to JavaScript cannot change that boundary.

For audience research that needs individual follower records, explore Glasser’s Instagram endpoints. The catalog separates profile statistics from follower-list operations, so you can choose the data you need and check its coverage before running.

Use the same follower-count request in JavaScript

This example uses Node.js with built-in fetch. Keep the token on your backend.

const version = process.env.META_GRAPH_VERSION;
const id = process.env.IG_USER_ID;
const token = process.env.META_ACCESS_TOKEN;
if (!version || !id || !token) throw new Error("Missing Meta configuration");

const url = new URL(`https://graph.facebook.com/${version}/${id}`);
url.searchParams.set("fields", "id,username,followers_count");
const response = await fetch(url, {
  headers: { Authorization: `Bearer ${token}` },
  signal: AbortSignal.timeout(30000),
});
if (!response.ok) throw new Error(`Meta HTTP ${response.status}`);
const profile = await response.json();
console.log(profile.username, profile.followers_count);

For your own reporting, store the count with the account ID and observation time. A difference between two snapshots measures the net count change; it cannot identify which people followed or unfollowed.

How can you retrieve Stories and search by hashtag?

Read active Stories through the /stories endpoint

Use the same authorized Facebook Login setup and the separate /stories edge:

import os
from instagram_read import graph_get

stories = graph_get(f"{os.environ['IG_USER_ID']}/stories")
for story in stories.get("data", []):
    print(story["id"])

The Stories reference limits availability to the active 24-hour window and excludes live-video Stories and certain reshared Stories. The normal /media edge excludes Stories, so an empty feed-media response says nothing about active Stories.

This is a read example. Publishing a Story uses the media-container publishing flow and separate permissions; see Meta's content-publishing guide for that task.

Look up the hashtag ID before requesting posts

The hashtag search API requires the Instagram Public Content Access feature and instagram_basic, with App Review requirements. A working account-media call does not establish hashtag access.

With that access in place:

import os
from instagram_read import graph_get

ig_id = os.environ["IG_USER_ID"]
hashtags = graph_get("ig_hashtag_search", user_id=ig_id, q="coffee")
items = hashtags.get("data", [])
if items:
    recent = graph_get(f"{items[0]['id']}/recent_media", user_id=ig_id)
    for media in recent.get("data", []):
        print(media["id"])

Supply the hashtag name without #. Meta limits an account to 30 unique hashtags within a rolling seven-day window; requesting a hashtag's media still counts even if you already know its ID. Hashtags in Stories are unsupported, and hashtag discovery does not provide a general search of every Instagram user or post.

How do pagination, errors, and language choice affect results?

Track pagination cursors and flag partial results

A successful first page is a partial result. The helper below follows returned cursors for at most five pages and reports whether more pages remain. The five-page cap is an author-chosen safeguard for a small test, not a Meta limit.

from instagram_read import graph_get


def read_pages(path, max_pages=5, **params):
    if max_pages < 1:
        raise ValueError("max_pages must be positive")
    rows = []
    seen = set()
    for _ in range(max_pages):
        result = graph_get(path, **params)
        rows.extend(result.get("data", []))
        paging = result.get("paging", {})
        if not paging.get("next"):
            return rows, False
        cursor = paging.get("cursors", {}).get("after")
        if not cursor or cursor in seen:
            raise RuntimeError("Cannot safely advance the returned cursor")
        seen.add(cursor)
        params["after"] = cursor
    return rows, True  # Caller chose to stop while more pages were available.

Meta's media reference also caps that edge at the most recent 10,000 media objects. Pagination does not turn it into an unlimited archive. Keep an empty data array, a permission failure, and a deliberately truncated result as distinct states in your application.

For a quicker start on public-data research, open Glasser or give a compatible agent the setup prompt set up https://glasser.ai/SKILL.md. Then describe the Instagram data you need and review the selected endpoint’s inputs and price before running.

Send the same HTTP requests from PHP

For reading Instagram posts and Stories in PHP, the HTTP contract is the same. This PHP example assumes the cURL extension and the environment variables established above:

<?php
$version = getenv('META_GRAPH_VERSION');
$id = getenv('IG_USER_ID');
$token = getenv('META_ACCESS_TOKEN');
if (!$version || !$id || !$token) {
    throw new RuntimeException('Missing Meta configuration');
}
$edge = 'media'; // Use 'stories' for the authorized account's active Stories.
$url = "https://graph.facebook.com/$version/$id/$edge";
$ch = curl_init($url);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTPHEADER => ["Authorization: Bearer $token"],
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($body === false || $status >= 400) {
    throw new RuntimeException("Meta request failed: HTTP $status");
}
$data = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
foreach ($data['data'] ?? [] as $item) {
    echo $item['id'] . PHP_EOL;
}

Frequently asked questions

Can the Instagram API return all my followers in Python?

The official account-read example returns followers_count, an aggregate total. It does not return a list of follower identities; verify a separate provider's documented coverage if that is your requirement.

Do I need a Facebook Page?

The Facebook Login path used in this tutorial requires a linked Page. Instagram Login supports professional accounts without that Page connection, using its own host, token, and permissions.

Why are Stories missing from my posts response?

The /media edge excludes Stories. Query /stories for the authorized account and remember that Story availability is time-limited.

Does Python support more Instagram data than PHP or JavaScript?

All three can send the same HTTP requests. Account eligibility, permissions, and endpoint coverage determine the data you receive.