Image edit returns 415 on Sume: send JSON, not multipart
A 415 unsupported_media_type from Sume's image API means the body was not application/json. Send reference images as public HTTPS URLs inside a JSON body.

If an image edit call to Sume comes back as 415 unsupported_media_type, the body was not sent as application/json. Sume's image API takes one JSON object, and the error body says so: it carries details.received_content_type (what you sent) and details.supported (["application/json"]). Switch the request to a JSON body and put each reference image in it as a public HTTPS URL, not as an uploaded file part.
This usually shows up when edit code written around file uploads (curl -F image=@photo.png, or a files= argument in a Python client) is pointed at Sume. Sume's error says it wants JSON, so the fix is to change the shape of the request rather than the form fields. The 415 itself is listed in Sume's errors page, and the edit fields are on the Image API page.
What does the 415 response look like?
The envelope is the standard Sume error: error.code, error.message, a request_id, and details. For a wrong content type the code is unsupported_media_type, the message is "Send the request body as application/json.", and details echoes the type you sent. Keep the request_id if you ever need to ask Sume support about a call.
| Status | Code | What it means for an edit |
|---|---|---|
415 | unsupported_media_type | Body was not application/json; send JSON. |
400 | invalid_request | A JSON field is wrong, for example a reference entry without image_url.url. |
400 | unsupported_parameter | The selected model does not list that field in its catalog descriptors. |
413 | payload_too_large | Body exceeds the API limit; references are URLs, so this should not happen with a normal edit. |
202 | (job envelope) | The generation outlived the 30-second wait; poll the job. |
How do I send a reference image instead of a file?
Host the photo at a public HTTPS URL and name it in input_references. Sume's image page is explicit that reference URLs must be public HTTPS: localhost, private-network, and non-HTTPS URLs are rejected before submission. A model whose input_references descriptor is {"min": 0, "max": 0} is text-to-image only and rejects references, so check the catalog if an edit is refused.
For ChatGPT Image 2.5 (openai/gpt-image-2.5) the same JSON can also carry up to 16 references and an optional mask_url, itself a public HTTPS URL. Use aspect_ratio: "auto" on an edit when the result should match the source shape, because the page says omitting the field is not the same as auto.
import os
import requests
resp = requests.post(
"https://api.sume.com/v1/images",
headers={"Authorization": f"Bearer {os.environ['SUME_API_KEY']}"},
json={ # json= sets Content-Type: application/json
"model": "openai/gpt-image-2.5",
"prompt": "Keep the product identical; soft daylight studio background",
"input_references": [
{"type": "image_url", "image_url": {"url": "https://example.com/product.png"}}
],
"aspect_ratio": "auto",
},
timeout=60,
)
print(resp.status_code) # 200 image response, or 202 job envelopeWhat do I check after fixing the body?
Read the status code, not the body shape. POST /v1/images blocks for up to 30 seconds and returns 200 with data[].url; a slow edit returns 202 with the job envelope, and you then poll status_url and result_url as described in Jobs and results.
If the 415 persists after switching to JSON, look at details.received_content_type. A proxy, an HTTP library default, or a hand-set Content-Type header is the usual reason the value is not what you meant to send.
Sources
Related posts
More in Developers
- Image model missing from Sume's /v1/images/models? Read it live
GET /v1/images/models lists models Sume can serve now; sume/auto is never listed, and unknown ids return 404 model_not_found. Read the catalog at runtime.
- Which Sume image models take no output_format? Soul and Ideogram 4.5
Soul and Ideogram 4.5 publish an empty output_format list on Sume: omit the field. Recraft V4 lists webp only; the other 16 rows take png, jpeg and webp.
- Image retry returns 409 idempotency_conflict: new key per payload
A 409 idempotency_conflict on a Sume image job means the same Idempotency-Key was reused with a different payload. Derive the key from the payload in Python.
- Image-to-image strength or denoise: no field on Sume, do this
No strength, denoise or seed field exists on Sume's Image API; it returns 400 unsupported_parameter. How to control how far an edit moves from the reference.
Written by Sume