sume-virtual-try-on Format: first frame, then Seedance 2.5

The sume-virtual-try-on Format builds a first frame with ChatGPT Image 2, then animates it with Seedance 2.5. What goes in, what comes back.

6 min readSume
All posts

The sume-virtual-try-on Format makes a short video of a person wearing a garment. In the first-party Format code, it builds the first frame with ChatGPT Image 2 and then animates it with Seedance 2.5 reference-to-video. You give it a person photo and a garment photo as attachments and call it on POST /v1/formats/sume/sume-virtual-try-on/runs.

That is a different product from the try-on button OpenAI launched in ChatGPT on October 1, 2026, which produces an image inside the chat. The Sume Format is meant for the next step a store usually wants: a clip it can post. For a still-only path, see the try-on screenshot post.

Inputs the run accepts

A Format run needs at least one of instruction, input, previous_run_id or attachments. Attachments can be up to 30 images in JPEG, PNG, WebP, GIF or AVIF, with 30 MB per file and 500 MB per run. For a try-on you need two: the person and the garment. Say in the instruction which is which, because the model sees only the pixels and the text.

The instruction is read up to 8000 characters, but only about the first 4000 are carried, so put the important parts first: aspect ratio, framing, what must not change.

sume-virtual-try-on run inputs, read 2026-10-03
InputLimitTip
attachmentsUp to 30 images, 30 MB each, 500 MB per runSend person first, then garment
instruction8000 chars, about 4000 carriedPut framing and constraints first
generation_spend_cap_usdFormat default $400, max $500, 0 rejectedSet a lower cap per run
Idempotency-KeyUp to 255 chars, scoped per FormatDerive from shopper and SKU
communication.webhook_urlPublic HTTPSReceive one signed format.run.terminal

Calling it

The create call returns 202 Accepted with a run object whose status starts at queued. Poll the run or arm a webhook and read the receipt when it is terminal. The receipt carries usage.billable_amount_usd_micros, and on a failed run primary_output_url is null, so branch on that before you show anything.

curl -sS -X POST "https://api.sume.com/v1/formats/sume/sume-virtual-try-on/runs" \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: tryon-shopper-77-sku-1042-v1" \
  -d '{
    "instruction": "Image 1 is the person, image 2 is the linen shirt. Vertical 9:16, full body, natural light.",
    "attachments": [
      {"type": "input_image", "image_url": "https://cdn.example.com/people/77.jpg"},
      {"type": "input_image", "image_url": "https://cdn.example.com/sku/1042.jpg"}
    ],
    "generation_spend_cap_usd": 20
  }'

Try-on or fitting

If your goal is a fashion ad rather than a personal preview, compare it with the sibling Format. The virtual fitting versus virtual try-on post sets them side by side. Whichever you pick, the catalog lists the slug and the owner handle sume, so a run is always addressed as /v1/formats/sume/<slug>/runs.

Treat the first output as a draft. Garment print, sleeve length and hands are where renders slip, and the QC checklist covers frame checks you can run before you ship.

Reading the result and the bill

When the run is terminal, read primary_output_url for the clip and usage.billable_amount_usd_micros for what the run cost. A failed run has a null primary_output_url and a failure code such as unattended_blocked, deliverable_missing or primary_output_missing, which the errors doc explains. Do not post a result whose primary_output_url is null.

If a draft is close but wrong, for example the shirt is the right colour but the wrong length, continue the same conversation with previous_run_id and a short corrective instruction rather than starting over with new attachments. That keeps the thread's context and usually costs less than a full re-run.

To get a typed response with the video URL in a named key, bind an output_schema with a SumeMediaFile# reference and set primary_output_key; the structured output doc shows the strict subset that is accepted.

Keep your own identifiers outside the run. On the projection path, input identifiers do not round-trip into the typed output, so key your SKU id by the run id or by your Idempotency-Key and look it up when the webhook arrives. For a catalog, see the bulk try-on post. A webhook receipt larger than 1 MiB arrives with a null payload, so fetch the run by id instead of trusting the body.

Sources

Related posts

More in Formats

All Formats posts

Written by Sume