Combine multiple product photos into one AI image via API

Combine product photos into one AI image: attach a packshot per SKU to Sume's sume-editorial-product-set Format, or send them to POST /v1/images.

5 min readSume
All posts

To combine multiple product photos into one AI image with the Sume API, attach one packshot per product to a run of the catalog Format sume-editorial-product-set at POST /v1/formats/sume/sume-editorial-product-set/runs. To pick the model and write the prompt yourself, send the same photos as input_references to POST /v1/images on a model that accepts that many references.

The facts below come from Sume's Format catalog, Create a run, Structured output, and Image API docs, read on 2026-09-27. The Format's description is quoted from its catalog entry.

Which catalog Format puts several products in one image?

sume-editorial-product-set (catalog title: Sume Editorial Product Set) is the catalog's product-set image Format. Its description reads: "Create a finished editorial product-set image featuring a coordinated collection, graphic arrangement, and premium set design. Use when the user asks for skincare routines, collection launches, bundles, gift sets, and multi-SKU campaigns. Not for: animated or motion deliverables."

Read that as the Format's stated aim, not a promise about any one image. GET /v1/formats/sume/sume-editorial-product-set returns the description before you call. The recipe body is not in that response: it reaches the agent, not the caller. Any key with formats:write may run the Format, and the run, its media, and its spend belong to that key.

How do I send one photo per product?

Add each packshot to attachments[] as an input_image with a public HTTPS image_url. A run takes up to 30 images the agent can see. filename is the label the agent sees, so name each product. Sume fetches every attachment when you create the run and checks its real type and size, so a broken or private image fails the create instead of the run.

Describe the arrangement in instruction: which products, which one leads, what setting. It accepts 8000 characters; about the first 4000 reach the run as prompt text. Your instruction is composed after the Format body, so where the two disagree, the model follows what you asked for.

curl -sS -X POST "https://api.sume.com/v1/formats/sume/sume-editorial-product-set/runs" \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: gift-set-winter-v1" \
  -d '{
    "instruction": "One gift-set image of the three attached products. Cleanser in front.",
    "attachments": [
      { "type": "input_image", "image_url": "https://example.com/cleanser.png", "filename": "cleanser.png" },
      { "type": "input_image", "image_url": "https://example.com/toner.png", "filename": "toner.png" },
      { "type": "input_image", "image_url": "https://example.com/cream.png", "filename": "cream.png" }
    ],
    "output_schema": {
      "name": "acme/gift-set/v1",
      "schema": {
        "type": "object",
        "additionalProperties": false,
        "required": ["hero_image"],
        "properties": { "hero_image": { "$ref": "SumeMediaFile#" } }
      }
    },
    "primary_output_key": "hero_image",
    "generation_spend_cap_usd": 10
  }'

How do I get the finished image back?

The create answers 202 with a run receipt. Poll GET /v1/format-runs/{run_id} until the status is terminal, or send communication.webhook_url and receive one signed format.run.terminal POST. The schema borrows from the docs' own example: hero_image is a SumeMediaFile#, and primary_output_key: "hero_image" makes it the receipt's primary_output_url. Every URL in output is checked against the media this run produced. Media URLs on media.sume.com do not expire, and they are public to anyone holding them.

If nothing the run made satisfies your schema, output is null, output_error says why, and over the API the run ends failed. artifacts[] still lists everything the run made. Schema rules are in Sume Format structured output.

Can I send the photos straight to the Image API instead?

Yes. POST /v1/images takes a model, a prompt, and an input_references array of public HTTPS image URLs, so you choose the model and write the prompt. The request itself is covered in Image generation API with reference images.

For a bundle, the number to check is the model's reference ceiling. Its input_references descriptor on GET /v1/images/models is a range, so pick a model whose maximum covers every product in the set. ChatGPT Image 2.5 (openai/gpt-image-2.5), used below, takes up to 16 image references. sume/auto is not listed in that catalog, so it shows no range to check.

curl -X POST "https://api.sume.com/v1/images" \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-image-2.5",
    "prompt": "The three referenced products arranged together as one gift set",
    "input_references": [
      { "type": "image_url", "image_url": { "url": "https://example.com/cleanser.png" } },
      { "type": "image_url", "image_url": { "url": "https://example.com/toner.png" } },
      { "type": "image_url", "image_url": { "url": "https://example.com/cream.png" } }
    ]
  }'

Which path should I use?

Use the Format when its saved recipe should make the production choices, and the Image API when you want to choose the model and prompt.

From Create a run, Format API attachments, and Image API, read 2026-09-27.
Catalog FormatImage API
EndpointPOST /v1/formats/sume/sume-editorial-product-set/runsPOST /v1/images
Product photosattachments[], up to 30 imagesinput_references[], up to the model's range
What steers the resultThe Format's recipe, plus your instructionYour model and prompt
Response202 run receipt, then poll or webhook200 with a signed data[].url, or 202 with a job
BillingMetered at API pricing rates, capped by generation_spend_cap_usdAll-or-nothing: completed generations billed in full, failed ones not billed

What are the limits?

From the same docs pages:

  • Attachments are JPEG, PNG, WebP, GIF, or AVIF, up to 30 MB per image and 500 MB per run. Too many items is 400 invalid_attachment; an oversized image or set is 413 attachment_too_large.
  • input_image is the only attachment type, and the Format makes a still, not motion.
  • generation_spend_cap_usd goes up to $500; null runs at $500, and 0 is rejected.
  • Replaying an Idempotency-Key with a different image list is 409 idempotency_conflict.
  • For one image per bundle across a catalog, one bulk request queues up to 100 runs of the Format. See Sume Format bulk runs.

Sources

Related posts

More in Use cases

All Use cases posts

Written by Sume