ESC
Type to search across all documentation
POST

/generate/i2v

202 Accepted

Animate a source image into a short video using Wan2.2 image-to-video. Provide the image as a base64-encoded string or a publicly accessible URL. The job is queued immediately — use GET /status/{uuid} to track progress.

Endpoint

POST  https://coals.ai/api/v1/magicoal/generate/i2v

Request Body Parameters

Parameter Type Required Description
image string required Source image as a base64-encoded string (with or without data URI prefix) or a publicly accessible HTTPS URL. JPEG, PNG, and WebP are supported. Recommended resolution: 480×832 or 832×480.
prompt string optional Motion description to guide animation. Max 2000 characters. Describe movement, camera motion, or action — not the image subject itself.
num_frames integer optional Number of frames to generate. Range: 17–161. Defaults to 81 (approx. 5 seconds at 16 fps). Use 161 for ~10 seconds.
guidance_scale number optional Classifier-free guidance scale. Range: 1.0–10.0. Default: 3.5. Higher values follow the prompt more strictly; lower values produce more natural motion.
seed integer optional Random seed for reproducibility. Omit for a random seed on each generation.

Frame count guide: 81 frames = ~5 seconds  |  161 frames = ~10 seconds (rendered at 16 fps). Frame counts must be odd numbers in the 17–161 range.

Request Body

{
  "image": "https://example.com/photo.jpg",
  "prompt": "gentle wind blowing through the trees, slow cinematic pan",
  "num_frames": 81,
  "guidance_scale": 3.5,
  "seed": 42
}

Response — 202 Accepted

{
  "success": true,
  "data": {
    "uuid": "3f8a2d1b-4c9e-4b7f-8d2a-1f3c5e7a9b0d",
    "type": "i2v",
    "status": "queued",
    "credits_charged": 50.0
  }
}
Field Description
uuid Unique job identifier. Pass this to GET /status/{uuid} to track progress.
type Always "i2v" for image-to-video jobs.
status Initial status is "queued". Will progress to "generating" then "completed" or "failed".
credits_charged Credits deducted upfront. Refunded automatically if generation fails.
curl -X POST https://coals.ai/api/v1/magicoal/generate/i2v \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "image": "https://example.com/photo.jpg",
    "prompt": "gentle wind blowing through the trees, slow cinematic pan",
    "num_frames": 81,
    "guidance_scale": 3.5
}'
// Using Guzzle
$response = $client->post('https://coals.ai/api/v1/magicoal/generate/i2v', [
  'headers' => ['Authorization' => 'Bearer YOUR_API_KEY'],
  'json' => [
    "image" => "https =>//example.com/photo.jpg",
    "prompt" => "gentle wind blowing through the trees, slow cinematic pan",
    "num_frames" => 81,
    "guidance_scale" => 3.5
]
]);
$data = json_decode($response->getBody(), true);
# Using requests
import requests

response = requests.post(
  "https://coals.ai/api/v1/magicoal/generate/i2v",
  headers={"Authorization": "Bearer YOUR_API_KEY"},
  json={
    "image": "https://example.com/photo.jpg",
    "prompt": "gentle wind blowing through the trees, slow cinematic pan",
    "num_frames": 81,
    "guidance_scale": 3.5
}
)
data = response.json()
# Using net/http
require "net/http"
require "json"

uri = URI("https://coals.ai/api/v1/magicoal/generate/i2v")
req = Net::HTTP::Post.new(uri)
req["Authorization"] = "Bearer YOUR_API_KEY"
req["Content-Type"] = "application/json"
req.body = '{
    "image": "https://example.com/photo.jpg",
    "prompt": "gentle wind blowing through the trees, slow cinematic pan",
    "num_frames": 81,
    "guidance_scale": 3.5
}'

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
data = JSON.parse(res.body)
// Using fetch (Node 18+)
const response = await fetch("https://coals.ai/api/v1/magicoal/generate/i2v", {
  method: "POST",
  headers: {
    "Authorization": "Bearer YOUR_API_KEY",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    "image": "https://example.com/photo.jpg",
    "prompt": "gentle wind blowing through the trees, slow cinematic pan",
    "num_frames": 81,
    "guidance_scale": 3.5
})
});
const data = await response.json();

For best results, use images with clear subjects and minimal motion blur. Portrait-oriented images (480×832) and landscape-oriented images (832×480) both work well. Avoid very small images — the model performs best above 480px on the short edge.