Compose 400: stack and overlay layout keys cannot be mixed

Fix compose_stack_takes_no_overlay_layout and its mirror: pick stack or overlay as operation, then send only the layout keys that belong to it.

5 min readSume
All posts

Timeline compose returns compose_stack_takes_no_overlay_layout when a stack request carries an overlay key, and compose_overlay_takes_no_stack_layout when an overlay request carries a stack key. Choose the operation first, then send only the layout keys that belong to it; the table below lists which are which.

The rules are from the Timeline compose page, read 2026-10-10. Compose puts one still and one video on screen together and returns one MP4 for $0.02 flat per job (confirm in GET /v1/catalog).

Which layout keys belong to which operation

The field that picks stack or overlay is operation. It is not mode, which is the usual async or sync communication option, and mixing the two up is the other common first mistake.

Compose layout keys by operation, from the Timeline compose docs (read 2026-10-10)
`layout` key`stack``overlay`
splithorizontal or verticalNot permitted
image_regiontop or bottom on a horizontal split; left or right on a vertical splitNot permitted
ratioThe still's share of the frame, 0.1 to 0.9Not permitted
image_fit and video_fitcover, contain or stretchvideo_fit only
positionNot permittedtop, center or bottom
width_ratioNot permitted0.05 to 1 of width, default 0.9
margin_ratioNot permitted0 to 0.45 of height, default 0.05

Why a copied layout object fails

The usual cause is reuse. A team builds a half-banner with split, image_region and ratio, then flips operation to overlay to get a price card on the clip and keeps the old layout object. The API answers 400 with compose_stack_takes_no_overlay_layout or its mirror image, because the vocabulary is separate on purpose: a stack divides the frame between two regions, while an overlay places a plate on top of a full-frame video.

A related error is compose_image_region_wrong_axis: left or right on a horizontal split, or top or bottom on a vertical one. The region must match the split, so a vertical split pairs with left or right.

  • Stack defaults are horizontal, top and 0.5: still on top, video below, the half-banner shape.
  • ratio is the still's share; the video takes the exact remainder.
  • blur is not a compose fit. It is a Timeline video[].fit value, so a compose request using it is not valid.
  • Overlay plates keep their own aspect ratio at the chosen width_ratio.

A valid overlay request

The sample puts a price card near the bottom of a clip, 80% of the width, with a 5% margin. It carries only overlay keys. Both URLs must already be media.sume.com files in your workspace (import them first), image.url must probe as a still and video.url as a video, and Idempotency-Key is required.

curl -X POST https://api.sume.com/v1/timeline-1.0/compose \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: compose-overlay-001" \
  -d '{
    "operation": "overlay",
    "image": {"url": "https://media.sume.com/artifacts/artf_demo/price-card.png"},
    "video": {"url": "https://media.sume.com/artifacts/artf_demo/talk.mp4"},
    "layout": {"position": "bottom", "width_ratio": 0.8, "margin_ratio": 0.05}
  }'

What stays the same either way

The output length always comes from the video layer: video.duration, or the rest of the file from source_in. The still stays on screen for the whole clip and can never make it longer. The ceiling is 300 seconds, and a duration past the end of the source is clamped with the warning compose_duration_clamped_to_source, which does not fail the job.

The default output is 1080 by 1920 MP4 at the video's frame rate. A silent video gives the warning compose_video_has_no_audio; it still renders, and a Timeline spine can supply sound at assembly. Put the finished MP4 into Timeline 1.0 video[] as a normal slot.

A quick checklist before you submit

Read the request top to bottom: pick operation, then check every layout key against the table, then confirm the still is a still and the video is a video. Keys such as filtergraph, ffmpeg_args, codec and crf are refused with a 400, so there is no way to hand-place a plate with a raw filter.

When the same price card must go on many clips, keep two small layout objects in your code, one per operation, and build requests from the one that matches. That removes the copy-and-flip mistake, and each job is a flat $0.02 whichever operation you choose, so a batch of 100 overlays costs $2.00 before any retries.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume