GPT Image 2.5 mask checklist: same size, alpha, under 50MB
Check your mask before a paid GPT Image 2.5 edit: same size and format as the image, an alpha channel, under 50MB. A short Python preflight for Sume mask_url.

Before you send a mask_url edit, confirm three things about the mask file: it has the same dimensions and format as the image, it has an alpha channel, and both files are under 50MB. The script below checks all of it for free, before Sume starts a paid generation.
These are OpenAI's published rules in its image generation guide: "The image to edit and mask must be of the same format and size (less than 50MB)," and masks require an alpha channel. Sume's Image API exposes mask_url for ChatGPT Image 2.5 edits, so a mask that breaks the rules is a wasted call.
Which rules apply, and where do they come from?
Only the OpenAI page was read for the numbers. Sume's docs add that the mask URL must be public HTTPS, and that localhost, private-network, non-HTTPS and non-image responses are rejected before generation starts.
| Rule | Source | Checked by the script |
|---|---|---|
| Same size as the image | OpenAI guide | Yes |
| Same format as the image | OpenAI guide | Yes |
| Alpha channel present | OpenAI guide | Yes |
| Each file under 50MB | OpenAI guide | Yes |
| Public HTTPS URL | Sume Image API docs | Yes (scheme only) |
Why check locally?
A failed Sume image generation is not billed, but a mask that passes validation and still looks wrong is billed in full, and that is the expensive case. A local check catches mismatched sizes, which are the usual mistake after someone exports a mask from a resized copy of the photo.
The docs also say that an unfetchable input is rejected with an image_not_fetchable style error, so confirm the URLs open in a browser without logging in.
Sume also publishes the sizes GPT Image 2.5 accepts for outputs: both edges multiples of 16, maximum edge 3840, aspect ratio at most 3:1, and 655,360 to 8,294,400 pixels. Those are output rules, separate from the mask rules here, but an edit uses the reference's shape when aspect_ratio is auto, so a reference outside those bounds is worth catching in the same script. The earlier size validator post has that code.
The preflight script
It downloads both files, reads the first with Pillow, and prints every problem it finds. Install requests and pillow.
import sys, requests
from io import BytesIO
from PIL import Image
def load(url):
if not url.startswith("https://"):
raise ValueError(f"not https: {url}")
data = requests.get(url, timeout=30).content
return len(data), Image.open(BytesIO(data))
def check(image_url, mask_url):
(n1, img), (n2, mask) = load(image_url), load(mask_url)
errs = []
if img.size != mask.size: errs.append(f"size {img.size} vs {mask.size}")
if img.format != mask.format: errs.append(f"format {img.format} vs {mask.format}")
if "A" not in mask.getbands(): errs.append(f"no alpha: {mask.mode}")
if max(n1, n2) >= 50 * 1024 * 1024: errs.append("file over 50MB")
return errs
if __name__ == "__main__":
problems = check(sys.argv[1], sys.argv[2])
print("\n".join(problems) or "mask looks valid")
sys.exit(1 if problems else 0)What does a valid mask still not guarantee?
It guarantees the request is well formed, not that the model respects the edges. See the earlier post on edits that leaked outside the mask, and keep the preserve instruction in the prompt. Treat the mask as a strong hint.
If you edit with several references, work out which image the mask belongs to before you send, as covered in the multi-reference mask post linked below.
A last practical point: serve the mask from storage that returns the raw file with an image content type. A page that wraps the picture in HTML, or a link that redirects to a login, fails the fetch rules even though it opens fine in a browser tab. Test with curl -I and look for a content-type that starts with image/.
Sources
Related posts
More in Developers
- GPT Image 2.5 edit with several references: number each image
With up to 16 references in a GPT Image 2.5 edit, name each one by number and role in the prompt. A Sume request with three references, and what to check.
- Graph API v26.0: does it change Reels publishing? Not by its notes
Graph API v26.0 shipped July 29, 2026. Its changelog lists no Reels or video changes, but removes Explore placement and five Page fields. Dates inside.
- Grok Imagine takes JPG or PNG up to 20 MiB: convert iPhone HEIC
xAI lists jpg, jpeg and png inputs up to 20 MiB for Grok Imagine. iPhone HEIC photos need converting first; here is a short script before an edit on Sume.
- Grok Imagine extension: duration is added seconds; Sume's chain
xAI's /v1/videos/extensions duration counts only the new seconds, so 10s plus 5 returns 15s. Sume has no extend call here: chain clips from the last frame.
Written by Sume