Edits keyframes vs Sume Timeline: stills are static, no zoom

Edits supports keyframes. Sume Timeline holds a still static and ignores a motion field; animate the still first with Video Router image-to-video.

4 min readSume
All posts

Instagram's Edits page lists keyframe support among the app's features (read 2026-10-03), so a slow push-in on a photo is a few taps there. Sume Timeline 1.0 cannot do that: it treats a still as a static hold, accepts a motion field on a slot and ignores it, reporting motion_ignored as a soft warning rather than an error. If you want a still to move, animate it first into a clip, then place the clip. The docs list one route for that: image-to-video on the Video Router.

What a Timeline slot actually does with a still

video[].source_url can be a hosted still, which holds for the slot's duration with fit set to cover, contain, stretch or blur. Transitions between slots are limited to fade, wipeleft, wiperight, slideup, slidedown and dissolve, at most one second and half the shorter neighbour. Nothing in that list is a zoom or pan, so a render of stills is a slideshow with transitions.

Moving a still: Edits versus Sume, read 2026-10-03
NeedEditsSume
Slow push-in on a photoKeyframesNot on Timeline; generate a clip first
Slide between photosTransitionsTimeline transitions, up to 1 s
Photo to short clipAI image animationVideo Router image_url, 3-10 s on gemini-omni-flash-1.1
Hold a stillYesYes, static, motion_ignored warning

Animate a still, then place it

gemini-omni-flash-1.1 accepts image_url for image-to-video at 3-10 seconds, resolution 360p to 4K, 16:9 or 9:16, with native audio always on. The request below asks for a 5-second 9:16 clip at 720p. Poll the job, take the clip from result.artifacts[], and use it as a video[] slot with source_in 0.

import json, os, urllib.request

API = "https://api.sume.com/v1"

def post(path, body, key):
    req = urllib.request.Request(
        f"{API}{path}",
        data=json.dumps(body).encode(),
        headers={
            "Authorization": f"Bearer {os.environ['SUME_API_KEY']}",
            "Content-Type": "application/json",
            "Idempotency-Key": key,
        },
        method="POST",
    )
    with urllib.request.urlopen(req) as res:
        return json.load(res)

job = post(
    "/video-router/generate",
    {
        "model": "gemini-omni-flash-1.1",
        "prompt": "Slow push-in on the product, soft daylight, no text",
        "image_url": os.environ["SUME_STILL_URL"],
        "duration": 5,
        "resolution": "720p",
        "aspect_ratio": "9:16",
        "mode": "async",
    },
    "animate-still-001",
)
print(job["request_id"])

Cost and choice

Billing for that model is provider list times 1.25 per output second by resolution, so read GET /v1/video-router/models for the current rate before you queue a batch. A generated clip is new footage, and the model may change details of the photo, so check the result. For a faithful push-in on a fixed image with no changes at all, keyframes in Edits are the more predictable tool; for many stills in a scripted run, the generate-then-place route is the one Sume documents.

Checking the plan for ignored motion

Because motion_ignored is a warning, not an error, a render can succeed with a still that never moves. The pre-flight POST /v1/timeline-1.0/plan cannot predict every warning (short-source pad or loop warnings are only known at render), so read warnings[] on the result and treat motion_ignored as a signal you asked for something Timeline does not do. If you saw it, you wanted an animated clip, not a hold.

One more fallback is to leave the push-in to an editor and use Sume for everything around it. That is a reasonable split: keyframes for a single hero shot, Timeline for the sequence, captions and soundtrack.

Three ways to get a moving shot

Pick the route by how much control you need over the movement itself.

  • Keyframes in Edits: exact start and end positions on a photo you already have, no generation.
  • Image-to-video through Sume: a generated clip from the still plus a prompt, with the model deciding how it moves.
  • Start and end frames: for models that list first_frame and last_frame in the catalog, pin both ends so the motion travels between two images you chose. Check the model's capabilities on GET /v1/videos/models before relying on it.

Doing the move before the render

If you want the effect of a keyframed zoom on a still, the practical route on Sume is to produce motion before Timeline sees it. Generate a short clip from the still with the Video Router image-to-video path, then place that clip in the video[] slots. The still itself stays a static hold, as the docs say, with a motion_ignored warning if you send motion fields. Whether the generated movement matches what you would have keyframed is a creative check you make by eye.

Cost stays small either way: the image-to-video clip is billed by the model you pick, and the Timeline render is $0.10 per ceiling minute, so a ten-second move inside a thirty-second Reel adds one generation and one render. Compare that with the price of reshooting, and with doing the keyframe in the Edits app, which Instagram offers for its own timeline (read 2026-10-03).

Sources

Related posts

More in Comparisons

All Comparisons posts

Written by Sume