Seamless loop AI video: make a clip end where it starts

To loop an AI video, send one image as both its first and last frame, then compare the two ends before you loop it. Which models take an end frame.

5 min readSume
All posts

A seamless loop is a clip whose last frame leads straight back into its first, so it can repeat without a visible jump. To make one with AI, generate an image-to-video clip that uses the same picture as both its first and its last frame, then check the two ends before you loop it. Only the ends are pinned: the motion between them is generated, and no documented setting makes it cyclic.

The steps use Sume's video API. Frame rules come from the Video generation docs, the check from the Video frames docs, and per-model support from the catalog behind GET /v1/videos/models, read on 2026-09-27.

How do I make an AI video loop?

  • Pick a model that takes a last frame. Every video model on Sume does except grok-imagine-video-1.5, which takes a first frame only.
  • Put the picture at a public HTTPS URL. Signed, private, localhost, and non-HTTPS links are refused.
  • Send it twice in frame_images: once with frame_type: "first_frame" and once with "last_frame". Current code takes at most two entries and refuses a last frame sent without a first frame.
  • Describe motion that can come back to where it started, such as a slow sway, a gentle bob, or rippling water.
  • For a silent background loop, send generate_audio: false on a model where sound is optional (next sections).
curl -X POST https://api.sume.com/v1/videos \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: loop-clip-001" \
  -d '{
    "model": "wan-3.0",
    "prompt": "The lantern sways gently on its chain while the water below ripples",
    "frame_images": [
      { "type": "image_url", "image_url": { "url": "https://example.com/lantern.png" }, "frame_type": "first_frame" },
      { "type": "image_url", "image_url": { "url": "https://example.com/lantern.png" }, "frame_type": "last_frame" }
    ],
    "generate_audio": false,
    "duration": 5
  }'

How do I check the loop before I use it?

Pull the first and last frames of the finished clip and compare them, then play the clip on repeat and watch the motion around the loop point: matching ends are not the whole test.

Video frames returns stills at the times you name, as durable images, and it is unbilled. It reads your workspace's media.sume.com copy of the clip, which GET /v1/jobs/{id}/result lists. Every time must satisfy 0 <= t < duration, so ask for the last frame just before the end; Extract the last frame of a video shows how to read the duration and frame rate and pick that time. For a 5-second clip at 24 fps, it is 4.958:

curl -X POST https://api.sume.com/v1/video-frames \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: loop-ends-001" \
  -d '{
    "video_url": "https://media.sume.com/artifacts/artf_demo/loop.mp4",
    "at": [0, 4.958],
    "format": "png"
  }'

Does the sound loop too?

Generated audio is not documented to loop, so a background loop is simplest without it. Sound is optional on the Seedance models, wan-3.0, and kling-3: send generate_audio: false. minimax-h3, minimax-h3-max, and gemini-omni-flash-1.1 always generate sound, and current code refuses generate_audio: false on them, so their clips come with audio. Which video models generate sound has the full list.

What are the limits?

From Video generation, Video frames, and the catalog behind GET /v1/videos/models, read 2026-09-27.
LimitWhat it means for a loop
Only the two ends are pinnedThe motion in between is generated; nothing in the docs makes it cyclic.
frame_images: at most two entries in current codeOne first frame and one last frame per clip.
No last frame on grok-imagine-video-1.5Use another model for a loop.
Clip length2–30 seconds depending on the model; seedance-2.5 and wan-3.0 go to 30.
Video frames times1–24 values per call, each 0 <= t < duration.

Sources

Related posts

More in Models

All Models posts

Written by Sume