# OpenRouter Video API — Alibaba: HappyHorse 1.1 (alibaba/happyhorse-1.1) Guide for generating videos with `alibaba/happyhorse-1.1` through OpenRouter's Video API. Docs: https://openrouter.ai/docs/guides/overview/multimodal/video-generation Model page: https://openrouter.ai/alibaba/happyhorse-1.1 Model discovery API: https://openrouter.ai/api/v1/videos/models Create an API key: https://openrouter.ai/settings/keys ## Endpoint POST https://openrouter.ai/api/v1/videos Headers: - Authorization: Bearer $OPENROUTER_API_KEY - Content-Type: application/json Generation is asynchronous: the submit call returns a job, which is polled until it finishes. The finished video is downloaded from the job, not returned inline. ## Request fields (alibaba/happyhorse-1.1) - model: string (required) — `"alibaba/happyhorse-1.1"` - prompt: string (optional when frame_images is set, otherwise required) — text description of the desired video - duration: 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 (optional) — length of the video in seconds - size: "1280x720" | "720x1280" | "720x720" | "960x720" | "720x960" | "1680x720" | "720x1680" | "1920x1080" | "1080x1920" | "1080x1080" | "1440x1080" | "1080x1440" | "2520x1080" | "1080x2520" (optional) — exact pixel dimensions, as WIDTHxHEIGHT - resolution: "720p" | "1080p" (optional) — resolution tier; interchangeable with size when paired with aspect_ratio - aspect_ratio: "16:9" | "9:16" | "1:1" | "4:3" | "3:4" | "21:9" | "9:21" (optional) — aspect ratio of the generated video - frame_images: array of frame references (optional) — images to condition the named frame on, as `{ "type": "image_url", "image_url": { "url": "…" }, "frame_type": "first_frame" }` entries; frame_type is one of "first_frame", and the url is an https URL or a base64 data URL - input_references: array of reference assets (optional) — images to guide the generation, as `{ "type": "image_url", "image_url": { "url": "…" } }` entries - seed: integer (optional) — sample deterministically; determinism is not guaranteed for every provider - callback_url: string (optional) — https URL notified by webhook when the job finishes, instead of polling These are the generation parameters this model accepts between its providers; an unlisted value is rejected, and a listed one can still be refused by whichever provider serves the call. `provider` (routing preferences) is accepted on every request. ## Response The submit call returns `202` with the job: ```json { "id": "job-abc123", "generation_id": "gen-xyz789", "polling_url": "/api/v1/videos/job-abc123", "status": "pending" } ``` Poll `GET https://openrouter.ai/api/v1/videos/{id}` with the same Authorization header while `status` is `pending` or `in_progress`, and stop once it is `completed`, `failed`, `cancelled`, or `expired`: ```json { "id": "job-abc123", "status": "completed", "unsigned_urls": ["https://storage.example.com/video.mp4"], "usage": { "cost": 0.5 } } ``` Download the bytes from `GET https://openrouter.ai/api/v1/videos/{id}/content` (`?index=N` selects a clip when the job produced more than one). `usage.cost` is the USD charge for the call. ## Examples ### Text to Video ```bash curl -X POST https://openrouter.ai/api/v1/videos \ -H "Authorization: Bearer $OPENROUTER_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "alibaba/happyhorse-1.1", "prompt": "a slow cinematic push-in on a glowing neon sign that reads \"OpenRouter\" in the window of a cozy coffee shop on a rainy night, rain streaking down the glass, reflections rippling on wet pavement", "duration": 5 }' ``` ## Errors Failures return `{"error": {"code": , "message": }}` with the HTTP status: - 400 — malformed body, a parameter or value this model does not accept, or input blocked by the provider's content moderation - 401 — missing or invalid API key - 402 — insufficient credits - 403 — spend limit reached, key disabled, or the model or provider is blocked for your account - 404 — unknown model or job, or no provider can serve the request - 429 — rate limited; retry with backoff - 500 — the job could not be submitted - 502 — the generation failed upstream; failed generations are not billed A job that fails after acceptance reports `status: "failed"` with an `error` message rather than an HTTP error, since the submit call already succeeded. --- Canonical version of this document: https://openrouter.ai/alibaba/happyhorse-1.1/llms.txt