API reference/POST /collage

Multi-photo collage

Send 2–9 product photos and get one hero collage back. Every photo is background-removed and tight-cropped, one "main" photo is placed dominant, and the rest are arranged around it. The only multi-file endpoint: send several files, get one composite. Paid tier only.

POSThttps://useknockout--api.modal.run/collage

Parameters

Send as multipart/form-data unless noted otherwise.

filesrequiredfile[]2–9 images. Send as repeated form fields all named "files": not "files[]", not one combined field.
main_indexint0Which uploaded photo is the hero (0-based). Must be 0..N-1.
main_positionstringBRWhere the hero sits. One of TL, T, TR, L, C, R, BL, B, BR (a 3×3 grid).
bg_colorstring#FFFFFFBackground hex color.
aspectstring1:1Output aspect ratio as W:H. Long side is 1600px.
paddingint 0-20024Padding in pixels between photos and canvas edge.
formatstringjpgOutput format: jpg, png, or webp. Output is opaque, so jpg is the default.
qualityint 1-10092JPEG/WebP quality. Ignored for PNG.
max_dimintClamp the longest output edge to N pixels (downscale only).
despillint 0-100Strength of colored edge-spill removal on each cutout. Knockout Plus only.
watermarkstringURL of a watermark image (PNG with alpha) to overlay. Knockout Plus only.
watermark_opacityfloat 0-11.0Watermark opacity. Only applies when watermark is set. Knockout Plus only.
presetstringApply a saved preset by id (see /presets). Explicit params override stored values. Knockout Plus only.

Request

curl -X POST "https://useknockout--api.modal.run/collage" \
  -H "Authorization: Bearer $TOKEN" \
  -F "files=@shoe-front.jpg" \
  -F "files=@shoe-side.jpg" \
  -F "files=@shoe-sole.jpg" \
  -F "main_index=0" \
  -F "main_position=BR" \
  -F "aspect=1:1" \
  -o collage.jpg

Response

HTTP/1.1 200 OK
content-type: image/jpeg
content-length: 412204
x-knockout-model: BiRefNet

Errors

400invalid_countcollage requires 2–9 images.
400invalid_main_indexmain_index must be 0..N-1.
400invalid_main_positionmain_position must be one of TL, T, TR, L, C, R, BL, B, BR.
400no_subject_detectedNo subject detected in image X of N. The message names which photo failed.
401unauthorizedMissing or invalid token.
402payment_requiredCollage is paid-tier only. Free and demo keys get 402: add a card or upgrade.
413payload_too_largeA file exceeds 10 MB or 4096×4096.
429rate_limit_exceededSlow down. Retry-After header tells you when.
500collage_failedCollage generation failed or produced no output.
Every error response also includes a request_id in the JSON body. Quote it when reporting issues.

Notes

  • Paid tier only. Free and demo keys receive HTTP 402.
  • Cost = N × the per-image price: a 9-photo collage bills as 9 images.
  • Slower than single-image endpoints: budget 4–13s per photo, since each is a separate model pass. Don't reuse a single-image request timeout.
  • Error bodies are JSON: {"detail": "..."}. For no_subject_detected, the detail names which photo (X of N) failed.
  • EXIF orientation is auto-corrected on every input: sideways phone photos come back upright.
  • Output is opaque (composited on bg_color), so jpg is valid and is the default.