POST
/generate/i2v
202 AcceptedAnimate 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.