Skip to content
繁體中文

Generate Video from an Image ​

Complete Generate Video Overview first, then add a local reference image. This page uses the same Sora-compatible route and model.

API Calls in Multiple Languages ​

See language setup. Set API_KEY and replace model, file URL, and ID placeholders first. Each version displays the raw response to the same request.

These examples submit a task only. Keep the returned id for subsequent queries. Place reference.png in the working directory; its format and dimensions must satisfy the selected model.

bash
curl --fail-with-body --silent --show-error --max-time 180 \
  --request POST \
  --url "https://api.tokatlas.ai/v1/videos" \
  --header "Authorization: Bearer $API_KEY" \
  --form model=YOUR_ENABLED_SORA_MODEL_ID \
  --form 'prompt=A ceramic cup on a table, steam rising, slow camera movement' \
  --form seconds=4 \
  --form size=720x1280 \
  --form 'input_reference=@reference.png;type=image/png'
python
import os
from pathlib import Path
import requests

headers = {
    'Authorization': 'Bearer ' + os.environ["API_KEY"],
}
files = {'model': (None, 'YOUR_ENABLED_SORA_MODEL_ID'),
 'prompt': (None, 'A ceramic cup on a table, steam rising, slow camera movement'),
 'seconds': (None, '4'),
 'size': (None, '720x1280')}
files['input_reference'] = ('reference.png', Path('reference.png').read_bytes(), 'image/png')
response = requests.request(
    'POST', 'https://api.tokatlas.ai/v1/videos', headers=headers,
    files=files,
    timeout=180,
)
response.raise_for_status()
print(response.text)
js
import { readFile } from "node:fs/promises";
if (!process.env.API_KEY) throw new Error("Set API_KEY first.");
const form = new FormData();
form.append("model", "YOUR_ENABLED_SORA_MODEL_ID");
form.append("prompt", "A ceramic cup on a table, steam rising, slow camera movement");
form.append("seconds", "4");
form.append("size", "720x1280");
form.append("input_reference", new Blob([await readFile("reference.png")], { type: "image/png" }), "reference.png");
const response = await fetch("https://api.tokatlas.ai/v1/videos", {
  method: "POST",
  headers: {
    "Authorization": "Bearer " + process.env.API_KEY,
  },
  body: form,
  signal: AbortSignal.timeout(180_000),
});
if (!response.ok) {
  throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}
console.log(await response.text());
java
import java.net.URI;
import java.net.http.*;
import java.time.Duration;
import java.nio.file.*;
import java.nio.charset.StandardCharsets;
import java.io.ByteArrayOutputStream;

public class Example {
    public static void main(String[] args) throws Exception {
        String apiKey = System.getenv("API_KEY");
        if (apiKey == null || apiKey.isBlank()) {
            throw new IllegalArgumentException("Set API_KEY first.");
        }
        String boundary = "TokatlasExampleBoundary";
        String payload =
            "--TokatlasExampleBoundary\r\nContent-Disposition: form-data; name=\"model\"\r\n\r\nYOUR_ENABLED_SORA_MODEL_ID\r\n" +
            "--TokatlasExampleBoundary\r\nContent-Disposition: form-data; name=\"prompt\"\r\n\r\nA ceramic cup on a table, steam rising, slow camera movement\r\n" +
            "--TokatlasExampleBoundary\r\nContent-Disposition: form-data; name=\"seconds\"\r\n\r\n4\r\n" +
            "--TokatlasExampleBoundary\r\nContent-Disposition: form-data; name=\"size\"\r\n\r\n720x1280\r\n";
        ByteArrayOutputStream multipart = new ByteArrayOutputStream();
        multipart.write(payload.getBytes(StandardCharsets.UTF_8));
        multipart.write(("--" + boundary + "\r\n"
            + "Content-Disposition: form-data; name=\"input_reference\"; filename=\"reference.png\"\r\n"
            + "Content-Type: image/png\r\n\r\n").getBytes(StandardCharsets.UTF_8));
        multipart.write(Files.readAllBytes(Path.of("reference.png")));
        multipart.write(("\r\n--" + boundary + "--\r\n").getBytes(StandardCharsets.UTF_8));
        HttpClient client = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(30)).build();
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create("https://api.tokatlas.ai/v1/videos"))
            .timeout(Duration.ofSeconds(180))
            .header("Authorization", "Bearer " + apiKey)
            .header("Content-Type", "multipart/form-data; boundary=" + boundary)
            .method("POST", HttpRequest.BodyPublishers.ofByteArray(multipart.toByteArray()))
            .build();
        HttpResponse<String> response = client.send(
            request, HttpResponse.BodyHandlers.ofString());
        if (response.statusCode() < 200 || response.statusCode() >= 300) {
            throw new IllegalStateException("HTTP " + response.statusCode() + ": "
                + response.body());
        }
        System.out.println(response.body());
    }
}

Steps ​

  1. Prepare reference.png with a format and dimensions accepted by the selected model. The example output is 720×1280.
  2. Place it beside generate_video.py.
  3. Preserve the previous task ID by renaming video-task.txt, allowing a new task to be submitted.
  4. Replace the files argument in the original requests.post call with the following fields.
  5. Run the original script; it polls and downloads to video.mp4 as before.
python
files = {
    "model": (None, os.environ["VIDEO_MODEL_ID"]),
    "prompt": (None, "Slow camera movement toward the subject. Preserve its appearance."),
    "seconds": (None, "4"),
    "size": (None, "720x1280"),
    "input_reference": ("reference.png", Path("reference.png").read_bytes(), "image/png"),
}

This is an argument fragment: define the dictionary before the POST call and pass files=files to it. Let requests generate the multipart Content-Type and boundary. Do not reuse image-generation image_urls.

If rejected, check image format, dimensions, and model reference-image support. For summaries or questions about an existing video, use a video-understanding model rather than the generation endpoint.