GetInSaver Developers
A hand holding a smartphone with a grid of photos open
Guide · Instaloader alternative

Instaloader Alternative API

If you use Instaloader to download Instagram Reels, posts or Stories and want to stop running a logged-in session, a hosted API replaces it with one HTTP call: send the public link, get the media URLs. Instaloader's documentation marks Stories and Highlights as "Requires login"; with this API no Instagram account of yours is involved.

Comparison: Instaloader needs a login for Stories and Highlights; the GetInSaver API needs no Instagram login and covers five platforms

Key facts

Endpoint
POST /v1/resolve (one endpoint for every service)
Free trial
20 result credits after email verification, no card
Price
from $19 for 7,500 results ($1.33–$2.53 per 1,000)
Billing
prepaid credits, no subscription, no expiry; failed or empty requests cost 0
Credits per result
1 (Instagram, TikTok, X, Pinterest) or 2 (Stories, Highlights, Telegram)
Limits
up to 20 items per request; 120 requests per minute per account; 2 in progress at once on the trial, 8 on paid accounts

Instaloader and this API side by side

InstaloaderGetInSaver API
What it isFree, open-source Python tool you run yourselfHosted REST API, any language
Instagram loginIts docs mark --stories and --highlights as "Requires login"Never; public content only
Stories and HighlightsWith a logged-in accountActive public Stories and public Highlights
Other platformsInstagram onlyInstagram, TikTok, X, Pinterest, Telegram
Profiles, followers, hashtagsYes (some need login)No: one link in, its media out
CostFree; your server, your account, your IP20 free credits, then prepaid from $19; failed requests cost 0

Keep Instaloader if you need whole-profile archives, follower lists or hashtag feeds. Use the API when your product gets single links from users and must not depend on an Instagram session.

Migrating: one function instead of a session

Where your code builds a post from a shortcode, send the link instead. This is the complete client; resolve() also covers Stories (instagram-story) and Highlights (instagram-highlight):

# pip install requests
import mimetypes, os, time
import requests

API_URL = "https://developers.getinsaver.com/v1/resolve"
API_KEY = os.environ["GIS_KEY"]  # keep the key on your server, never in a browser


def resolve(service, url, max_results=10, retries=3):
    """Turn a public link into media items: [{"type": "video", "url": ...}]."""
    for attempt in range(retries + 1):
        response = requests.post(
            API_URL,
            headers={"Authorization": f"Bearer {API_KEY}"},
            json={"service": service, "url": url, "max_results": max_results},
            timeout=130,
        )
        data = response.json()
        if response.ok:
            return data
        # 429 = rate or concurrency limit, 502/504 = platform hiccup; none of them is charged
        if response.status_code in (429, 502, 504) and attempt < retries:
            time.sleep(int(response.headers.get("Retry-After", 5)))
            continue
        raise RuntimeError(f"{data['code']}: {data['message']}")


def download(item, name, folder="downloads"):
    """Media URLs expire within minutes to hours, so save the file right away."""
    os.makedirs(folder, exist_ok=True)
    with requests.get(item["url"], stream=True, timeout=120) as media:
        media.raise_for_status()
        kind = media.headers.get("Content-Type", "").split(";")[0]
        path = os.path.join(folder, name + (mimetypes.guess_extension(kind) or ".bin"))
        with open(path, "wb") as f:
            for chunk in media.iter_content(chunk_size=65536):
                f.write(chunk)
    return path


if __name__ == "__main__":
    # TikTok works the same way: resolve("tiktok", "https://www.tiktok.com/@user/video/123...")
    result = resolve("instagram", "https://www.instagram.com/reel/SHORTCODE/")
    print(f"{result['item_count']} items, {result['credits_used']} credits")
    for i, item in enumerate(result["items"]):
        print(item["type"], download(item, f"{result['request_id']}-{i}"))

Getting a key

  1. Create a free account and verify your email. You get 20 free credits, no card needed.
  2. Create an API key in Dashboard → API keys and store it as the environment variable GIS_KEY on your server.

Errors to handle

HTTPCodeWhat to do
402INSUFFICIENT_CREDITSTop up, or lower max_results: a request reserves max_results × credits per result first.
422UPSTREAM_REJECTEDThe post is private, deleted, expired or login-only. Show the message to your user; nothing was charged.
429RATE_LIMITED / CONCURRENCY_LIMITWait for Retry-After seconds and retry. 120 requests per minute per account; 2 at once on the trial, 8 after buying credits.
502 / 504UPSTREAM_*Temporary platform failure. Safe to retry; nothing was charged.

Every error body is JSON with a stable code and a readable message. The full list is in the API reference.

FAQ

Can it download private accounts like a logged-in Instaloader?

No. It does not log in and does not bypass privacy. Private, deleted and login-only content returns an error and costs nothing.

Does it download Stories without a login?

Yes, active Stories of public accounts, and one exact Story when the link contains its ID. Expired Stories are gone; use Highlights for saved ones.

Is there a Python package to install?

Only requests. The example on this page is the whole client.

Do failed requests cost credits?

No. Credits are reserved while a request runs and refunded in full when it fails or finds no media. You only pay for items that come back.

Updated 2026-10-30. The code on this page is executed by our test suite against the API server before every release.

Make your first call in five minutes.

20 free credits when you verify your email. No card needed.

Create a free account