My last two posts were about making single stickers that WhatsApp accepts. This one is the next step: turning a folder of images into a live Telegram sticker pack with its own t.me/addstickers/... link — no code for the publishing part, just one Python script to get the images into spec.
What Telegram actually checks
| Sticker type | Format | Size | Limits |
|---|---|---|---|
| Static | PNG or WebP | one side exactly 512 px | ≤ 512 KB |
| Animated | TGS (Lottie-based) | 512×512 | ≤ 64 KB, ≤ 3 s, 30 fps |
| Video | WEBM (VP9) | 512×512 | ≤ 256 KB, ≤ 3 s |
| Pack size | — | — | up to 120 stickers |
If you're just starting out, static PNG is the simplest path: no Lottie tooling, no timing rules — resize, pad, upload.
Step 1 — batch-prepare a whole folder with Pillow
from pathlib import Path
from PIL import Image
SRC = Path("my_images") # raw images, any size or format
OUT = Path("telegram_ready")
OUT.mkdir(exist_ok=True)
for i, f in enumerate(sorted(SRC.iterdir()), 1):
if f.suffix.lower() not in {".png", ".jpg", ".jpeg", ".webp"}:
continue
im = Image.open(f).convert("RGBA")
im.thumbnail((512, 512)) # keeps aspect ratio
canvas = Image.new("RGBA", (512, 512), (0, 0, 0, 0))
canvas.paste(im, ((512 - im.width) // 2, (512 - im.height) // 2), im)
canvas.save(OUT / f"{i:02d}.png")
Why PNG for the output: at 512 px there's rarely a size problem, so PNG sidesteps any quality tuning. If one of your stickers does blow past 512 KB (noisy, highly detailed art can), re-save just that file as WebP with quality=90 — Telegram accepts WebP the same way.
Step 2 — talk to @Stickers
Open t.me/Stickers in Telegram. This bot builds every public pack on the platform.
- Send
/newpack— it asks for a pack name (this is the display name users see). - Upload your images as files, not as photos. This is the single most common mistake: sending as a photo makes Telegram compress the image, which wrecks transparency and sharp edges. Use the paperclip → File, or drag the file onto the chat on desktop.
- After each upload the bot asks for one emoji. Pick the best match — that emoji is how your sticker gets suggested in the emoji panel later.
- When the last sticker is in, send
/publish. - Choose a short public link. You get a URL like
t.me/addstickers/my_pack_name— anyone who opens it can install the pack in two taps.
Useful later: /addsticker appends to an existing pack, /delpack deletes one, /cancel backs out of any wizard.
The failure modes I hit, so you don't have to
-
511×512 or 513×512 → rejected. "One side exactly 512" means exactly. My
thumbnail((512, 512))plus padding canvas handles this, but if you resize by hand, double-check. - Uploaded as photo → blurry sticker. Resend as file. There's no way to fix a compressed upload after the fact.
- GIF ≠ animated sticker. Animated packs need TGS (a Lottie JSON converted with the official tooling), not a renamed GIF. Start with static if you don't want to touch that toolchain.
Make it once, use it twice
The same square, transparent PNG that Telegram accepts is one quality-loop away from being a WhatsApp sticker — WhatsApp wants exactly 512×512 WebP under 100 KB instead of "one side 512". I covered that conversion, including the quality loop, in my previous post.
Or skip the pipeline entirely
If you'd rather see finished packs first: FunnieStickers is a free library of 192 stickers, shipped in WhatsApp and Telegram formats — no sign-up, click to download. The meme and reactions sets are the ones I'd install first.
Built a pack from this? Drop the link in the comments — I actually install them.
Top comments (0)