GetInSaver Developers
Python code in a dark code editor
Guide · Python

Python Instagram and TikTok Downloader API

To download Instagram or TikTok media in Python, send the public link to POST https://developers.getinsaver.com/v1/resolve with the requests library. The API answers with direct video and image URLs, and you save them with a streamed GET. No Instagram login, cookies or headless browser runs on your side.

Python code that posts an Instagram link to the GetInSaver API with requests, and the JSON response with a video URL

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

Steps

  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.
  3. Install the one dependency: pip install requests.
  4. Save the script below as resolve.py and run python resolve.py.

Complete Python example

It resolves one Reel, retries on rate limits and temporary failures, and saves every returned file under downloads/. Change the service ID and link for TikTok, X, Pinterest, Stories or Highlights.

# 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}"))

What the API returns

{
  "ok": true,
  "service": "instagram",
  "source_url": "https://www.instagram.com/reel/SHORTCODE/",
  "item_count": 1,
  "items": [
    {
      "type": "video",
      "url": "https://cdn.example/media.mp4"
    }
  ],
  "metadata": {
    "title": null,
    "author": "creator",
    "caption": null
  },
  "request_id": "39a3bff5-0000-4000-8000-000000000000",
  "credits_used": 1
}

A carousel returns one item per slide, up to max_results (1 to 20). credits_used is what the call cost; 1 credit per Instagram post item, 2 per Story or Highlight item.

Service IDs for other platforms

serviceCoversCredits / resultLink format
instagramInstagram Posts & Reels1instagram.com/p/...
instagram-storyInstagram Stories2instagram.com/stories/username/...
instagram-highlightInstagram Highlights2instagram.com/stories/highlights/...
tiktokTikTok1tiktok.com/@user/video/...
xX / Twitter1x.com/user/status/...
pinterestPinterest1pinterest.com/pin/...
telegramTelegram Public Media2t.me/channel/123

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.

Coming from Instaloader?

Instaloader's own documentation marks --stories and --highlights as "Requires login", so your Instagram account is in the loop. With this API the function above is the whole integration and no account of yours is involved. See the Instaloader alternative page for a side-by-side comparison.

FAQ

Do I need an Instagram account or cookies?

No. The API reads publicly visible content. Your code sends a link and your API key, nothing else.

Does it work with asyncio or httpx?

Yes. It is a plain HTTPS POST with a JSON body; any HTTP client works. Keep a timeout of at least 130 seconds, because slow platforms can take up to two minutes.

Can I download a whole profile?

No. The API resolves one post, Reel, Story set, Highlight, TikTok, X post, Pin or Telegram post per request. It does not list profiles or return follower data.

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