Guide

Text to video vs image to video: the five API modes explained

Most video models accept more than a prompt. You can start from an image, fix the first and last frames, pass reference images for characters and products, or work from an existing clip. This guide explains each mode, when to use it, and how to call it.

The five modes at a glance

Every mode uses the same endpoint, POST /v1/generations. What changes is the input you send next to the prompt.

Video generation modes
ModeWhat you sendGood for
Text to videoa promptexploring ideas, b-roll, scenes you have no images for
Image to videoa start frame as image_url, plus a promptanimating product shots, artwork and stills with an exact look
First and last frameimage_url and end_image_url, plus a prompttransitions, reveals and shots that must end on a set image
Reference imagesseveral images as image_urls, plus a promptkeeping characters, products and places consistent across shots
Video to videoa source clip, plus a promptrestyling or reworking footage you already have

Not every model supports every mode. The support table below covers the main models, and each model's page on the models page lists its tasks.

Text to video

Text to video is the simplest mode: you describe the shot and the model decides everything else, from the faces and the set to the colours and the framing. That freedom is useful when you are exploring ideas or need generic footage, such as b-roll, establishing shots or abstract backgrounds.

It is the wrong mode when the video has to show something specific: your product, your logo, a particular person or a layout that must match a brand guide. Every generation invents those details anew, so two clips from the same prompt will not match.

A good text prompt covers the subject, the action, the setting, the camera and the light, and the sound if the model generates it. Our Seedance 2.0 guide has more prompt tips.

Image to video

With image to video, your image becomes the first frame. Everything in it (the product, the face, the composition and the colours) is fixed at the start, and the prompt only has to describe what happens next. This is the mode for animating product photos, illustrations and key art, and for any shot where the look has to be exact.

A common workflow is to make the still first with an image model such as Nano Banana Pro or GPT Image 2, get it right, and then animate it. Stills are cheaper and faster to iterate on than video.

Here is an image to video request for Seedance 2.0: a 5 second 720p clip with sound, which costs $0.75. The adaptive aspect ratio matches the frame to the shape of your image.

cURL
export REVANA_API_KEY="sr_live_..."

# 1. Submit the job (returns 202 with the generation id)
curl https://api.revana.si/v1/generations \
  -H "Authorization: Bearer $REVANA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "seedance-2.0",
    "input": {
      "prompt": "The coffee in the cup starts to steam, and a hand reaches in from the right and lifts the cup off the table. Morning light, quiet cafe ambience.",
      "image_url": "https://example.com/coffee.jpg",
      "resolution": "720p",
      "duration": 5,
      "aspect_ratio": "adaptive",
      "audio": true
    },
    "max_cost_usd": 2
  }'

# 2. Poll with the id from step 1 until status is "succeeded" or "failed"
curl https://api.revana.si/v1/generations/gen_01JBX7Q2M4 \
  -H "Authorization: Bearer $REVANA_API_KEY"
Python
import os
import time

import requests

API = "https://api.revana.si/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['REVANA_API_KEY']}"}

resp = requests.post(f"{API}/generations", headers=HEADERS, json={
    "model": "seedance-2.0",
    "input": {
        "prompt": "The coffee in the cup starts to steam, and a hand reaches in from the right and lifts the cup off the table. Morning light, quiet cafe ambience.",
        "image_url": "https://example.com/coffee.jpg",
        "resolution": "720p",
        "duration": 5,
        "aspect_ratio": "adaptive",
        "audio": True,
    },
    "max_cost_usd": 2,
})
resp.raise_for_status()
job = resp.json()

while job["status"] in ("queued", "running"):
    time.sleep(5)
    job = requests.get(f"{API}/generations/{job['id']}", headers=HEADERS).json()

if job["status"] == "succeeded":
    print(job["output"]["urls"], job["cost_usd"])
else:
    print("Failed:", job["error"])
Node.js
// Node 18 or later. Save as generate.mjs and run: node generate.mjs
const API = "https://api.revana.si/v1";
const headers = {
  Authorization: `Bearer ${process.env.REVANA_API_KEY}`,
  "Content-Type": "application/json",
};

const res = await fetch(`${API}/generations`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    model: "seedance-2.0",
    input: {
      prompt: "The coffee in the cup starts to steam, and a hand reaches in from the right and lifts the cup off the table. Morning light, quiet cafe ambience.",
      image_url: "https://example.com/coffee.jpg",
      resolution: "720p",
      duration: 5,
      aspect_ratio: "adaptive",
      audio: true,
    },
    max_cost_usd: 2,
  }),
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
let job = await res.json();

while (job.status === "queued" || job.status === "running") {
  await new Promise((r) => setTimeout(r, 5000));
  job = await (await fetch(`${API}/generations/${job.id}`, { headers })).json();
}

if (job.status === "succeeded") console.log(job.output.urls, job.cost_usd);
else console.error("Failed:", job.error);

Describe motion, not the image: the model can already see it. "The steam rises and the cup is lifted" works better than restating "a white cup of coffee on a wooden table".

First and last frames

Add end_image_url and the model generates the motion between two images you choose. Because the ending is fixed, this mode suits transitions between scenes, before and after shots, product reveals, and clips that must cut cleanly into the next one. For a loop, try the same image at both ends.

The two frames should be plausible ends of one shot: the same scene, framing and light. If they are too different, the model has to invent a large change in a few seconds, and results get less predictable. This silent 5 second 1080p Kling 3.0 clip costs $0.60:

Request body
{
  "model": "kling-3.0",
  "input": {
    "prompt": "Time-lapse: the empty plot fills with a small wooden cabin as the camera holds still, clouds racing overhead",
    "image_url": "https://example.com/plot-empty.jpg",
    "end_image_url": "https://example.com/plot-cabin.jpg",
    "resolution": "1080p",
    "duration": 5,
    "audio": false
  },
  "max_cost_usd": 1
}

Seedance 2.5, Seedance 2.0, Seedance 2.0 Mini, Veo 3.1, Veo 3.1 Fast, Veo 3.1 Lite, Kling 3.0, Kling 3.0 Omni, Wan 3.0 and Grok Imagine Video 1.5 list first and last frames in the catalogue. Hailuo 2.3 takes a start frame but no end frame.

Reference images

Reference images are not frames. The model uses them to learn what a person, product or place looks like, then puts them into a new shot that the prompt describes. That makes references the mode for consistency: the same character across ten shots, or the same product in different settings.

Send the images as image_urls and refer to each one by its position in the prompt, for example "the woman from the first image holds the bag from the second image". The limit depends on the model: Seedance 2.5 takes up to 30, Wan 3.0 takes up to 10, Seedance 2.0 takes up to 9, Seedance 2.0 Mini takes up to 9, Veo 3.1 Fast takes up to 3 and Veo 3.1 Lite takes up to 3. On the Seedance models, send frames or references in one request, not both.

This 8 second 720p Veo 3.1 Fast request with sound costs $0.80:

Request body
{
  "model": "veo-3.1-fast",
  "input": {
    "prompt": "The man from the first image walks into the bakery from the second image, picks up a loaf and smiles at the camera. Bell over the door, quiet chatter.",
    "image_urls": [
      "https://example.com/man.jpg",
      "https://example.com/bakery.jpg"
    ],
    "resolution": "720p",
    "duration": 8,
    "aspect_ratio": "16:9",
    "audio": true
  },
  "max_cost_usd": 1.5
}

Video to video

Video to video starts from a clip you already have. The source guides the motion and timing, and the prompt describes what should change: a new style, a new setting, or different details. It suits restyling live footage, reworking an earlier generation, or keeping a performance while changing the look.

Among the models in this guide, Seedance 2.5, Kling 3.0 Omni and Wan 3.0 list video to video, and Kling 3.0 Motion Control works from a source video too. The inputs for a source clip vary by model, so check the model's page before you build on it.

Jobs with a video input are priced differently on some models. On Seedance 2.5, the billed seconds are the output plus the input clip, at a lower with video input rate: a 10 second 720p clip made from a 10 second source costs $2.40, against $2.00 for the same clip from a prompt. Kling 3.0 Omni lists its own rate for jobs with a video input, $0.13 per second at 720p.

Which models support which mode

From the Revana catalogue in October 2026:

Generation modes supported by each model
ModelTextImageFirst and lastReferencesVideo
Seedance 2.5yesyesyesyesyes
Seedance 2.0yesyesyesyesno
Seedance 2.0 Miniyesyesyesyesno
Veo 3.1yesyesyesnono
Veo 3.1 Fastyesyesyesyesno
Veo 3.1 Liteyesyesyesyesno
Kling 3.0yesyesyesnono
Kling 3.0 Omniyesyesyesyesyes
Wan 3.0yesyesyesyesyes
Hailuo 2.3yesyesnonono
Grok Imagine Video 1.5yesyesyesyesno

Does the mode change the price?

Mostly not. Video models are billed by output seconds, resolution and, on some models, sound. A 5 second 720p Seedance 2.0 clip costs $0.75 whether it starts from a prompt or from an image, and adding an end frame or reference images does not change the catalogue price. The exception is video input, covered above.

Each job's price is held from your prepaid balance when you submit it and charged only if the job succeeds. The pricing page lists every rate.

How to choose a mode

  • No assets yet: start with text to video, or make a still with an image model and animate it.
  • The look must be exact: image to video, from a frame you have approved.
  • The ending matters: first and last frames.
  • The same character or product in many shots: reference images.
  • You already have footage: video to video.

A field or value a model does not support is rejected with a 422 before anything is charged, so a wrong mode costs nothing. Full field reference: the docs.

Ready to try them? Get an API key and send your first request.

Frequently asked questions

What is the difference between text to video and image to video?

Text to video works from a prompt alone, so the model invents everything in the shot. Image to video uses your image as the first frame, so the look is fixed and the prompt only describes the motion.

Does image to video cost more than text to video?

Not on the catalogue prices. Video models are billed by output seconds, resolution and, on some models, sound. A 5 second 720p Seedance 2.0 clip costs $0.75 either way in October 2026.

What are first and last frames?

You send a start image as image_url and an end image as end_image_url, and the model generates the motion between them. It is useful for transitions, reveals and loops.

How many reference images can I send?

It depends on the model: Seedance 2.5 up to 30, Wan 3.0 up to 10, Seedance 2.0 up to 9, Seedance 2.0 Mini up to 9, Veo 3.1 Fast up to 3 and Veo 3.1 Lite up to 3.

Can I combine a start frame with reference images?

Not on the Seedance models: send frames or references in one request, not both.

Which models support video to video?

Among the main models, Seedance 2.5, Kling 3.0 Omni and Wan 3.0 list video to video, as does Kling 3.0 Motion Control. The models page lists the tasks for every model.

Try every mode with one key

Text, image, frame and reference jobs all use the same request on Revana. Prepaid credit from $10.