Telegram Bot File Storage
Persistent File Storage for Telegram Bots
Store and serve files from your Telegram bot with global CDN.
The Telegram Bot API is great at moving messages and terrible at being a file store. getFile returns a file_path that's valid for roughly an hour, so the thing you'd actually put in a database — a stable download URL — doesn't exist. What you get is a file_id, which is a reference, not a link, and it's bound to your specific bot token: rotate the token or migrate to a new bot and every saved file_id becomes dead weight.
On top of that, getFile downloads are capped at 20 MB and uploads at 50 MB, so anything chunky simply can't round-trip through the Bot API.
The durable pattern is to treat Telegram as the inbox and files.link as the warehouse. When a user sends a document or photo, download it once via the bot, push the bytes through the files.link three-call upload, and persist the permanent CDN URL against the user or chat id. That URL outlives token rotations, bot migrations, and the file_path expiry window, and serves from edge locations worldwide when you reference it elsewhere.
A python-telegram-bot handler:
async def handle_file(update, context):
tg_file = await update.message.document.get_file()
data = bytes(await tg_file.download_as_bytearray())
name = update.message.document.file_name
# 1) POST /v1/files/{folderId} -> { urls: [{ url, id }] }
meta = api_post(f"/v1/files/{FOLDER}",
{"filesMetadata": [{"name": name}]})
url, fid = meta["urls"][0]["url"], meta["urls"][0]["id"]
requests.put(url, data=data) # 2) PUT bytes
api_post("/v1/files/confirm-upload", {"ids": [fid]}) # 3) confirm
save_for_user(update.effective_user.id, cdn_url_for(fid))
await update.message.reply_text("Saved permanently.")The Authorization header is your raw API key. To send a stored file back, you don't re-upload bytes — hand Telegram the CDN URL directly: await context.bot.send_photo(chat_id, photo=cdn_url) or send_document(chat_id, document=cdn_url), and Telegram fetches it from the edge itself. For files larger than the 50 MB Bot API cap, reply with a CDN link instead of pushing bytes; the user taps it and the browser downloads from the nearest edge. For private files, mint a fresh signed URL (10-minute expiry) immediately before the send.
Benefits With No Complexity
Global CDN delivery
Edge-cached worldwide
Signed-URL security
What You Get
Unlimited files
Unlimited storage
Public + Private storage
CDN ready links
Prepaid credits
More coming soon
How files.link Works
1. Upload
2. Copy
3. Use Anywhere
Why Developers Choose files.link
A Better Way to Store & Deliver Files
| Telegram Bot API Files | Firebase Storage | Backblaze B2 | files.link | |
|---|---|---|---|---|
| Durable URL (no ~1h file_path expiry) | ||||
| Handles files over the 50 MB Bot API cap | ||||
| Permanent CDN URLs | ||||
| Global CDN delivery built in | ||||
| Single REST API, no SDK / cloud project | ||||
| Send stored file back by passing the URL |
Calculate Your Needs
Storage
Egress
CDN Bandwidth
Start Telegram Bot Storage
- Global CDN delivery
- Edge-cached worldwide
- Signed-URL security
- Unlimited files
- Unlimited storage
- Public + Private storage
- No subscription — prepaid credits keep spend predictable