AI Mastodon header 1500x500 and 400x400 avatar under 2 MB

Mastodon downscales headers to 1500x500 and avatars to 400x400, 2 MB max. Make both with the Sume image API: a 3:1 header, a square avatar, a crop script.

5 min readSume
All posts

Mastodon's profile docs say avatars are downscaled to 400x400 and headers to 1500x500, with a maximum file size of 2 MB for each and WEBP, PNG, GIF or JPG accepted. A 1500x500 header is 3:1. On Sume, Ideogram V3 and Ideogram 4.5 list 3:1 directly ($0.075 each at the catalog's default), or you can ask Nano Banana 2 for 4:1 at $0.10 and crop the sides to 3:1 with Pillow.

What Mastodon says

Facts from the Mastodon documentation (read 2026-10-03).

Mastodon profile image rules (read 2026-10-03)
ImageFinal sizeMax fileFormats
AvatarDownscaled to 400x4002 MBWEBP, PNG, GIF, JPG
HeaderDownscaled to 1500x5002 MBWEBP, PNG, GIF, JPG

Two ways to a 3:1 header

Direct: send aspect_ratio: "3:1" to ideogram/ideogram-v3 or ideogram/ideogram-v4.5. Both list 3:1 in the catalog (read 2026-10-03). Ideogram 4.5 has a quality field (low, medium, high) priced at $0.0375, $0.075 and $0.275 per image on Sume, and its output format list is empty, so you cannot choose the file type.

Crop: ask Nano Banana 2 for 4:1 and trim the left and right edges. That works because 4:1 is wider than 3:1, so no part of the height is lost. The model also lists output_format of png, jpeg and webp, which helps with the 2 MB cap.

Header options on Sume (read 2026-10-03)
ModelRatioPrice per image
Ideogram 4.5, low3:1$0.0375
Ideogram V33:1$0.075
Ideogram 4.5, high3:1$0.275
Nano Banana 2 then crop4:1$0.10

Crop to 1500x500 and check the size

The script scales the 4:1 image to a height of 500, trims the center 1500 columns, and writes a WEBP at quality 85. It prints the file size so you can see the 2 MB cap is met.

import os, requests
from io import BytesIO
from PIL import Image

r = requests.post(
    "https://api.sume.com/v1/images",
    headers={"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"},
    json={"model": "google/nano-banana-2", "aspect_ratio": "4:1",
          "output_format": "webp", "resolution": "1K",
          "prompt": "wide watercolor of a harbor at dawn, calm sky, subject in the center, no text"},
    timeout=120)
if r.status_code != 200:
    raise SystemExit(f"{r.status_code}: poll {r.json()['data']['status_url']}")
im = Image.open(BytesIO(requests.get(r.json()["data"][0]["url"], timeout=60).content)).convert("RGB")
w, h = im.size
im = im.resize((round(w * 500 / h), 500))
left = (im.width - 1500) // 2
im.crop((left, 0, left + 1500, 500)).save("header.webp", quality=85)
print(os.path.getsize("header.webp") / 1e6, "MB")

The avatar

Make the avatar as its own 1:1 call, since a square crop of a header throws away the subject. A 1024-pixel square from any model downscales to 400x400 cleanly. On Sume a GPT Image 2.5 square at low quality is an estimated $0.0074, and Grok Imagine or Imagen 4 Fast are $0.025. Mastodon shows avatars small beside posts, so keep one bold shape.

What Sume does not do

Sume does not upload to your instance or check the 2 MB cap; the script above checks the header file size itself. Keep the original render if you want to re-crop later.

Sources

Related posts

More in Use cases

All Use cases posts

Written by Sume