happyhorse-1.0
Alibaba Cloud Bailian Happy Horse 1.0 — one async endpoint that auto-routes text-to-video, image-to-video, reference-to-video, and video edit by request shape.
Alibaba Cloud Bailian Happy Horse 1.0 — a single async video endpoint that auto-routes between T2V / I2V / R2V / EDIT based on which media field your request carries. 720P or 1080P, 3–15 second outputs, billed only by resolution × duration regardless of mode. See current pricing on the model page.
Quick example
curl https://reapi.ai/api/v1/videos/generations \
-H "Authorization: Bearer rk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"model": "happyhorse-1.0",
"prompt": "A coastal road at sunset, slow-motion camera push-in, cinematic feel",
"resolution": "1080P",
"size": "16:9",
"duration": 5,
"seed": 42
}'import requests
resp = requests.post(
"https://reapi.ai/api/v1/videos/generations",
headers={
"Authorization": "Bearer rk_live_xxx",
"Content-Type": "application/json",
},
json={
"model": "happyhorse-1.0",
"prompt": "A coastal road at sunset, slow-motion camera push-in",
"resolution": "1080P",
"size": "16:9",
"duration": 5,
"seed": 42,
},
timeout=30,
)
print(resp.json())const r = await fetch("https://reapi.ai/api/v1/videos/generations", {
method: "POST",
headers: {
Authorization: "Bearer rk_live_xxx",
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "happyhorse-1.0",
prompt: "A coastal road at sunset, slow-motion camera push-in",
resolution: "1080P",
size: "16:9",
duration: 5,
seed: 42,
}),
});
console.log(await r.json());package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
func main() {
body, _ := json.Marshal(map[string]any{
"model": "happyhorse-1.0",
"prompt": "A coastal road at sunset, slow-motion camera push-in",
"resolution": "1080P",
"size": "16:9",
"duration": 5,
"seed": 42,
})
req, _ := http.NewRequest("POST",
"https://reapi.ai/api/v1/videos/generations", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer rk_live_xxx")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body)
fmt.Println(string(out))
}Submit response
{
"id": "task_018f5a3a1b6e7d9f8c2b4d6e8f0a2c4e",
"model": "happyhorse-1.0",
"status": "processing",
"created_at": 1735000000
}Poll GET /api/v1/tasks/{id} (see the Tasks reference) until
status === "completed". The completed payload's output.video_urls
holds the generated MP4 URLs, valid for 7 days.
Authentication
Every call needs a Bearer token. Generate keys at reapi.ai/settings/apikeys.
Authorization: Bearer YOUR_API_KEYKeys carry the active workspace's billing scope — there is no separate project header.
Endpoint
POST /api/v1/videos/generations
GET /api/v1/tasks/{id}Submission is async. The POST returns immediately with a task_id; the
task endpoint returns the same envelope until completion. Polling does
not consume credits.
Mode routing
happyhorse-1.0 is one model id that picks its mode from which media
fields you set:
| Fields you send | Mode | What it does |
|---|---|---|
prompt only | T2V | Generate from text |
prompt + first_frame_image | I2V | Animate starting from a still frame |
prompt + image_urls (1–9) | R2V | Compose a new scene from reference images |
video_url (+ prompt, optional image_urls ≤ 5 / audio_setting) | EDIT | Restyle / rewrite an existing clip |
Resolution priority when multiple fields are set:
video_url > first_frame_image > image_urls > prompt-only.
Mutex rule. The three media fields (first_frame_image, image_urls,
video_url) are mutually exclusive in pairs. The single legal pairing
is video_url + image_urls (EDIT with style references). Any other
combination is rejected with 400 first_frame_image and image_urls cannot be combined or 400 first_frame_image and video_url cannot be combined (code 20003).
Request body
model — required
string. Always "happyhorse-1.0".
prompt — string
Up to 2,500 characters. Required in T2V / R2V / EDIT; optional in I2V (but recommended — phrasing the camera move and motion improves output quality).
Failure modes.
- Missing in non-I2V →
400 prompt is required in T2V / R2V / EDIT modes(code20002). - Longer than 2,500 chars →
400 prompt must be at most 2500 characters(code20007).
first_frame_image — string
Public HTTP(S) URL pointing at the still you want animated. Triggers
I2V when set. Mutually exclusive with image_urls and video_url.
Recommended source asset: JPEG / PNG / BMP / WEBP, short side ≥ 300px,
ratio between 1:2.5 and 2.5:1, ≤ 10MB. The upstream model
also enforces these — the gateway forwards the URL untouched, so
non-compliant assets surface as a delayed provider_failed rather than
an immediate 400. Validate before submitting if the source isn't yours.
No data: URIs. reapi rejects base64 inputs platform-wide. Upload to
public storage (your own CDN, S3, R2…) and pass the URL.
image_urls — string[]
Array of public HTTP(S) URLs.
- R2V (no
video_url): 1–9 entries. The upstream composes a fresh scene that incorporates the supplied subjects / styles. - EDIT (
video_urlset): 0–5 entries acting as style references on top of the source video. Sending more than 5 is rejected with400 image_urls allows at most 5 entries in EDIT mode.
Same per-asset constraints as first_frame_image (short side ≥ 720px is
recommended for R2V, short / long ≥ 0.4, ≤ 10MB each). T2V and I2V
requests are rejected if image_urls is present — the upstream
wouldn't consume it, and silently dropping it would make billing
surprising. Mutually exclusive with first_frame_image.
video_url — string
Public HTTP(S) URL of the source clip. Triggers EDIT mode. Combinable
with image_urls (≤ 5) and audio_setting. Mutually exclusive with
first_frame_image.
Source asset shape (enforced upstream): MP4 / MOV (H.264 recommended),
duration 3–60 seconds, ≥ 480p / short side ≥ 360, ratio between 1:8
and 8:1, > 8 fps, ≤ 100MB.
Length caps the output. If the source video runs longer than 15s,
the upstream truncates from second 0 to second 15 before processing.
The output clip's length matches the source's processed length —
trim the input yourself if you need a different segment or a tighter
total. In EDIT mode the duration parameter is ignored for both
generation and billing; reapi probes the source clip server-side and
charges
(ceil(probed_seconds) + min(ceil(probed_seconds), 15)) × per_second_usd
— input and capped output are both billable. See the duration field
below.
audio_setting — string, default "auto"
Only valid in EDIT mode. Sending it without video_url is rejected with
400 audio_setting requires video_url (EDIT mode only).
| Value | Behavior |
|---|---|
"auto" | Generate a fresh audio track (default) |
"origin" | Keep the source video's original audio |
resolution — string, default "1080P"
"720P" or "1080P". Drives pricing — every other parameter is free
across the two tiers. Lowercase forms ("720p", "1080p") are accepted
and normalized for symmetry with seedance; the upstream sees the
canonical uppercase form.
size — string, default "16:9"
Output ratio for T2V and R2V only. One of 16:9 / 9:16 /
1:1 / 4:3 / 3:4.
In I2V and EDIT, the upstream derives the output ratio from the
input media (first-frame image / source video) and ignores size. The
gateway still accepts the field — it's just inert.
duration — integer, default 5
Output length in seconds for T2V / I2V / R2V. Any integer in
[3, 15]. Drives pricing linearly:
ceil(per_second_usd × duration × 1000) credits (1 credit = $0.001).
EDIT mode ignores duration for billing. When video_url is set,
reapi probes the source video's actual length on the server (ffmpeg
metadata) and bills both the input clip AND the (capped) output:
billable = ceil(probed_seconds) + min(ceil(probed_seconds), 15)
bill_usd = billable × per_second_usdA 5s source bills 10s; a 60s source bills 75s (60 + 15-cap output).
Whatever you send in duration is ignored for cost. The upstream also
ignores duration here (output length tracks the source). Probe
failures return 400 PRICING_UNAVAILABLE (code 30002) with no charge.
watermark — boolean, default false
Adds the platform watermark to the generated clip when true.
seed — integer
Reproducibility hint. Range [0, 2147483647]. Same seed plus an
otherwise identical request returns a similar (not bit-for-bit
identical) result. Omit for full randomness.
Response envelope
Submit and poll share the same shape — only status and output fill in
over time.
{
"id": "task_018f5a3a1b6e7d9f8c2b4d6e8f0a2c4e",
"model": "happyhorse-1.0",
"status": "completed",
"created_at": 1735000000,
"output": {
"video_urls": ["https://cdn.reapi.ai/media/tasks/018f5a3a1b6e7d9f8c2b4d6e8f0a2c4e/0.mp4"]
},
"error": null
}| Field | Type | Notes |
|---|---|---|
id | string | Task identifier — keep it for polling and audit |
model | string | Echo of the submitted model |
status | string | processing / completed / failed |
created_at | integer | Submission unix timestamp |
output | object | null | null until completion. output.video_urls holds MP4s |
error | object | null | Populated on failed — { code, message } |
output.video_urls URLs are valid for 7 days. Re-host to your own
storage if you need them longer.
Validation errors
All cases below return HTTP 400 with code 20003 unless noted. Pattern-match
on code, not message — message strings carry request-specific context
(field names, observed dimensions, etc.) and are not a stable contract.
| Trigger | Code | Message (illustrative) |
|---|---|---|
prompt missing in T2V / R2V / EDIT | 20002 | happyhorse: prompt is required in T2V / R2V / EDIT modes |
prompt longer than 2,500 chars | 20007 | happyhorse: prompt must be at most 2500 characters |
first_frame_image + image_urls together | 20003 | happyhorse: first_frame_image and image_urls cannot be combined |
first_frame_image + video_url together | 20003 | happyhorse: first_frame_image and video_url cannot be combined |
image_urls empty array in R2V | 20003 | happyhorse: image_urls contained no usable URLs |
image_urls > 5 in EDIT | 20003 | happyhorse: image_urls allows at most 5 entries in EDIT mode |
audio_setting set without video_url | 20003 | happyhorse: audio_setting requires video_url (EDIT mode only) |
image_urls carrying a data: URI | 20003 | happyhorse: image_urls must be public http(s) URLs |
video_url carrying a data: URI | 20003 | happyhorse: video_url must be a public http(s) URL |
| EDIT source duration < 3s or > 60s | 20003 | video_url duration X.XXs is out of range (must be 3–60s) |
| EDIT source resolution below 480p (short side < 360) | 20003 | video_url resolution WxH is below the 480p minimum (short side must be ≥ 360px) |
| EDIT source ratio outside 1:8–8:1 | 20003 | video_url aspect ratio WxH is out of range (must be between 1:8 and 8:1) |
| EDIT source video probe fails (network / format) | 30002 | Could not determine source video duration for billing: … |
The full envelope is { "error": { "code", "message", "request_id" } } —
see Errors catalog for the wire format and request_id
correlation tips.
Recipes
T2V — minimum request
{
"model": "happyhorse-1.0",
"prompt": "A little girl walking down the road, cinematic feel"
}T2V — full parameters
{
"model": "happyhorse-1.0",
"prompt": "Sunset coastal road, slow camera push-in, cinematic warm tones",
"resolution": "1080P",
"size": "16:9",
"duration": 8,
"watermark": false,
"seed": 42
}I2V — first-frame animation
{
"model": "happyhorse-1.0",
"prompt": "Bring the scene to life with gentle camera dolly forward",
"first_frame_image": "https://your-cdn.com/first_frame.png",
"resolution": "1080P",
"duration": 5
}R2V — multiple references
{
"model": "happyhorse-1.0",
"prompt": "The protagonist from image 1 runs through image 2's scene then picks up the prop from image 3. 3D cartoon style, smooth motion.",
"image_urls": [
"https://your-cdn.com/img_01.jpg",
"https://your-cdn.com/img_02.png",
"https://your-cdn.com/img_03.jpeg"
],
"resolution": "1080P",
"size": "16:9",
"duration": 5
}EDIT — keep original audio + style reference
{
"model": "happyhorse-1.0",
"prompt": "Repaint the character in a 3D cartoon style, keep the original motion",
"video_url": "https://your-cdn.com/source.mp4",
"image_urls": ["https://your-cdn.com/style_ref.jpg"],
"resolution": "1080P",
"audio_setting": "origin",
"seed": 42
}720P — cost-conscious
{
"model": "happyhorse-1.0",
"prompt": "Waves crashing on a beach at sunset, wide shot",
"resolution": "720P",
"size": "16:9",
"duration": 5
}Choosing a mode
| Need | Send |
|---|---|
| Generate from text | prompt only (T2V) |
| Animate a still | prompt + first_frame_image (I2V) |
| Compose a new scene from reference images | prompt + image_urls 1–9 (R2V) |
| Restyle / rewrite an existing clip | video_url (+ prompt, optional refs ≤ 5, audio_setting) (EDIT) |
| Cut spend in half | Set resolution: "720P" |
Polling pattern
The task endpoint behaves identically to image tasks — the only
difference is the completed output shape (video_urls instead of
image_urls). A pragmatic schedule:
0–5 minutes: poll every 5s
5 min – 1 h: back off gradually toward 1 min
≥ 1 h: cap at 3 min between pollsA typical task completes in a few minutes. The worker's wall-clock cap is 48 hours, comfortably above any realistic queue.
Channels
happyhorse-1.0 ships in three channels. The wire schema is identical;
you pick a channel by switching the model id you POST. Pricing,
upstream routing, and a few feature corners differ — same input you
send to any of them, just at different cost / quality / latency.
| Channel | model id | Pricing | 4K | mask | negative prompt |
|---|---|---|---|---|---|
| Standard (default) | happyhorse-1.0 | baseline | — | — | — |
| Official (-10%) | happyhorse-1.0-official | 0.9 × | ✓ | — | — |
Both accept the same request body documented in this page —
prompt, first_frame_image, image_urls, video_url,
audio_setting, resolution, size, duration, seed, watermark.
The only client-visible difference at the schema level is:
- Official channel: adds 2 extra aspect ratios (
4:5,5:4) and supports4Kresolution.watermarkis forcedfalse.
Submit/poll envelope is identical across channels — task id format,
status enum, output.video_urls shape. Polling rate, retention
(7 days for video URLs), and validation error codes are the same.
Pick by use case:
- Standard is the default for new integrations — predictable latency, full feature surface (only one that supports R2V image cardinality up to 9).
- Official if you need 4K output, the wider aspect-ratio set, or the 10% discount applies to your volume.
Pricing
Per-second × resolution. Mode does not change the rate. Both channels share the same parameter shape:
- Standard —
happyhorse-1.0, full feature surface. - Official —
happyhorse-1.0-official, cheaper than Standard, supports 4K (see official-only doc).
See current 720P / 1080P / 4K rates per channel on the Happy Horse model page.
Bill formula (1 credit = $0.001):
| Mode | Billable seconds |
|---|---|
| T2V / I2V / R2V | duration you sent (default 5) |
| EDIT | ceil(server_probed_source_seconds) + min(ceil(server_probed_source_seconds), 15) — input and capped output both billable. duration is ignored in EDIT; server measures the uploaded clip. Failed probe → 400 PRICING_UNAVAILABLE, no charge |
Final bill: ceil(per_second_usd × billable_seconds × 1000) credits.
Failed jobs refund automatically.
Tips
- Prompt motion, not just scene. "Slow push-in, warm tones, shallow depth of field" outperforms a pure noun-list of what's on screen.
- Sweet-spot duration: 5–10 seconds. Below 5s motion looks choppy; above 10s upstream wall-time grows fast.
- First-frame quality matters. Subject centered, clear composition, no heavy filters — I2V output quality tracks input quality directly.
- Pre-trim EDIT sources. > 15s clips get auto-truncated to the first 15s upstream and capped at 15s for billing. Slice the input yourself if you want a different segment.
- EDIT cost = source length. A 5s source bills 5s; an 8s source bills 8s; a 60s source bills 15s (the cap). The playground's draft estimate may show a default before the upload finishes — the authoritative number is computed at submit after the server probes the file.