Kolbo.AIKolbo.AI Docs
Developer API

Video-to-Video

Restyle and transform existing videos using AI with the Kolbo API.

Restyle and transform existing videos using AI. Provide a source video and a text prompt describing the desired transformation, and Kolbo generates a new video with the applied style or changes.

Smart Select (recommended): Omit the model field and Kolbo automatically picks the best model for your prompt. This is the default and recommended approach for most use cases.

Model identifiers are Kolbo-specific. Never hardcode model identifiers — always fetch the current list from GET /api/v1/models?type=video_from_video first. Models may be added, renamed, or retired at any time.

Endpoint

POST /api/v1/generate/video-from-video

Request Body

Accepts multipart/form-data (for file uploads) or application/json (for URL-based inputs).

FieldTypeRequiredDescription
promptstringNoDescribe the desired transformation or style. Most models require a prompt — only a few specialized models allow omitting it.
video_urlstringNoURL of the input video
filesfile(s)NoVideo file upload (multipart, max 100 MB)
modelstringNoModel identifier from GET /api/v1/models?type=video_from_video (default: auto-select)
aspect_ratiostringNo"16:9", "9:16", "1:1" (default: "16:9")
durationnumberNoOutput duration in seconds
enhance_promptbooleanNoEnhance prompt for better results (default: true)

You must provide either video_url or a files upload — not both.

Examples

curl -X POST https://api.kolbo.ai/api/v1/generate/video-from-video \
  -H "X-API-Key: kolbo_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Transform into anime style with vibrant colors",
    "video_url": "https://example.com/original-clip.mp4",
    "aspect_ratio": "16:9"
  }'

cURL with File Upload

curl -X POST https://api.kolbo.ai/api/v1/generate/video-from-video \
  -H "X-API-Key: kolbo_live_YOUR_API_KEY" \
  -F "prompt=Transform into anime style with vibrant colors" \
  -F "[email protected]"

With Specific Model

To choose a specific model, first fetch identifiers from GET /api/v1/models?type=video_from_video, then pass the identifier value:

curl -X POST https://api.kolbo.ai/api/v1/generate/video-from-video \
  -H "X-API-Key: kolbo_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Transform into anime style with vibrant colors",
    "video_url": "https://example.com/original-clip.mp4",
    "model": "your-model-identifier"
  }'

Model identifiers come from GET /api/v1/models?type=video_from_video. Always fetch the latest list rather than hardcoding identifiers, as models may change over time.

JavaScript

const API_KEY = "kolbo_live_YOUR_API_KEY";

// Fetch available video-to-video models
async function initModels() {
  const res = await fetch("https://api.kolbo.ai/api/v1/models?type=video_from_video", {
    headers: { "X-API-Key": API_KEY },
  });
  const data = await res.json();
  console.log("Available models:", data.models.map((m) => m.identifier));
}

async function main() {
  await initModels();

  // Using URL (Smart Select)
  const response = await fetch("https://api.kolbo.ai/api/v1/generate/video-from-video", {
    method: "POST",
    headers: {
      "X-API-Key": API_KEY,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      prompt: "Transform into anime style with vibrant colors",
      video_url: "https://example.com/original-clip.mp4",
      aspect_ratio: "16:9",
    }),
  });

  const data = await response.json();
  console.log("Generation ID:", data.generation_id);
  console.log("Poll URL:", data.poll_url);

  // Poll for completion
  const pollForResult = async (generationId) => {
    while (true) {
      await new Promise((r) => setTimeout(r, data.poll_interval_hint * 1000));
      const status = await fetch(
        `https://api.kolbo.ai/api/v1/generate/${generationId}/status`,
        { headers: { "X-API-Key": API_KEY } }
      ).then((r) => r.json());

      console.log("State:", status.state, "Progress:", status.progress);

      if (status.state === "completed") {
        console.log("Video URL:", status.result.urls[0]);
        return status;
      }
      if (status.state === "failed") {
        console.error("Generation failed:", status.error);
        return status;
      }
    }
  };

  await pollForResult(data.generation_id);
}

main();

Python

import requests
import time

API_KEY = "kolbo_live_YOUR_API_KEY"
BASE_URL = "https://api.kolbo.ai/api"
HEADERS = {"X-API-Key": API_KEY}

# Fetch available video-to-video models
models_res = requests.get(
    f"{BASE_URL}/v1/models",
    headers=HEADERS,
    params={"type": "video_from_video"},
)
print("Available models:", [m["identifier"] for m in models_res.json()["models"]])

# --- Option A: Using URL (Smart Select) ---
response = requests.post(
    f"{BASE_URL}/v1/generate/video-from-video",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={
        "prompt": "Transform into anime style with vibrant colors",
        "video_url": "https://example.com/original-clip.mp4",
        "aspect_ratio": "16:9",
    },
)

data = response.json()
print("Generation ID:", data["generation_id"])

# --- Option B: Using file upload ---
# with open("original-clip.mp4", "rb") as vid:
#     response = requests.post(
#         f"{BASE_URL}/v1/generate/video-from-video",
#         headers=HEADERS,
#         files={"files": vid},
#         data={"prompt": "Transform into anime style with vibrant colors"},
#     )
#     data = response.json()

# Poll for completion
generation_id = data["generation_id"]
poll_interval = data.get("poll_interval_hint", 8)

while True:
    time.sleep(poll_interval)
    status = requests.get(
        f"{BASE_URL}/v1/generate/{generation_id}/status",
        headers=HEADERS,
    ).json()

    print(f"State: {status['state']}  Progress: {status.get('progress', 0)}%")

    if status["state"] == "completed":
        print("Video URL:", status["result"]["urls"][0])
        break
    if status["state"] == "failed":
        print("Error:", status.get("error"))
        break

Response

Generation Started

{
  "success": true,
  "generation_id": "v2v_abc123",
  "type": "video_from_video",
  "model": "auto",
  "credits_charged": 50,
  "poll_url": "/api/v1/generate/v2v_abc123/status",
  "poll_interval_hint": 8
}

Completed Status

{
  "success": true,
  "generation_id": "v2v_abc123",
  "type": "video_from_video",
  "state": "completed",
  "progress": 100,
  "result": {
    "urls": ["https://cdn.kolbo.ai/videos/..."],
    "thumbnail_url": "https://cdn.kolbo.ai/thumbs/...",
    "duration": 5,
    "aspect_ratio": "16:9",
    "prompt_used": "Transform into anime style with vibrant colors",
    "model": "auto",
    "created_at": "2026-04-12T10:00:00.000Z"
  }
}

Tips

  • Use Smart Select (the default). Omit the model field and Kolbo picks the best model for your prompt. This is the simplest and most future-proof approach.
  • Video-to-video generation typically takes 2-5 minutes depending on the model and duration.
  • Be descriptive in your prompt — specify the target style, mood, and any visual changes you want applied.
  • When using file uploads, the total request size limit is 100 MB per file.
  • Credits are charged per second: model.credit x duration.
  • Use poll_interval_hint from the initial response to set your polling interval.
  • Check supported_durations and supported_aspect_ratios on each model via the Models endpoint before requesting specific values.
  • Not all models support all durations or aspect ratios — if unsupported, the API may select the closest match.