Sume Image API 400 unsupported_parameter: which field fails where

Which Sume image models list quality, resolution, mask_url, background, output_format and references, and which never do (seed, stream). Plus a check script.

6 min readSume
All posts

The Sume Image API returns 400 unsupported_parameter when a request sets a parameter the selected model does not list, and it never drops the field silently. No model lists seed, output_compression or streaming today, so those always fail. mask_url and background are listed by ChatGPT Image 2.5 (Flare and Sunburst) only. quality, resolution and output_format are listed by a handful of rows each, and the table below says which.

This is from the catalog on origin/main and the Sume docs, read 2026-10-08. The endpoints route is the source of truth, so the pre-flight script below checks it before you send.

Who lists what

Every row lists prompt, aspect_ratio and n. The rest varies.

Optional Image API fields by model on Sume (read 2026-10-08)
FieldRows that list it
seed, output_compression, streamingNone
mask_url, backgroundChatGPT Image 2.5 (Flare) and ChatGPT Image 2.5 Sunburst only
qualityChatGPT Image 2 (3 values), ChatGPT Image 2.5 and Sunburst (6 values), Ideogram V3 and 4.5 (low, medium, high)
resolutionNano Banana 2.1 and Pro (512 to 4K), Imagen 4 Ultra and Ideogram 4.5 (1K, 2K), Soul (720p, 1080p)
output_formatNot listed on Soul or Ideogram 4.5; webp only on Recraft V4; png, jpeg, webp elsewhere
input_references above 0Not on Soul, Qwen Image Max, Imagen 4 Fast, Imagen 4 Ultra, Recraft V4
n above 1Every row except Grok Image

A pre-flight check

This function reads the endpoint record and returns the keys in your body that the row will reject. It treats an input_references descriptor with a maximum of 0 as unsupported, since the docs say such a model rejects references. It checks names, not values; a value outside an enum is the other thing to compare against the descriptor.

import os, requests

SKIP = {"model", "prompt", "mode", "webhook_url", "provider"}


def unsupported(model_id, body):
    url = f"https://api.sume.com/v1/images/models/{model_id}/endpoints"
    headers = {"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"}
    ep = requests.get(url, headers=headers, timeout=30).json()["endpoints"][0]
    listed = ep["supported_parameters"]
    bad = []
    for key in body:
        if key in SKIP:
            continue
        if key not in listed:
            bad.append(key)
        elif key == "input_references" and listed[key].get("max", 0) == 0:
            bad.append(key)
    return bad


if __name__ == "__main__":
    body = {"model": "google/imagen-4-fast", "prompt": "a tin", "quality": "high"}
    print(unsupported(body["model"], body))

Building request bodies

Keep one body builder per model id and let it add optional fields only when the endpoint record lists them. A shared body with quality: "high" works on Ideogram and ChatGPT Image rows and fails on Flux and Seedream rows. Failed requests are not billed, but they still use a round trip, so the check is cheaper than discovering the rejection at send time.

Capability descriptors have three types: an enum is a list of allowed strings, a range is any integer between a minimum and a maximum, and a boolean means the field is accepted when present.

Log the full error body on every 400. It names the parameter that failed, which is quicker to act on than the status code alone. If you see it on a model you did not change, the catalog row may have changed, so fetch the endpoint record again and update your builder from it.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume