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.

4 min readSume
All posts

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 codes you meet when moving an edit call to Sume. Source: docs.sume.com errors page and image API page, read 2026-10-03.
StatusCodeWhat it means for an edit
415unsupported_media_typeBody was not application/json; send JSON.
400invalid_requestA JSON field is wrong, for example a reference entry without image_url.url.
400unsupported_parameterThe selected model does not list that field in its catalog descriptors.
413payload_too_largeBody 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 envelope

What 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

All Developers posts

Written by Sume