Models

Image-to-video API: set the first and last frame with frame_images

Send frame_images to POST /v1/videos with a first_frame and an optional last_frame. Which Sume models take each frame, what wins, and what gets refused.

5 min readSume
All posts

To turn a still image into a video with the Sume API, send POST /v1/videos with a frame_images array: an entry with frame_type: "first_frame" sets the clip's first frame, and an optional "last_frame" entry sets its last. Every video model in the catalog accepts a first frame, and all but grok-imagine-video-1.5 also accept a last frame.

Field rules below come from the Video generation docs. Per-model support comes from the catalog that GET /v1/videos/models returns, read on 2026-09-26.

How do I send a first and last frame?

Each frame_images entry has type: "image_url", an image_url object holding the url, and a frame_type of first_frame or last_frame. The request below adapts the docs' image-to-video example to pin both ends of a Seedance 2.0 clip at 1080p.

  • Image URLs must be fetchable public HTTPS URLs. Localhost, private-network, non-HTTPS, and signed or private URLs are rejected before the job is submitted.
  • Send Idempotency-Key to make retries safe: a replay returns the original job.
  • The call returns 202 with a job id and a polling_url. Poll until status is completed, then download from unsigned_urls[0].
curl -X POST https://api.sume.com/v1/videos \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: i2v-first-last-001" \
  -d '{
    "model": "seedance-2",
    "prompt": "A character walking through a forest",
    "frame_images": [
      {
        "type": "image_url",
        "image_url": { "url": "https://example.com/first-frame.png" },
        "frame_type": "first_frame"
      },
      {
        "type": "image_url",
        "image_url": { "url": "https://example.com/last-frame.png" },
        "frame_type": "last_frame"
      }
    ],
    "resolution": "1080p"
  }'

Which models accept a first frame, a last frame, or both?

Each model lists the frame_type values it accepts in supported_frame_images. A model that also does text-to-video runs from the prompt alone when you send no frame. grok-imagine-video-1.5 is image-to-video only: it requires a first frame and takes no end frame.

Frame support per model, from the catalog behind GET /v1/videos/models and Video generation, read 2026-09-26. Confirm with GET /v1/videos/models before you submit.
Model id`first_frame``last_frame`Prompt only
seedance-2.5, seedance-2, seedance-2-fast, seedance-2-miniYesYesYes
kling-3YesYesYes
wan-3.0YesYesYes
minimax-h3, minimax-h3-maxYesYesYes
gemini-omni-flash-1.1YesYesYes
grok-imagine-video-1.5RequiredNoNo

What happens if I send frames and references together?

frame_images takes precedence. When a request carries both frame_images and input_references, Sume treats it as image-to-video and does not pass the references to the model. A frame image sets the clip's first or last frame; references are visual guidance rather than exact frames, covered in Reference-to-video API.

Why was my image-to-video request refused?

POST /v1/videos checks your frames against the model's catalog entry and refuses a mismatch with a 400 and the error code unsupported_capability:

  • A last_frame with no first_frame: “frame_images with a last_frame also requires a first_frame.”
  • A frame_type the model does not list, such as last_frame on grok-imagine-video-1.5: “grok-imagine-video-1.5 does not support frame_type last_frame.” The error details carry the model's supported values.
  • resolution, aspect_ratio, and duration are checked against the model's lists the same way. See AI video length limits by model for durations.

What if my code still sends image_url and end_image_url?

Those are the flat fields of the older routes: Video 1.0, which is retiring soon, and the Video Router, which still works unchanged, take image_url for the first frame and end_image_url for the end frame. The field-by-field move is in Video 1.0 and Image 1.0 are retiring soon.

Two frame rules differ by route when model is a catalog id. POST /v1/videos refuses the flat fields with 400 invalid_request, so send frame_images there. POST /v1/video-router/generate refuses a first frame and reference_*_urls in the same request, where /v1/videos lets the frames take precedence.

How is an image-to-video clip billed?

Like any video job: the cost is reserved from the workspace USD balance on submit at the provider's list price × 1.25, plus a 5.5% agent fee by default, using the rates each model lists in pricing_skus on GET /v1/videos/models; see API pricing.

Sources

Related posts

Written by Sume