One Python API to download Instagram reels and posts, TikTok videos without watermark, YouTube
as MP4 (up to 4K) or MP3, plus Pinterest, Facebook, X/Twitter, RuTube and Likee. Includes a Shazam
song-recognition API and YouTube audio delivered as a Telegram file_id for music bots. Sync and
async. Free tier: 1,000 credits, no credit card.
from fastsaver import FastSaver
client = FastSaver("fs_sk_...") # or export FASTSAVER_API_KEY
video = client.fetch("https://www.tiktok.com/@scout2015/video/6718335390845095173")
print(video.download_url) # direct MP4 link, no watermarkStart free: 1,000 credits, no credit card; paid plans from $9/month for 100,000 credits. Create a key at api.fastsaver.io/auth (email, Google or Telegram login),
pip install fastsaver, and you are downloading in under a minute.
Sign up · API docs · Pricing · Telegram community · support@fastsaver.io
- Why FastSaverAPI · vs yt-dlp / instaloader
- Platforms, credit costs and plans
- Install · Get your API key · Quickstart · Async and bulk
- Instagram · TikTok (no watermark) · YouTube MP4 / MP3 · Telegram music bot · Pinterest, Facebook, X, RuTube, Likee · Shazam
- Balance · Errors · Retries, timeouts, proxies · CLI
- FAQ · Examples · Support
Scraping social networks yourself means proxies, cookies, IP bans, captchas and a parser that breaks every time Instagram or TikTok ships an update. FastSaverAPI is a hosted social media downloader API: you send a link, you get back direct download URLs and metadata in one stable JSON shape. No browser automation, no yt-dlp upgrades at 3 a.m., no servers to babysit.
- Free to start — 1,000 credits on sign-up, no credit card, 10 requests/minute.
- 8 platforms, one endpoint — Instagram, TikTok, Pinterest, Facebook, X/Twitter, RuTube,
Likee via
client.fetch(url), plus a full YouTube toolset. Every result has the same fields. - TikTok without watermark, Instagram reels/carousels/stories, YouTube up to 2160p (4K) and MP3/audio.
- Built for Telegram bots — turn a YouTube video into a Telegram
file_idin one call, backed by a cache of millions of tracks. Your bot never downloads or uploads a byte. - Shazam built in — recognise a song from a voice message, browse charts, fetch lyrics.
- Predictable billing — a fixed credit price per call; a failed resolve costs 0.1 credit; bad key, no credits or rate-limit rejections cost nothing.
- Fast — Instagram and TikTok fetches typically answer in under a second; popular posts come straight from cache.
- Sync and async clients with identical method names:
FastSaver/AsyncFastSaver. - Typed, frozen dataclasses for every response — the full JSON is always on
.raw. - Precise exceptions:
AuthenticationError,InsufficientCreditsError,RateLimitError,NotFoundError,FetchError, andInvalidArgumentErrorfor mistakes caught before a request. - Automatic retries with exponential backoff for network errors, 5xx and 429.
- Streaming
save()that writes any download link to disk without leaking your API key. - A
fastsavercommand-line tool for quick checks and shell scripts. - Zero heavy dependencies — just
httpx. Python 3.9+. Fully type-hinted (py.typed), checked withmypy --strict. - 800+ mocked test cases (
respx) run in CI on Python 3.9 through 3.14 —uv run pytestneeds no API key.
yt-dlp, instaloader and friends are great tools. They run on your machine, which is the
whole difference:
| Self-hosted scrapers (yt-dlp, instaloader, custom) | FastSaverAPI + fastsaver |
|
|---|---|---|
| Keeps working when platforms change | You update, redeploy, and hope | Handled server-side, same JSON |
| Proxies, cookies, IP bans, captchas | Your problem, your cost | Included |
| TikTok without watermark | Depends on the current extractor | Yes |
| YouTube 4K + MP3 conversion | Needs ffmpeg and CPU on your server | Done upstream, you get a link |
| Telegram delivery | Download → upload to Telegram (≤ 50 MB) | file_id in one call, no upload |
| Song recognition (Shazam) | Separate service | Built in |
| Time to first working call | Hours to days | Minutes — 1,000 free credits |
| Marginal cost per link | $0 (plus servers, proxies, your time) | From ~$0.14 per 1,000 links on Pro |
| Works offline / no third party | Yes | No — it is a hosted API |
| Cost model | Servers, proxies, maintenance time | From $0; Pro at $9 / 100,000 credits |
When yt-dlp is still the right tool: one-off personal downloads, archiving your own channel at zero marginal cost, or environments that must not call an external service. FastSaverAPI is for apps and bots that need to keep working every day without you maintaining scrapers.
| Platform | What you can download | Credits / request |
|---|---|---|
| Posts, reels, IGTV, carousels (albums) | 1.5 | |
| Stories and highlights | 5 | |
| TikTok | Videos without watermark, photo posts, the original sound | 1.5 |
| YouTube | Video info and available formats | 2 |
| YouTube | Music search (YouTube Music) | 2 |
| YouTube | Download MP4 144p–1080p, or audio/MP3 | 15 |
| YouTube | Download 1440p (2K) / 2160p (4K) | 25 |
| YouTube → Telegram | Audio as a Telegram file_id |
7 (cached) · 15 (first time) |
Pins, videos, idea pins (pinterest.com, pin.it) |
1.5 | |
Videos and reels (facebook.com, fb.com, fb.watch) |
1.5 | |
| X / Twitter | Videos, GIFs and images (x.com, twitter.com) |
1.5 |
| RuTube | Videos (rutube.ru, rutube.com) |
3 |
| Likee | Videos (likee.video, likee.com) |
3 |
| Shazam | Identify a song from audio | 5 |
| Shazam | Top charts by country | 1 |
| Shazam | Lyrics by title and artist | 2 |
| Account | Balance and plan | free |
Credits are consumed per successful call. Paid plans start at $9/month. Rate limits are per
API key in a fixed 60-second window, shared across /fetch, /youtube/* and /shazam/*.
| Plan | Price / month | Credits / month | Requests / min | What that buys |
|---|---|---|---|---|
| Free | $0 — no card | 1,000 | 10 | ~660 Instagram/TikTok fetches, or ~66 YouTube downloads, or ~140 cached Telegram tracks |
| Pro | $9 | 100,000 | 60 | ~66,000 fetches, or ~6,600 YouTube downloads, or ~14,000 cached Telegram tracks |
| Ultra | $39 | 500,000 | 250 | ~333,000 fetches, or ~33,000 YouTube downloads |
| Mega | $99 | 1,500,000 | 900 | ~1,000,000 fetches, or ~100,000 YouTube downloads |
On Pro that works out to roughly $0.14 per 1,000 Instagram/TikTok links, $1.35 per 1,000 YouTube MP4/MP3 downloads and $0.63 per 1,000 cached Telegram audio tracks (Ultra and Mega are cheaper per credit). A failed resolve (private, deleted, unsupported URL) costs 0.1 credit; rejected requests (bad key, no credits, rate limit) cost nothing. Pay by card or crypto. Current prices and plan details: https://api.fastsaver.io/pricing.
pip install fastsaveruv add fastsaverRequires Python 3.9 or newer. The only dependency is httpx.
- Sign up at api.fastsaver.io/auth — email code, Google or Telegram login. No card needed for the Free plan.
- Copy your key from the dashboard. It looks like
fs_sk_.... - Export it so
FastSaver(),AsyncFastSaver()and the CLI find it automatically:
export FASTSAVER_API_KEY="fs_sk_..." # macOS / Linux$env:FASTSAVER_API_KEY = "fs_sk_..." # Windows PowerShellOr pass it explicitly: FastSaver(api_key="fs_sk_..."). Without a key the client raises
ConfigurationError at construction time, before any request.
from fastsaver import FastSaver
with FastSaver() as client: # reads FASTSAVER_API_KEY
result = client.fetch("https://www.instagram.com/p/DRsmm9UjKfH/")
print(result.source) # instagram.com
print(result.type) # image | video | album
print(result.caption)
if result.is_album:
# Carousels have no top-level download_url — iterate the items
for item in result.items:
print(item.type, item.download_url, item.width, item.height)
else:
print(result.download_url, result.width, result.height, result.duration)
# Every download link, regardless of type
for url in result.download_urls:
print(url)
print(result.raw) # the JSON exactly as the API returned itSave a result to disk — save() streams the file, follows redirects and never sends your API
key to the file host. Keep it inside the same with block (a closed client raises
ConfigurationError):
from fastsaver import FastSaver
with FastSaver() as client:
result = client.fetch("https://www.instagram.com/p/DRsmm9UjKfH/")
if result.is_album:
# Carousels have no top-level download_url — save every item
for i, url in enumerate(result.download_urls, 1):
client.save(url, f"downloads/{result.id}_{i}")
elif result.download_url:
# Pick your own file name ...
path = client.save(result.download_url, f"downloads/{result.id}.mp4")
# ... or hand it a directory (created on demand) and let the response name the file
path = client.save(result.download_url, "downloads/")
print(path)The remaining sections assume one open client created for the whole program:
from fastsaver import FastSaver
client = FastSaver() # reads FASTSAVER_API_KEY; call client.close() at exitReady to run this? Get a free API key — 1,000 credits (about 660 Instagram/TikTok fetches), no card.
AsyncFastSaver has the same endpoint methods — just await them (close it with
await client.aclose() or async with). Reuse one instance per application; it is safe to use
from many coroutines at once.
import asyncio
from fastsaver import AsyncFastSaver, FastSaverError
URLS = [
"https://www.instagram.com/reel/DRsmm9UjKfH/",
"https://www.tiktok.com/@scout2015/video/6718335390845095173",
"https://pin.it/4nUh8Jx",
]
REQUESTS_PER_MINUTE = 10 # Free plan; Pro 60, Ultra 250, Mega 900 (see client.balance().rpm_limit)
async def main() -> None:
# Rate limits are counted per API key in a FIXED 60-second window and the API sends no
# Retry-After, so space requests out client-side instead of firing everything at once.
# A semaphore alone only limits concurrency, not requests per minute.
gap = 60 / REQUESTS_PER_MINUTE
lock = asyncio.Lock()
async with AsyncFastSaver() as client:
async def fetch(url: str):
async with lock: # one request every `gap` seconds
await asyncio.sleep(gap)
return await client.fetch(url)
results = await asyncio.gather(*(fetch(u) for u in URLS), return_exceptions=True)
for url, r in zip(URLS, results):
if isinstance(r, FastSaverError):
print("failed:", url, r)
else:
print(r.source, r.type, r.download_urls)
for link in r.download_urls:
await client.save(link, "downloads/")
asyncio.run(main())await client.save(url, dest) works the same way as the sync version (the network part is
async; disk writes are ordinary blocking writes). Downloads from the CDN do not count against
the API rate limit — only fetch, youtube.* and shazam.* calls do.
An Instagram reels downloader in Python is one call: client.fetch() handles reels, posts,
carousels, IGTV, stories and highlights. Every post form works: instagram.com/p/…, /reel/…,
/tv/…, /share/… links and /stories/<user>/<story_id>/.
reel = client.fetch("https://www.instagram.com/reel/DRsmm9UjKfH/")
print(reel.type, reel.download_url, reel.thumbnail_url, reel.duration)
post = client.fetch("https://www.instagram.com/p/C1abcDEfGhI/")
if post.is_album:
# carousel: one file per slide (items carry their own type/size)
for i, item in enumerate(post.items, 1):
if item.download_url:
ext = "mp4" if item.is_video else "jpg"
client.save(item.download_url, f"downloads/{post.id}_{i}.{ext}")
elif post.download_url:
client.save(post.download_url, "downloads/") # single image or video, named by the response
story = client.fetch("https://www.instagram.com/stories/nasa/3141592653589793238/") # 5 creditsNotes: a private or deleted post raises NotFoundError / FetchError (0.1 credit). Profile
URLs are rejected — pass a post, reel or story link.
A TikTok video downloader API without watermark: videos come back clean, no watermark, photo posts as albums, and every result carries the original sound:
tt = client.fetch("https://www.tiktok.com/@scout2015/video/6718335390845095173")
print(tt.download_url) # clean MP4, no watermark
print(tt.width, tt.height, tt.duration, tt.caption)
if tt.music:
print(tt.music.title, tt.music.author, tt.music.download_url) # MP3 of the soundShort vm.tiktok.com/… and vt.tiktok.com/… links are accepted too.
# Download a YouTube video in Python without yt-dlp or ffmpeg: metadata + available formats.
# Accepts watch, youtu.be, shorts, embed, live URLs or a bare id.
info = client.youtube.info("https://www.youtube.com/watch?v=HanBb8FonWs")
print(info.title, info.author, info.duration) # duration in seconds
print(info.available_formats) # ['audio', '144p', '360p', '720p', '1080p', ...]
print(info.best_video_format) # '1080p'
for f in info.formats:
print(f.type, f.format, f.filesize)
# YouTube Music search: 10 results per page, pages 1-3
search = client.youtube.search("the weeknd one of the girls", page=1)
for track in search:
# track.duration is a "m:ss" string; use track.duration_seconds for an int
print(track.video_id, track.title, track.duration, track.url)
# Download as MP4 ("144p" ... "2160p") ...
dl = client.youtube.download("https://youtu.be/HanBb8FonWs", format="720p") # 15 credits
print(dl.filename, dl.download_url)
# ... or as audio/MP3 ("audio" — "mp3"/"m4a" are aliases)
mp3 = client.youtube.download("https://youtu.be/HanBb8FonWs", format="audio") # 15 credits
# The link is valid for 10 minutes — save it right away
if dl.download_url:
path = client.save(dl.download_url, "downloads/") # file name comes from the response
print(path)download_urlneeds no API key and redirects to the actual file. It expires after 10 minutes (it can be reused until then); an expired link raisesDownloadErrorfromsave().- An invalid
formatraisesInvalidArgumentErrorbefore any credits are spent. - Conversion happens upstream, so a download can take a while — the SDK uses a 120 s read
timeout for this call. Override per call with
timeout=.
The killer feature for a Telegram music bot in Python. audio_for_bot returns a Telegram
file_id for the audio of a YouTube video, so your bot calls send_audio without downloading,
converting or uploading anything — no 50 MB upload limit, no bandwidth, no ffmpeg. Millions of
tracks are pre-cached: a cache hit costs 7 credits and returns in seconds; a miss is downloaded
first (15 credits, may take a minute or more — the default read timeout for this call is 300 s).
audio = client.youtube.audio_for_bot("vk6014HuxcE", "@my_music_bot")
print(audio.file_id)
# Prefer the channel/message pair? (for copy_message-style delivery)
ref = client.youtube.audio_for_bot("vk6014HuxcE", "@my_music_bot", return_file_id=False)
print(ref.channel_id, ref.message_id)A
file_idis bot-scoped: it only works for the bot you pass asbot_username(the leading@is added for you). Store thefile_id— re-sending it later is a plain Telegram call that costs no credits.
Minimal aiogram 3 handler (pip install "aiogram>=3"). BOT_USERNAME
must be the username of the bot whose token you pass to Bot(...) — a file_id only works
for that bot:
import os
from aiogram import Bot, Dispatcher, types
from aiogram.filters import Command
from fastsaver import AsyncFastSaver, FastSaverError
BOT_TOKEN = os.environ["BOT_TOKEN"] # from @BotFather
BOT_USERNAME = os.environ["BOT_USERNAME"] # "@my_music_bot" — the SAME bot as BOT_TOKEN
bot = Bot(BOT_TOKEN)
dp = Dispatcher()
saver = AsyncFastSaver() # reads FASTSAVER_API_KEY
@dp.message(Command("song"))
async def song(message: types.Message) -> None:
query = (message.text or "").partition(" ")[2].strip()
if not query:
await message.answer("Usage: /song <title or artist>")
return
try:
search = await saver.youtube.search(query) # 2 credits
track = next((t for t in search if t.video_id), None)
if track is None or track.video_id is None:
await message.answer("Nothing found.")
return
audio = await saver.youtube.audio_for_bot(track.video_id, BOT_USERNAME) # 7 / 15 credits
except FastSaverError as exc:
await message.answer(f"Could not fetch audio: {exc}")
return
if audio.file_id is None:
await message.answer("No file_id returned for this track.")
return
await message.answer_audio(audio.file_id, title=track.title) # no download, no upload
dp.run_polling(bot)A complete bot lives in
examples/telegram_bot_aiogram.py.
Building a Telegram music bot? The Free plan's 1,000 credits cover ~140 cached tracks — enough to ship a prototype today: api.fastsaver.io/auth. Pro ($9) covers ~14,000 cached tracks a month.
The same client.fetch(url) call is a Pinterest video downloader, Facebook reels downloader and
X/Twitter video downloader API, and returns the same MediaResult:
pin = client.fetch("https://pin.it/4nUh8Jx") # Pinterest (pin.it / pinterest.com)
fb = client.fetch("https://fb.watch/abc123/") # Facebook video / reel
x = client.fetch("https://x.com/NASA/status/1727080000000000000") # X / Twitter video, GIF, images
ru = client.fetch("https://rutube.ru/video/0123456789abcdef/") # RuTube (3 credits)
lk = client.fetch("https://l.likee.video/v/AbCdEf") # Likee share link (3 credits)
for r in (pin, fb, x, ru, lk):
print(r.platform, r.type, r.download_urls)Not sure which platform a link belongs to? detect_platform(url) mirrors the server's routing
and returns "youtube" for links you should send to client.youtube.*, None for
unsupported hosts, and "instagram_story" for story links:
from fastsaver import CREDIT_COSTS, detect_platform
platform = detect_platform("https://vm.tiktok.com/ZMabc/") # 'tiktok'
if platform is None:
print("unsupported URL (would cost 0.1 credit if sent)")
elif platform == "youtube":
print("use client.youtube.info / download / audio_for_bot")
else:
print(CREDIT_COSTS[platform]) # 1.5 — the /fetch platforms are keys of CREDIT_COSTS# Song recognition API in Python: identify a song from a clip (mp3/m4a/ogg/mp4, up to 50 MB;
# 5-15 s of clear audio is enough)
match = client.shazam.identify("clip.ogg")
print(match.title, "-", match.artist, match.thumbnail)
if match.best_match:
print("YouTube:", match.best_match.url) # ready for youtube.download / audio_for_bot
# Top charts: a country code ("us", "gb", "de", ...) or "world"; 10 tracks per page, pages 1-3
for track in client.shazam.top(country="world", page=1):
print(track.title, track.duration, track.url)
# Lyrics by title + artist (exactly as identify() returned them)
print(client.shazam.lyrics("Blinding Lights", "The Weeknd"))Recognise a Telegram voice message (in-memory buffers need a filename= so the recogniser
knows the container — Telegram voice notes are OGG/Opus). A complete aiogram 3 handler, using
the same bot, dp, saver and BOT_USERNAME as the music-bot example above:
from aiogram import F, types
from fastsaver import FastSaverError
@dp.message(F.voice)
async def recognise(message: types.Message) -> None:
assert message.voice is not None # guaranteed by the F.voice filter
buf = await bot.download(message.voice) # aiogram: BytesIO
if buf is None:
await message.answer("Could not download the voice note.")
return
try:
match = await saver.shazam.identify(buf, filename="voice.ogg") # 5 credits
except FastSaverError as exc:
await message.answer(f"Recognition failed: {exc}")
return
if not match.title:
await message.answer("No match.")
return
await message.answer(f"{match.title} — {match.artist}")
# Deliver the song itself: best YouTube match -> Telegram file_id
if match.best_match and match.best_match.video_id:
audio = await saver.youtube.audio_for_bot(match.best_match.video_id, BOT_USERNAME)
if audio.file_id:
await message.answer_audio(audio.file_id, title=match.title, performer=match.artist)file may be a path, bytes, an open binary file, or a (filename, data[, content_type])
tuple.
balance() is free and has its own limit of 60 requests per minute.
b = client.balance()
print(b.plan, b.credits, "/", b.plan_credits) # Free 987 / 1000
print(b.rpm_limit, b.balance, b.auto_renew) # 10 0.00 False (balance is a Decimal, USD)
print(b.plan_expires_at, b.expire_label) # 2026-10-09 12:00:00+00:00 Ends in 30 days
print(b.is_free_plan) # TrueA call either returns a model (ok: true) or raises a subclass of FastSaverError — you
never inspect HTTP status codes. Bad arguments (empty URL, unknown format, oversized file)
raise InvalidArgumentError before any request is made; it is both a FastSaverError and a
ValueError.
from fastsaver import (
FastSaver,
FastSaverError,
AuthenticationError,
InsufficientCreditsError,
RateLimitError,
NotFoundError,
FetchError,
)
client = FastSaver()
try:
result = client.fetch("https://www.instagram.com/p/DRsmm9UjKfH/")
except AuthenticationError:
print("Invalid API key — check FASTSAVER_API_KEY")
except InsufficientCreditsError:
print("Out of credits — top up at https://api.fastsaver.io/dashboard")
except RateLimitError:
# Fixed 60-second window per key and no Retry-After header: wait for the window to roll over
print("Rate limited — wait up to 60 s (Free: 10 requests/min), then retry")
except NotFoundError:
print("Post not found (private, deleted or wrong URL)")
except FetchError as exc:
print("Resolve failed:", exc.code) # fetch.failed, fetch.timeout, "fetch.error: 502", ...
except FastSaverError as exc:
print("Something else went wrong:", exc) # bad argument, network, timeout, 5xx, validation
else:
print(result.download_urls)FastSaverError
├── ConfigurationError missing API key, closed client
├── InvalidArgumentError bad argument, caught client-side (also a ValueError)
├── APIError any non-2xx (.status_code, .detail, .body)
│ ├── AuthenticationError 401
│ ├── InsufficientCreditsError 400 "Insufficient credits" — there is no HTTP 402
│ ├── RateLimitError 429 (.retry_after when the server sends Retry-After)
│ ├── InvalidRequestError 400 bad URL / format / bot username / file too large
│ │ └── ValidationError 422 (.errors)
│ ├── FetchError 400 resolve failed (.code, .upstream_status)
│ │ └── NotFoundError code "not.found"
│ └── ServerError 5xx
├── TransportError connection problems (wraps httpx errors)
│ └── RequestTimeoutError
└── DownloadError save(): final response was not 2xx (e.g. expired link)
Billing notes:
- Requests rejected by a guard — bad key, no credits, rate limit, bad format, bad bot username, oversized file — cost nothing.
- A resolve that reaches the platform and fails (
FetchError,NotFoundError, and an unsupported host onfetch()) costs 0.1 credit. - Running out of credits is reported as HTTP 400 with
InsufficientCreditsError, not 402.
import httpx
from fastsaver import FastSaver
client = FastSaver(
max_retries=3, # default 2
timeout=httpx.Timeout(30.0, connect=5.0), # default Timeout(60.0, connect=10.0)
)
# Per-call override for slow operations
dl = client.youtube.download("https://youtu.be/HanBb8FonWs", format="2160p", timeout=300)- Retried automatically with exponential backoff and jitter: connection errors, HTTP 5xx and
HTTP 429 (429 backs off 2 s, 4 s; a
Retry-Afterheader is honoured, capped at 30 s). - Not retried: read timeouts — the server may already have done (and billed) the work. You
get a
RequestTimeoutErrorimmediately and decide yourself. - Default read timeouts: 60 s for most calls, 120 s for
youtube.download, 300 s foryoutube.audio_for_botandsave(). The per-calltimeout=always wins. - Rate limits are a fixed 60-second window per key and the API sends no
Retry-After, so for bulk jobs space requests out client-side (see the async example) rather than relying on retries.
Bring your own httpx client for proxies, custom transports or HTTP/2. The SDK does not close
it, always applies its own timeouts, and never follows redirects on API calls (so your key is
never replayed to another host).
import httpx
from fastsaver import FastSaver, AsyncFastSaver
http = httpx.Client(proxy="http://user:pass@proxy.example:8080")
client = FastSaver(http_client=http)
ahttp = httpx.AsyncClient(http2=True) # needs: pip install "httpx[http2]"
aclient = AsyncFastSaver(http_client=ahttp)FastSaver is thread-safe — create one instance and share it. AsyncFastSaver belongs to the
event loop it was created in.
The package installs a fastsaver command (also python -m fastsaver). Output is the raw API
response as indented JSON; pass --compact for single-line JSON in pipelines.
export FASTSAVER_API_KEY="fs_sk_..."
fastsaver fetch "https://www.instagram.com/reel/DRsmm9UjKfH/"
fastsaver youtube info "https://youtu.be/HanBb8FonWs"
fastsaver youtube search "the weeknd" --page 2
fastsaver youtube download "https://youtu.be/HanBb8FonWs" --format 1080p --out ./downloads/
fastsaver youtube tg-audio vk6014HuxcE --bot @my_music_bot [--no-file-id]
fastsaver shazam identify clip.ogg
fastsaver shazam top --country us --page 1
fastsaver shazam lyrics "Blinding Lights" "The Weeknd"
fastsaver balance
fastsaver save "https://api.fastsaver.io/v1/tunnel?id=..." ./downloads/Global options: --api-key, --base-url, --timeout, --compact, --version. Errors go to
stderr with exit code 1 (2 for usage errors), so the CLI is safe in scripts:
fastsaver --compact fetch "$URL" | jq -r '.download_url // .items[].download_url'Constants for your own accounting:
from fastsaver import CREDIT_COSTS, YOUTUBE_FORMATS, detect_platform, extract_youtube_id
CREDIT_COSTS["youtube_download"] # 15
YOUTUBE_FORMATS # ('audio', '144p', ..., '2160p')
detect_platform("https://vm.tiktok.com/ZMabc/") # 'tiktok'
extract_youtube_id("https://youtu.be/HanBb8FonWs") # 'HanBb8FonWs'How do I download an Instagram reel or post with Python?
client.fetch("https://www.instagram.com/reel/…") returns download_url (video/image) or
items for carousels; client.save(url, "downloads/") writes it to disk. Stories and
highlights use the same call.
How do I download TikTok videos without a watermark in Python?
client.fetch(tiktok_url).download_url is the clean MP4. Photo posts come back as an album,
and result.music.download_url is the original sound.
How do I get a YouTube video as MP4 or MP3 without yt-dlp?
client.youtube.download(url, format="1080p") (or format="audio" for MP3/M4A) returns a
link valid for 10 minutes; save it with client.save(). Formats go up to 2160p (4K).
How do I send YouTube music in a Telegram bot without downloading it?
client.youtube.audio_for_bot(video_id, "@your_bot") returns a Telegram file_id; pass it
to send_audio / answer_audio. 7 credits when cached, 15 the first time anyone asks.
How do I recognise a song from a Telegram voice message?
await saver.shazam.identify(buf, filename="voice.ogg") — 5 credits — returns title, artist,
cover art, lyrics and matching YouTube tracks you can deliver with audio_for_bot.
Is it really free? Yes: every account gets 1,000 credits without a card (about 660 TikTok/Instagram fetches, 66 YouTube downloads, or ~140 cached Telegram audio tracks) at 10 requests/minute. Paid plans start at $9/month for 100,000 credits.
Do I need Instagram cookies, a login, or proxies? No. You send a public post URL and an API key; sessions, proxies and captchas are handled on FastSaverAPI's side. Nothing runs in a browser on your machine.
Can it download from private Instagram accounts or a whole profile?
No. Only public posts, reels, stories and highlights are supported, one URL per call; profile
URLs are rejected. A private or deleted post raises NotFoundError / FetchError (0.1 credit).
Can I use it in a commercial app or a public Telegram bot? The SDK is MIT-licensed. Use of the API itself is governed by the FastSaverAPI terms at https://api.fastsaver.io; paid plans (Pro/Ultra/Mega) are designed for production bots and apps, with rate limits from 60 to 900 requests per minute.
I don't use Python — is there a REST API for Node.js, PHP or Go?
Yes. This package is a thin client over the plain HTTPS/JSON API documented at
https://api.fastsaver.io/docs; every call here maps to one endpoint (GET /v1/fetch,
POST /v1/youtube/download, POST /v1/youtube/audio/tg-bot, POST /v1/shazam/identify, …)
with an X-Api-Key header.
Which URLs are supported?
Instagram (instagram.com), TikTok (tiktok.com, vm.tiktok.com), YouTube (youtube.com,
youtu.be, shorts, music), Pinterest (pinterest.com, pin.it), Facebook (facebook.com,
fb.com, fb.watch), X/Twitter (x.com, twitter.com), RuTube (rutube.ru, rutube.com),
Likee (likee.video, likee.com). detect_platform(url) tells you before you spend a credit.
Does the SDK work with asyncio, FastAPI, aiogram, python-telegram-bot?
Yes — AsyncFastSaver is a normal httpx-based async client. Create one instance at startup
and reuse it.
Is my API key safe?
The key is sent only to api.fastsaver.io over HTTPS. save() downloads from CDNs without
the key, API calls never follow redirects, and the key is masked in repr() and never logged.
What happens when a post is private or deleted?
You get NotFoundError or FetchError (with .code) and 0.1 credit is charged for the
attempt. Retrying will not help; guard rejections (bad key, rate limit, no credits) are free.
All examples read FASTSAVER_API_KEY from the environment and live in
examples/:
quickstart.py— fetch any supported URL and print its download links.async_batch.py— download many URLs concurrently, paced to your plan's rate limit, with per-URL error reporting.youtube_download.py— pick a format fromyoutube.info, download, save to disk.telegram_bot_aiogram.py— a complete music bot: search →file_id→answer_audio.shazam_identify.py— identify a local clip, print the best YouTube match and lyrics.
- Telegram community & support: https://t.me/fastsaverapi
- Email: support@fastsaver.io
- API documentation: https://api.fastsaver.io/docs
- SDK bugs and feature requests: GitHub issues
Not signed up yet? Create a free key — 1,000 credits, no card, and pricing from $9/month when you outgrow it.
If this SDK saves you an afternoon, a ⭐ on GitHub helps other developers find it.
Pull requests are welcome — see
CONTRIBUTING.md.
Tests are fully mocked with respx (800+ test cases, Python 3.9–3.14 in CI), so
uv sync && uv run pytest needs no API key. Security issues: see
SECURITY.md.
The SDK is released under the MIT License. Use of the FastSaverAPI service is subject to its own terms at https://api.fastsaver.io.
Русский — Python SDK для FastSaverAPI
Скачивание видео и фото из Instagram, TikTok (без водяного знака), YouTube (MP4 до 4K и MP3),
Pinterest, Facebook, X/Twitter, RuTube и Likee через один API, распознавание музыки (Shazam) и
аудио из YouTube как Telegram file_id для ботов. Sync и async клиенты.
1 000 кредитов бесплатно, без карты: https://api.fastsaver.io/auth. Поддержка в Telegram:
https://t.me/fastsaverapi.
O'zbekcha — FastSaverAPI uchun Python SDK
Instagram, TikTok (suv belgisiz), YouTube (4K gacha MP4 va MP3), Pinterest, Facebook, X/Twitter,
RuTube va Likee'dan video/rasm yuklab olish, Shazam orqali musiqani aniqlash va Telegram botlar
uchun YouTube audioni file_id ko'rinishida olish — bitta API. Sync va async.
1 000 kredit bepul, karta shart emas: https://api.fastsaver.io/auth. Telegram:
https://t.me/fastsaverapi.