Why your Instagram scraper works on your laptop and dies on the server
The most common message in our support inbox is a variation of “it worked yesterday on my machine”. It did, and it will again — on that machine. Instagram, TikTok and the sites that front them treat a Hetzner or AWS address differently from a home connection, and a scraper that passed every local test meets that difference in production. This guide is what the difference is, measured, and how to build around it rather than against it.
Updated
The address is the fingerprint
Platforms score a request before reading it: a datacenter ASN, a TLS handshake that does not match the claimed browser, and a session that does not exist all lower the score, and the page you get is the login wall or a captcha. Your laptop passes on all three without trying. The server fails the first one before your code runs.
What we measured
Instagram's own endpoints from a Hetzner IP: 0 of 11 posts. yt-dlp: 0 of 13. The download sites that serve as intermediaries went the same way one at a time — one family of them put a Turnstile captcha in front of datacenter addresses and dropped from 11 of 11 in July to 0 of 8 in September 2026. Every one of those links resolved from a home connection the same day.
Why a proxy is a treadmill, not a fix
A residential proxy restores the score for a while and then the pool gets flagged, because everyone else is renting the same addresses. TLS fingerprinting needs a client that impersonates a browser handshake — plain requests or httpx is refused with a 422 before the body is read. Each fix is another moving part to watch, and the platform changes faster than you patch.
What a resolver that lives with it looks like
Ours runs several independent sources in a chain, measures each one from the server address it actually runs on, re-orders them when a source degrades and drops the ones that stop working. You call one endpoint and the chain is our problem. The call from your side is the same one for every platform.
Terminalcurl -s "https://api.saveapi.org/v1/instagram" \ -H "Authorization: Bearer sk_live_xxxx" \ -G --data-urlencode "url=https://www.instagram.com/reel/ABC123/"
Handle the two failures that remain
No chain makes a deleted post exist. The response distinguishes: a link the source refuses comes back with a final code and costs 0.1 credits; a timeout or an upstream error costs nothing and is worth exactly one retry. Keep the retryable codes in one place and never retry a final answer.
PythonRETRY = {"UPSTREAM_TIMEOUT", "UPSTREAM_ERROR"}
async def resolve(link: str) -> dict:
for attempt in (1, 2):
r = await client.get(API, params={"url": link}, headers=HEADERS)
data = r.json()
if data["success"] or data["error"]["code"] not in RETRY:
return data
return dataQuestions before you build
- Will a VPN on the server help?
- Consumer VPN exits are datacenter addresses too, and shared ones are flagged faster than yours. The measurement that matters is the one from the address you deploy on.
- Does the API run on datacenter IPs?
- Yes — the same kind you deploy on. The difference is that the sources it uses are chosen and measured for that address, and replaced when they stop working, which is the work you would otherwise be doing.
- Which platforms are affected?
- Instagram is the extreme case, and TikTok's own endpoints behave the same way; sites that publish open JSON, like Pinterest, are largely indifferent. The front page shows the measured success rate across all of them.
Platform references used here
Other guides
Run this guide with your own key
Key in under a minute. 1,000 free credits, no card, no expiry.