When a marketer manually checks dozens of public IG profiles, the main cost is not opening the pages—it is the lack of comparable history. One snapshot tells you the follower count today; two snapshots let you calculate the difference over a chosen interval. For simple profile monitoring, you can automate the request, save only the fields you need, and produce a change table.
Below is a minimal working Python example: it retrieves profile information by username through the IG Scraper API and writes a timestamped JSONL record. The result is a small history source that you can connect to cron, n8n, or your own storage. The official route and parameter details are provided in the IG API reference.
What question does a daily snapshot answer?
Suppose a team tracks public brand or partner accounts and wants to notice changes in follower count, post count, or verification status. Viewing a page shows current values, but does not by itself preserve the state from the previous week. So first decide which fields matter, then save them with the date of observation.

The /v1/user/by/username route accepts the required username parameter. The response includes, among other fields, follower_count, following_count, media_count, is_verified, is_private, and biography. This set works for a profile snapshot; it does not contain post history and does not, by itself, explain why metrics changed.
The script is deliberately narrow: retrieve an observable set of fields at a specified time and compare it with previous records. This lets an analyst see, for example, that the follower count changed between saved dates, then investigate further separately from the automated collection.
Prepare your key and account list
Install the requests library and set the API key in an environment variable. Do not put the secret in a source file, repository, or program output. The API uses the license_key query parameter; the library below constructs the query string automatically.
python -m pip install requests
export JSONSCRAPER_INSTAGRAM_LICENSE_KEY="your_key"
It is convenient to keep the profile list in a configuration file or project variable. For the first run, one username is enough to check the response, access, and storage. In the example, username is passed as an API parameter, while the key is read only from the environment.
Request and save a snapshot in Python
The script checks the HTTP response, the API-level status, and whether the ig object is present. It then saves only values that actually exist. If a field is missing, the record retains null: substituting zero would conflate an unknown value with a real zero.

import json
import os
from datetime import datetime, timezone
from pathlib import Path
import requests
API_URL = "https://ig.jsonscraper.com/v1/user/by/username"
LICENSE_KEY = os.environ["JSONSCRAPER_INSTAGRAM_LICENSE_KEY"]
USERNAME = "apple" # replace with a profile from your list
OUTPUT = Path("instagram-profile-snapshots.jsonl")
response = requests.get(
API_URL,
params={"username": USERNAME, "license_key": LICENSE_KEY},
timeout=30,
)
response.raise_for_status()
payload = response.json()
if payload.get("status") != "ok" or not isinstance(payload.get("ig"), dict):
raise RuntimeError("API returned an unexpected status or structure")
profile = payload["ig"]
record = {
"observed_at": datetime.now(timezone.utc).isoformat(),
"username": profile.get("username", USERNAME),
"pk": profile.get("pk"),
"follower_count": profile.get("follower_count"),
"following_count": profile.get("following_count"),
"media_count": profile.get("media_count"),
"is_verified": profile.get("is_verified"),
"is_private": profile.get("is_private"),
}
with OUTPUT.open("a", encoding="utf-8") as file:
file.write(json.dumps(record, ensure_ascii=False) + "\n")
print("Snapshot saved:", record["username"], record["observed_at"])
The example's fields and structure correspond to the profile information described for this route. A successful request returns an observation from the time of the call; to analyze trends, run the script repeatedly and save each snapshot. The IG Scraper API page shows a basic request and a sample JSON response.
Calculate the change between snapshots
JSONL stores one record per line, so you can read it with Python's standard library. The following snippet selects the two latest records for a profile and calculates the difference in follower count. It prints a result only when both records contain a numeric value.
import json
from pathlib import Path
rows = [
json.loads(line)
for line in Path("instagram-profile-snapshots.jsonl").read_text(encoding="utf-8").splitlines()
]
username = "apple"
profile_rows = [row for row in rows if row.get("username") == username]
profile_rows.sort(key=lambda row: row["observed_at"])
if len(profile_rows) >= 2:
previous, current = profile_rows[-2:]
old = previous.get("follower_count")
new = current.get("follower_count")
if isinstance(old, int) and isinstance(new, int):
print({
"username": username,
"from": previous["observed_at"],
"to": current["observed_at"],
"follower_delta": new - old,
})
The difference applies strictly to the two selected observations. If you miss runs, the interval between them will be longer, so the report should show both dates rather than automatically calling the change “daily.” For regular operation, schedule runs with cron or a cloud platform scheduler. In n8n, you can assemble the same sequence from scheduler, HTTP request, and result-writing nodes; node names and storage connections depend on your installation.
Expand to multiple profiles
For a list of accounts, put the usernames in a separate file and loop through them. Record the status of each request separately so a failure for one profile does not erase successfully retrieved data for the others. Add a timeout, an error log, and a retry limited to accounts whose requests failed.
You can use pk as the record key if the API returns it, while also retaining the username for readability. An identifier helps distinguish a profile from a text label in a report; if the value is missing, do not invent one or substitute another field. For analysis, it is useful to store the original collection time in UTC and explicitly set the comparison period.
If your task only requires retrieving information at a particular frequency, the documented cache_timeout parameter lets you specify a cache duration in seconds; caching is disabled by default for IG. Choose a duration that fits your monitoring interval and save it with the collection settings so you can account for request parameters when interpreting results.
What you get
After several runs, you will have a file of timestamped public-metric snapshots and a simple, calculable difference between selected dates. You can load it into Google Sheets, PostgreSQL, or an analytics system; a separate processing layer can generate an alert when a change exceeds a threshold set by your team. The threshold is your business rule, not a built-in API feature.
The profile route returns account fields, so auditing new posts requires the appropriate media collection—not conclusions drawn from media_count. The IG API reference lists a separate posts retrieval route with paginated loading by user_id and the end_cursor parameter; use it if your task requires examining the posts themselves. For the result described here—a historical table of profile metrics—one request per user and repeatedly saving snapshots are enough.
Start with one profile and a couple of runs: make sure the response status is correct, dates are saved, and missing data remains explicitly unknown. Then add an account list and a schedule. This gives you a reproducible observation with a clear interval and original values that can be checked and passed along to an analytics workflow.