alibaba/happy-horse/image-to-video
Input
Hint: Drag and drop image files from your computer, images from web pages, paste from clipboard (Ctrl/Cmd+V), or provide a URL. Accepted file types: jpg, jpeg, png, webp, gif, avif

Customize your input with more control.
Result
Waiting for your input...
What would you like to do next?
For every second of 720p video you generated, you will be charged $0.14/second. For 1080p video you will be charged $0.28/second.
Logs
Run Happy Horse 1.0: Image to Video API
Animate any still image into a 1080p video with synchronized native audio, Foley sounds, and multilingual lip-sync. No GPU management required.
Model ID: `alibaba/happy-horse/image-to-video`
Provider: fal.ai
Commercial rights: Full commercial rights on all outputs
Specifications
| Property | Value |
|---|---|
| Resolution | 720p, 1080p |
| Duration | 3–15 seconds |
| Aspect ratios | 16:9, 9:16, 1:1, 4:3, 3:4 |
| Input image min size | 400px on shortest side (720p+ recommended) |
| Input image max size | 10 MB |
| Input formats | JPEG, JPG, PNG, BMP, WEBP |
| Prompt length | Up to 2,500 characters |
| Lip-sync languages | English, Mandarin, Cantonese, Japanese, Korean, German, French |
Pricing
| Resolution | Price |
|---|---|
| 720p | $0.14 / second |
| 1080p | $0.28 / second |
A 10-second clip at 1080p costs $2.80.
Quickstart
Install
JavaScript:
bashnpm install @fal-ai/client
Python:
bashpip install fal-client
Set your API key
bashexport FAL_KEY="YOUR_API_KEY"
Submit a request
JavaScript:
jsimport { fal } from "@fal-ai/client"; const result = await fal.subscribe("alibaba/happy-horse/image-to-video", { input: { image_url: "https://example.com/your-image.jpg", prompt: "Bring the scene to life with natural motion and sound.", resolution: "1080p", duration: 5, }, logs: true, onQueueUpdate: (update) => { if (update.status === "IN_PROGRESS") { update.logs.map((log) => log.message).forEach(console.log); } }, }); console.log(result.data.video.url);
Python:
pythonimport fal_client def on_queue_update(update): if isinstance(update, fal_client.InProgress): for log in update.logs: print(log["message"]) result = fal_client.subscribe( "alibaba/happy-horse/image-to-video", arguments={ "image_url": "https://example.com/your-image.jpg", "prompt": "Bring the scene to life with natural motion and sound.", "resolution": "1080p", "duration": 5, }, with_logs=True, on_queue_update=on_queue_update, ) print(result["video"]["url"])
Note: The
`image_url`is used as the first frame. Use a publicly accessible URL, or upload via the client storage helpers below.
Input parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
`image_url` | string | required | First-frame image URL. Min 400px shortest side, max 10 MB. JPEG, PNG, BMP, or WEBP. |
`prompt` | string | — | Text description guiding the animation. Max 2,500 characters. |
`resolution` | `"720p"` | `"1080p"` | `"1080p"` | Output video resolution. |
`duration` | integer (3–15) | `5` | Clip length in seconds. |
`seed` | integer (0–2,147,483,647) | — | Set for reproducible outputs. |
`enable_safety_checker` | boolean | `true` | Content moderation on input and output. |
Output
json{ "video": { "url": "https://...", "content_type": "video/mp4", "file_name": "output.mp4", "file_size": 4404019, "width": 1920, "height": 1080, "fps": 24, "duration": 5.0, "num_frames": 120 }, "seed": 1234567 }
Queue API (long-running requests)
For clips longer than a few seconds, use the queue API to avoid blocking.
JavaScript:
jsimport { fal } from "@fal-ai/client"; // Submit const { request_id } = await fal.queue.submit("alibaba/happy-horse/image-to-video", { input: { image_url: "https://example.com/your-image.jpg", duration: 15, resolution: "1080p", }, webhookUrl: "https://your-server.com/webhook", }); // Poll status const status = await fal.queue.status("alibaba/happy-horse/image-to-video", { requestId: request_id, logs: true, }); // Fetch result once complete const result = await fal.queue.result("alibaba/happy-horse/image-to-video", { requestId: request_id, }); console.log(result.data.video.url);
Python:
pythonimport fal_client # Submit handler = fal_client.submit( "alibaba/happy-horse/image-to-video", arguments={ "image_url": "https://example.com/your-image.jpg", "duration": 15, "resolution": "1080p", }, webhook_url="https://your-server.com/webhook", ) request_id = handler.request_id # Poll status status = fal_client.status("alibaba/happy-horse/image-to-video", request_id, with_logs=True) # Fetch result once complete result = fal_client.result("alibaba/happy-horse/image-to-video", request_id) print(result["video"]["url"])
Uploading files
If your image isn't already hosted, upload it via the client before submitting.
JavaScript:
jsimport { fal } from "@fal-ai/client"; const file = new File([imageBuffer], "frame.jpg", { type: "image/jpeg" }); const url = await fal.storage.upload(file); // Use `url` as image_url in your request
Python:
pythonimport fal_client url = fal_client.upload_file("path/to/your/image.jpg") # Use `url` as image_url in your request
Client-side usage
Security: Never expose your
`FAL_KEY`in browser or mobile code. Route requests through a server-side proxy: set`FAL_KEY`as a server environment variable and have your frontend call your own backend endpoint, which forwards the request to fal.