Sora input_reference image: upload with uploadFile, use frame_images

OpenAI took the first-frame image as multipart input_reference. Sume wants an HTTPS URL: upload with the SDK's uploadFile, then pass it as frame_images.

5 min readSume
All posts

If your Sora code sent a local JPEG, PNG or WebP as input_reference, the Sume version is two steps: upload the bytes with uploadFile from @sume-com/sdk to get a durable HTTPS URL, then send that URL in frame_images with frame_type first_frame. Sume's /v1/videos takes JSON and URLs, not a multipart file part.

OpenAI's video guide, read 2026-10-08, describes input_reference as an image that becomes the first frame, and the same guide now says the Videos API shuts down on September 24, 2026.

Field by field

Sume also has input_references, with an s, which conditions the whole clip rather than pinning the opening frame. If your Sora call was a first frame, use frame_images. If you send both fields, frame_images wins.

Image input mapping, vendor docs read 2026-10-08
ConcernOpenAI guideSume docs
Where the image goesinput_reference, multipart file partframe_images[].image_url.url, JSON
Role of the imagefirst frameframe_type: first_frame or last_frame
Countone imageframe_images up to 2; input_references up to 12
Formats namedJPEG, PNG, WebPan HTTPS image URL; the model row lists its supported types
Where limits livethe guide pagethe model row in GET /v1/videos/models

The upload and the call

uploadFile reserves a presigned PUT, sends the bytes straight to storage, then completes the asset and returns the durable URL. It reuses the client's key and base URL, which defaults to https://api.sume.com. Run this as an ES module on Node 18 or later with SUME_API_KEY set.

import { readFile } from "node:fs/promises";
import { createSumeClient, createVideoGeneration, uploadFile } from "@sume-com/sdk";

const client = createSumeClient({ apiKey: process.env.SUME_API_KEY });
const bytes = await readFile("start.png");
const asset = await uploadFile({
  client,
  file: new Uint8Array(bytes),
  contentType: "image/png",
  filename: "start.png",
});

const { data, error } = await createVideoGeneration({
  client,
  headers: { "Idempotency-Key": "start-png-1" },
  body: {
    model: "sume/auto",
    prompt: "The camera pulls back from the product on the desk",
    frame_images: [{
      type: "image_url",
      image_url: { url: asset.url },
      frame_type: "first_frame",
    }],
  },
});
console.log(error ?? data);

Things to check

The asset endpoints behind uploadFile are kept out of the public OpenAPI document, which is why the helper exists; do not hand-roll them from the spec. Generated SDK calls return an object with data, error and response instead of throwing, so the last line prints whichever one is set.

Not every catalog model accepts a first frame. Read supported_frame_images on the model row before you pin sume/auto in code, and see the first-frame size post for the size question.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume