How Much Can an Instagram Profile API Post Sample Tell You?
An Instagram profile API can give you a dated sample of recent public posts from one known account. Save the returned IDs, links and dates, then mark any missing dates or uncertain coverage. A first-page sample cannot establish the account’s full posting history or prove that every post in your campaign window was found.
I founded Serpent API, so this guide is affiliated. I reviewed its published profile fields and Meta’s official Instagram API documentation on October 5, 2026. The Python record is illustrative; I did not observe a live account or measure sample coverage.
Define the recent-post sample
Start with a known public handle and a clear audit question: which recent posts appeared, which formats were represented, and which entries need human review? Use the public profile endpoint with include_posts=true. Keep the username and observation time beside each post. A business report should say “recent posts returned” rather than “all posts in the period.”
The public contract returns recentPosts only when the post group is requested. Preserve shortcode as an item key and permalink as the link reviewers open. A thumbnail URL is a display aid, not durable identity. Check timestamp before applying a date-window rule; a post with no readable time belongs in an unknown-date bucket, not silently outside the window.
Fields to keep with each post
Meta’s official Instagram API with Facebook Login is designed around authorized professional account access and does not expose arbitrary consumer accounts through that path. Serpent’s profile read is a public-data task with a best-effort recent sample. If you administer the account and need authorized insights, official access is the better fit.
| Field or input | Use | Interpretation check |
|---|---|---|
| username, profileUrl | Confirm that the response names the account requested. | Do not merge similarly named profiles. |
| recentPosts[].shortcode, permalink | Keep a stable post key and review link. | A missing shortcode or link needs manual review. |
| recentPosts[].timestamp, mediaType | Date and classify the returned sample. | A null date is unknown, not old. |
| postsCount versus recentPosts length | Keep published profile count separate from sampled rows. | The sample is not complete history. |
Prepare a dated post review in Python
Set SERPENT_API_KEY and install requests. The example below includes request authentication, a bounded timeout, a parsed success check and explicit missing-data handling. Its syntax was checked locally; production values and access remain to be validated with an authorized account. Replace the illustrative handle, ID or tag with one you are permitted to review.
import os
from datetime import datetime, timezone
import requests
BASE = "https://apiserpent.com"
KEY = os.environ["SERPENT_API_KEY"]
def fetch(path, params):
response = requests.get(BASE + path, params=params,
headers={"X-API-Key": KEY}, timeout=60)
if response.status_code == 404:
# HTTP status alone cannot separate route access from resource absence.
return {"lookup": "unverified_404", "observed_at":
datetime.now(timezone.utc).isoformat()}
response.raise_for_status()
data = response.json()
if data.get("success") is not True:
raise ValueError("No usable response")
data["observed_at"] = datetime.now(timezone.utc).isoformat()
return data
handle = "example_account"
data = fetch("/api/social/instagram/profile",
{"username": handle, "include_posts": "true"})
if data.get("lookup") == "unverified_404":
print({"handle": handle, "status": "unverified API 404; check route access and request"})
else:
posts = data.get("recentPosts")
if not isinstance(posts, list):
raise ValueError("recentPosts was not a list")
if (data.get("username") or "").lower() != handle.lower():
raise ValueError("Profile identity did not match")
ledger = []
for post in posts:
if not isinstance(post, dict):
continue
ledger.append({"shortcode": post.get("shortcode"),
"permalink": post.get("permalink"),
"timestamp": post.get("timestamp"),
"media_type": post.get("mediaType")})
print({"handle": handle, "observed_at": data["observed_at"],
"profile_posts_count": data.get("postsCount"),
"recent_posts_returned": len(posts), "ledger": ledger,
"delivery": data.get("delivery")})
Interpret the printed record carefully. A recentPosts length of eight against a profile postsCount of hundreds means eight rows were returned for review; it does not tell you why the remaining posts are absent or prove they are unavailable. Save the raw response for a manual spot check. Shortcodes, timestamps and permalinks make later comparisons more reliable than image links.
Budget the account checks
At the documented Default Instagram rate, a basic profile or include_posts=true call is $0.40 per 1,000 calls. One account checked daily for 30 days is 30 × $0.0004 = $0.012 in metered usage. Rich include_post_details=true is $4.00 per 1,000 before optional field groups and should only be added if captions or engagement counts change the audit decision. Check the ledger for the delivered tier.
These are dated contract calculations, not a live invoice or a guarantee of result quality. See Serpent pricing for current tier terms, and inspect your account ledger after a small verified run. Do not divide a bill by returned items when the published unit is a request or requested depth.
When account access is the better option
| Option | Best use | Access or billing unit | Decision |
|---|---|---|---|
| Meta Instagram API with Facebook Login | Authorized professional-account content and insights. | App review, permissions and account authorization; terms in Meta’s official collection. | Choose it for an account you manage and permissioned metrics. |
| Serpent Instagram profile with posts | Best-effort recent public-post sample for a known handle. | $0.40/1K Default calls with include_posts=true. | Choose for a lightweight public review queue, not a full archive. |
| Manual Instagram profile review | View current public presentation and post context. | Human time. | Use to verify surprising gaps or media context. |
Where a recent sample can mislead
Private profiles, removed posts, changing public visibility and short delivery can limit the sample. Do not present the first page as a full history or compute a publishing rate from it. Like and comment counts from a grid-only post can be null; do not call null zero engagement. Signed image URLs can expire and should not be used as item IDs.
Make the post review reproducible
Define the audit window before fetching. For example, a review of campaign posts from Monday through Sunday needs an account identity, a timezone for the window and a rule for unknown post dates. The profile's postsCount is context, while recentPosts is the actual sample to inspect. If the oldest returned post is newer than the window start, you cannot know from this response whether earlier in-window posts were missed. Mark coverage unconfirmed rather than reporting a complete weekly count.
| Returned row | Review bucket | Next action |
|---|---|---|
| Shortcode, permalink and readable timestamp | Known post in or out of the chosen window | Open selected links and check format/context. |
| Shortcode and permalink, timestamp null | Known post, date unknown | Review the public post before a date-based conclusion. |
| Missing shortcode or permalink | Unresolved identity | Keep the raw row; do not deduplicate by thumbnail. |
| No recent rows | Empty returned sample | Check profile identity and accessibility; do not report zero posts. |
On the next run, join records by shortcode and preserve both observation times. Report “three returned posts newly observed since Tuesday” only after comparing the same account and request settings; that is not a claim that exactly three posts were published. If the decision needs captions or engagement, request the detail group for a small validation sample first and compare the additional charge with the decision it changes.
Check the sample before reporting
- Pick a known public handle and decide whether recent post IDs, dates or captions are needed before selecting optional detail groups.
- Confirm the profile identity in parsed output and record profile postsCount beside the number of recentPosts actually returned.
- Spot-check a few post permalinks and timestamps. Keep inaccessible or missing rows unknown rather than calling posts deleted.
- Check the account charge for the exact selected groups before scheduling another profile audit.
Save a dated post sample
Start with one known public account. Save the returned post IDs, dates and coverage limits before drawing a publishing conclusion.
Get an API keyFAQ
Does include_posts return every post?
No. It returns a best-effort recent sample, limited to public posts available in the current profile view.
Do I need include_post_details for shortcodes and links?
No. The recent-post group includes shortcode, permalink, media type and timestamp; rich details are a separate cost choice.
Can a private account be audited?
Only public profile information that is available may be returned. Do not promise private posts or complete private-account data.
Should postsCount equal recentPosts length?
No. postsCount is the profile’s stated total; recentPosts is the sample returned by this call.





