happyhorse-1.1-r2v
A video generation model driven by reference images and a text scenario. Helps preserve the appearance of characters, objects and the visual style in a new scene.
- Ailoot · Video
POST /v1/videos/generationshappyhorse-1.1-r2v - Ailoot · Video
POST /v1/videos/generationshappyhorse-r2v - Ailoot · Video
POST /v1/videos/generationshappyhorse-r2v-latest
About the model
This description covers the model’s capabilities. Available in Ailoot inputs, outputs and options are listed for the selected method below.
HappyHorse-1.1-R2V creates a new video scene from reference images and a text prompt. Alibaba designs the model to preserve recognizable characters, objects and visual style while generating movement. The references establish the scene's content and appearance, and the text describes how those elements should interact.
The roles of visual references
Between one and nine images can be used. They may define a character, an object, the surroundings or an artistic treatment. The prompt can identify a reference by number and name a particular object in it, linking the visual material to the relevant part of the action. This is especially useful when elements from several images need to be combined in one composition.
Unlike the mode that uses an initial frame, references here guide the content of a new scene. A text prompt is required: it connects the appearance of objects to the action, camera movement and overall staging. The manufacturer highlights visual consistency and cinematic movement. The model generates a new video rather than editing the source images.
JPEG, JPG, PNG and WEBP files of up to 20 MB each are accepted. The shorter dimension must be at least 400 pixels; material at 720P or higher is recommended. This mode takes images and text as its inputs.
Duration, framing and audio
The result is saved as MP4 at 24 frames per second. Duration is specified as an integer from 3 to 15 seconds. Resolution can be selected from 480P, 720P and 1080P; audio generation is supported.
Landscape, portrait and square frames are available: 16:9, 9:16, 1:1, 4:3, 3:4, 4:5, 5:4, 9:21 and 21:9. Selecting a format helps define the compositional space of the new scene in advance.
The prompt may be in any language. The limit is 5000 non-Chinese or 2500 Chinese characters, with any excess truncated. The most important reference roles, actions and movements must fit within this length. A random seed can guide similarity between variations, but does not guarantee an exact reproduction of a video.
Ailoot · Video POST /v1/videos/generations happyhorse-1.1-r2v
happyhorse-1.1-r2vhappyhorse-1.1-r2vhappyhorse-r2vhappyhorse-r2v-latest
Overview
A video generation model driven by reference images and a text scenario. Helps preserve the appearance of characters, objects and the visual style in a new scene.
- Accepted inputs
- Text · Images
- Results
- Video
Available in Ailoot · inputs & methods
Ailoot · Video POST /v1/videos/generations
- Input types
text,image- Output types
video- Output format
- mp4
| Field | Type | Requirement | Values & limits | Default |
|---|---|---|---|---|
Fieldmodel | Typestring | RequirementRequired | Values & limits happyhorse-1.1-r2v | Default— |
Fieldprompt | Typestring | RequirementRequired | Values & limits Minimum length: 1 | Default— |
Fieldduration | Typeinteger | RequirementOptional | Values & limits Minimum: 3 Maximum: 15 Unit: seconds | Default5 |
Fieldresolution | Typestring | RequirementOptional | Values & limits 480P, 720P, 1080P | Default720P |
Fieldratio | Typestring | RequirementOptional | Values & limits 16:9, 9:16, 1:1, 4:3, 3:4, 4:5, 5:4, 9:21, 21:9 | Default16:9 |
Fieldimage_urls | Typehttps_url|data_image_url[] | RequirementRequired | Values & limits Minimum items: 1 Maximum items: 9 Maximum decoded bytes: 20,971,520 MIME types: image/jpeg, image/png, image/webp | Default— |
Input material combinations
reference_images_to_video · Required: prompt, image_urls
Method parameters and lifecycle
| Parameter | Contract |
|---|---|
Parametercontent_type | Contractapplication/json |
Parameterrequired | Contractmodel, prompt, image_urls |
Parametermaterial_types | Contracttext, image |
Parameteroptional | Contractduration, resolution, ratio |
Parameterduration_integer_range | Contract3, 15 |
Parameterdefault_duration | Contract5 |
Parameterresolution | Contract480P, 720P, 1080P |
Parameterdefault_resolution | Contract720P |
Parameterratio | Contract16:9, 9:16, 1:1, 4:3, 3:4, 4:5, 5:4, 9:21, 21:9 |
Parameterratio_must_omit | Contractfalse |
Parameterimage_urls | Contract{"min_count":1,"max_count":9,"schemes":["https","data raster base64"],"max_data_image_bytes":20971520} |
Lifecycle: submit_once_poll_original
GET /v1/videos/{request_id}
GET /v1/videos/generations/{request_id}
GET /v1/videos/{request_id}/content
GET /v1/videos/generations/{request_id}/content
Method shapes and IDs are exact; supplier capability is separate from admission.
Pricing
Ailoot method rates
POST /v1/videos/generations- Output
- $0.18 per second at 1080p
- Output
- $0.07 per second at 480p
- Output
- $0.14 per second at 720p
Ailoot reserves an estimated amount before a request. After the result, it settles the final charge from measured usage. Streaming settlement uses the final usage record. How reservation and settlement work →
Example requests
Ailoot · Video
set -eu
: "${AILOOT_API_KEY:?Set your Ailoot API key}"
: "${AILOOT_IMAGE_URLS_FILE:?Set a JSON file containing your actual reference-image URLs}"
export AILOOT_IMAGE_URLS_FILE
python3 - <<'PY_REQUEST'
import json,os
from pathlib import Path
p=json.loads('{"model": "happyhorse-1.1-r2v", "prompt": "The subject walks slowly toward the camera.", "duration": 5, "resolution": "720P"}')
from urllib.parse import urlsplit
f=Path(os.environ["AILOOT_IMAGE_URLS_FILE"])
if not f.is_file():raise SystemExit("Choose the actual reference URL JSON file")
urls=json.loads(f.read_text())
if not isinstance(urls,list) or not 1<=len(urls)<=9:raise SystemExit("Provide one to nine reference-image URLs")
for u in urls:
z=urlsplit(u) if isinstance(u,str) else None
if not z or z.scheme!="https" or not z.netloc or z.username or z.password:raise SystemExit("Each reference must be an actual HTTPS image URL")
p["image_urls"]=urls
p["ratio"]="16:9"
Path("request.json").write_text(json.dumps(p,ensure_ascii=False))
PY_REQUEST
curl --fail-with-body --silent --show-error https://api.ailoot.ai/v1/videos/generations \
-H "Authorization: Bearer $AILOOT_API_KEY" -H 'Content-Type: application/json' \
--data-binary @request.json -D response-headers.txt -o result.json
python3 - <<'PY_RESULT'
import json
from pathlib import Path
r=json.loads(Path("result.json").read_text())
print(json.dumps(r))
PY_RESULT
Receive and save results
Ailoot · Video
mp4
GET /v1/videos/{request_id}GET /v1/videos/generations/{request_id}GET /v1/videos/{request_id}/contentGET /v1/videos/generations/{request_id}/content
Check job status
set -eu
: "${AILOOT_API_KEY:?Set your Ailoot API key}"
: "${AILOOT_OPERATION_ID:?Set the actual Ailoot operation ID returned by creation}"
export AILOOT_OPERATION_ID
operation_id=$(python3 -c 'import os,urllib.parse;print(urllib.parse.quote(os.environ["AILOOT_OPERATION_ID"],safe=""))')
curl --fail-with-body --silent --show-error "https://api.ailoot.ai/v1/videos/generations/$operation_id" \
-H "Authorization: Bearer $AILOOT_API_KEY" -o status.json
python3 - <<'PY_STATUS'
import json
from pathlib import Path
r=json.loads(Path("status.json").read_text())
print(json.dumps(r))
if r.get("status")=="completed":
for x in r.get("data",[]):print(x)
PY_STATUS
Save all completed assets
set -eu
: "${AILOOT_API_KEY:?Set your Ailoot API key}"
: "${AILOOT_STATUS_FILE:?Set the actual completed status JSON file}"
export AILOOT_STATUS_FILE
python3 - <<'PY_REQUEST'
import json,os
from pathlib import Path
from urllib.parse import urlsplit,urljoin
f=Path(os.environ["AILOOT_STATUS_FILE"])
if not f.is_file():raise SystemExit("Choose the actual completed status file")
r=json.loads(f.read_text())
if r.get("status")!="completed" or not isinstance(r.get("data"),list) or not r["data"]:raise SystemExit("Wait for a completed status with asset paths")
urls=[]
for x in r["data"]:
if not isinstance(x,str) or "\n" in x or "\r" in x:raise SystemExit("Invalid asset path")
u=urljoin("https://api.ailoot.ai",x)
z=urlsplit(u)
if z.scheme!="https" or z.netloc!="api.ailoot.ai" or z.username or z.password:raise SystemExit("Use the actual Ailoot asset paths from status")
urls.append(u)
Path("asset-urls.txt").write_text("\n".join(urls)+"\n")
PY_REQUEST
index=0
while IFS= read -r asset_url; do
curl --fail-with-body --silent --show-error "$asset_url" \
-H "Authorization: Bearer $AILOOT_API_KEY" -o "video-${index}.mp4"
index=$((index + 1))
done < asset-urls.txt
Other content reads
set -eu
: "${AILOOT_API_KEY:?Set your Ailoot API key}"
: "${AILOOT_OPERATION_ID:?Set the actual Ailoot operation ID returned by creation}"
export AILOOT_OPERATION_ID
operation_id=$(python3 -c 'import os,urllib.parse;print(urllib.parse.quote(os.environ["AILOOT_OPERATION_ID"],safe=""))')
curl --fail-with-body --silent --show-error "https://api.ailoot.ai/v1/videos/generations/$operation_id/content" \
-H "Authorization: Bearer $AILOOT_API_KEY" -o video.mp4
Keep all completed results
Save every completed video or returned file; retrieve every actual returned asset URL.
Preserve every returned data item/output index. content_url is first only; fetch every actual content path/asset. GETcontentwithoutindex isnotalloutputs.
If the original response needs checking
Read existing original job; never resubmit unknown send.
Response fields
| Field | Type |
|---|---|
Fieldid | Typestring |
Fieldobject | Typestring |
Fieldmodel | Typestring |
Fieldstatus | Typestring |
Fieldcontent_url | Typesigned URL |
Fielddata[] | Typesigned URL |
Fieldusage | Typeobject |
Fieldresult_pending_check | Typeboolean |
Errors and next steps
| Response | Condition | Next step |
|---|---|---|
Response400 · invalid_request_error | ConditionInvalid required fields, material representation or parameter value | Next stepCorrect the indicated fields before a new creation request. |
Response409 · video_not_ready | ConditionOriginal result content is not yet available | Next stepPoll the original returned ID and respect Retry-After. |
Responseserver_error | ConditionThe returned response says the operation or result requires a check | Next stepKeep the original returned operation/task ID, request headers and response; continue supported reads of that original operation. Do not resubmit the creation request. |
Aliases
Model aliases
Ailoot happyhorse-1.1-r2v, happyhorse-r2v, happyhorse-r2v-latest
Method path aliases
Use the method paths shown above.
Related caller IDs
Ailoot · Video POST /v1/videos/generations happyhorse-r2v
happyhorse-r2vhappyhorse-1.1-r2vhappyhorse-r2vhappyhorse-r2v-latest
Overview
A video generation model driven by reference images and a text scenario. Helps preserve the appearance of characters, objects and the visual style in a new scene.
- Accepted inputs
- Text · Images
- Results
- Video
Available in Ailoot · inputs & methods
Ailoot · Video POST /v1/videos/generations
- Input types
text,image- Output types
video- Output format
- mp4
| Field | Type | Requirement | Values & limits | Default |
|---|---|---|---|---|
Fieldmodel | Typestring | RequirementRequired | Values & limits happyhorse-r2v | Default— |
Fieldprompt | Typestring | RequirementRequired | Values & limits Minimum length: 1 | Default— |
Fieldduration | Typeinteger | RequirementOptional | Values & limits Minimum: 3 Maximum: 15 Unit: seconds | Default5 |
Fieldresolution | Typestring | RequirementOptional | Values & limits 480P, 720P, 1080P | Default720P |
Fieldratio | Typestring | RequirementOptional | Values & limits 16:9, 9:16, 1:1, 4:3, 3:4, 4:5, 5:4, 9:21, 21:9 | Default16:9 |
Fieldimage_urls | Typehttps_url|data_image_url[] | RequirementRequired | Values & limits Minimum items: 1 Maximum items: 9 Maximum decoded bytes: 20,971,520 MIME types: image/jpeg, image/png, image/webp | Default— |
Input material combinations
reference_images_to_video · Required: prompt, image_urls
Method parameters and lifecycle
| Parameter | Contract |
|---|---|
Parametermaterial_types | Contracttext, image |
Parameterrequired | Contractnull |
Parameteroptional_controls | Contractnull |
Lifecycle: submit_once_poll_original
GET /v1/videos/{request_id}
GET /v1/videos/generations/{request_id}
GET /v1/videos/{request_id}/content
GET /v1/videos/generations/{request_id}/content
Method shapes and IDs are exact; supplier capability is separate from admission.
Pricing
Ailoot method rates
POST /v1/videos/generations- Output
- $0.18 per second at 1080p
- Output
- $0.07 per second at 480p
- Output
- $0.14 per second at 720p
Ailoot reserves an estimated amount before a request. After the result, it settles the final charge from measured usage. Streaming settlement uses the final usage record. How reservation and settlement work →
Example requests
Ailoot · Video
set -eu
: "${AILOOT_API_KEY:?Set your Ailoot API key}"
: "${AILOOT_IMAGE_URLS_FILE:?Set a JSON file containing your actual reference-image URLs}"
export AILOOT_IMAGE_URLS_FILE
python3 - <<'PY_REQUEST'
import json,os
from pathlib import Path
p=json.loads('{"model": "happyhorse-r2v", "prompt": "The subject walks slowly toward the camera.", "duration": 5, "resolution": "720P"}')
from urllib.parse import urlsplit
f=Path(os.environ["AILOOT_IMAGE_URLS_FILE"])
if not f.is_file():raise SystemExit("Choose the actual reference URL JSON file")
urls=json.loads(f.read_text())
if not isinstance(urls,list) or not 1<=len(urls)<=9:raise SystemExit("Provide one to nine reference-image URLs")
for u in urls:
z=urlsplit(u) if isinstance(u,str) else None
if not z or z.scheme!="https" or not z.netloc or z.username or z.password:raise SystemExit("Each reference must be an actual HTTPS image URL")
p["image_urls"]=urls
p["ratio"]="16:9"
Path("request.json").write_text(json.dumps(p,ensure_ascii=False))
PY_REQUEST
curl --fail-with-body --silent --show-error https://api.ailoot.ai/v1/videos/generations \
-H "Authorization: Bearer $AILOOT_API_KEY" -H 'Content-Type: application/json' \
--data-binary @request.json -D response-headers.txt -o result.json
python3 - <<'PY_RESULT'
import json
from pathlib import Path
r=json.loads(Path("result.json").read_text())
print(json.dumps(r))
PY_RESULT
Receive and save results
Ailoot · Video
mp4
GET /v1/videos/{request_id}GET /v1/videos/generations/{request_id}GET /v1/videos/{request_id}/contentGET /v1/videos/generations/{request_id}/content
Check job status
set -eu
: "${AILOOT_API_KEY:?Set your Ailoot API key}"
: "${AILOOT_OPERATION_ID:?Set the actual Ailoot operation ID returned by creation}"
export AILOOT_OPERATION_ID
operation_id=$(python3 -c 'import os,urllib.parse;print(urllib.parse.quote(os.environ["AILOOT_OPERATION_ID"],safe=""))')
curl --fail-with-body --silent --show-error "https://api.ailoot.ai/v1/videos/generations/$operation_id" \
-H "Authorization: Bearer $AILOOT_API_KEY" -o status.json
python3 - <<'PY_STATUS'
import json
from pathlib import Path
r=json.loads(Path("status.json").read_text())
print(json.dumps(r))
if r.get("status")=="completed":
for x in r.get("data",[]):print(x)
PY_STATUS
Save all completed assets
set -eu
: "${AILOOT_API_KEY:?Set your Ailoot API key}"
: "${AILOOT_STATUS_FILE:?Set the actual completed status JSON file}"
export AILOOT_STATUS_FILE
python3 - <<'PY_REQUEST'
import json,os
from pathlib import Path
from urllib.parse import urlsplit,urljoin
f=Path(os.environ["AILOOT_STATUS_FILE"])
if not f.is_file():raise SystemExit("Choose the actual completed status file")
r=json.loads(f.read_text())
if r.get("status")!="completed" or not isinstance(r.get("data"),list) or not r["data"]:raise SystemExit("Wait for a completed status with asset paths")
urls=[]
for x in r["data"]:
if not isinstance(x,str) or "\n" in x or "\r" in x:raise SystemExit("Invalid asset path")
u=urljoin("https://api.ailoot.ai",x)
z=urlsplit(u)
if z.scheme!="https" or z.netloc!="api.ailoot.ai" or z.username or z.password:raise SystemExit("Use the actual Ailoot asset paths from status")
urls.append(u)
Path("asset-urls.txt").write_text("\n".join(urls)+"\n")
PY_REQUEST
index=0
while IFS= read -r asset_url; do
curl --fail-with-body --silent --show-error "$asset_url" \
-H "Authorization: Bearer $AILOOT_API_KEY" -o "video-${index}.mp4"
index=$((index + 1))
done < asset-urls.txt
Other content reads
set -eu
: "${AILOOT_API_KEY:?Set your Ailoot API key}"
: "${AILOOT_OPERATION_ID:?Set the actual Ailoot operation ID returned by creation}"
export AILOOT_OPERATION_ID
operation_id=$(python3 -c 'import os,urllib.parse;print(urllib.parse.quote(os.environ["AILOOT_OPERATION_ID"],safe=""))')
curl --fail-with-body --silent --show-error "https://api.ailoot.ai/v1/videos/generations/$operation_id/content" \
-H "Authorization: Bearer $AILOOT_API_KEY" -o video.mp4
Keep all completed results
Save every completed video or returned file; retrieve every actual returned asset URL.
Preserve every returned data item/output index. content_url is first only; fetch every actual content path/asset. GETcontentwithoutindex isnotalloutputs.
If the original response needs checking
Read existing original job; never resubmit unknown send.
Response fields
| Field | Type |
|---|---|
Fieldid | Typestring |
Fieldobject | Typestring |
Fieldmodel | Typestring |
Fieldstatus | Typestring |
Fieldcontent_url | Typesigned URL |
Fielddata[] | Typesigned URL |
Fieldusage | Typeobject |
Fieldresult_pending_check | Typeboolean |
Errors and next steps
| Response | Condition | Next step |
|---|---|---|
Response400 · invalid_request_error | ConditionInvalid required fields, material representation or parameter value | Next stepCorrect the indicated fields before a new creation request. |
Response409 · video_not_ready | ConditionOriginal result content is not yet available | Next stepPoll the original returned ID and respect Retry-After. |
Responseserver_error | ConditionThe returned response says the operation or result requires a check | Next stepKeep the original returned operation/task ID, request headers and response; continue supported reads of that original operation. Do not resubmit the creation request. |
Aliases
Model aliases
Ailoot happyhorse-1.1-r2v, happyhorse-r2v, happyhorse-r2v-latest
Method path aliases
Use the method paths shown above.
Related caller IDs
Ailoot · Video POST /v1/videos/generations happyhorse-r2v-latest
happyhorse-r2v-latesthappyhorse-1.1-r2vhappyhorse-r2vhappyhorse-r2v-latest
Overview
A video generation model driven by reference images and a text scenario. Helps preserve the appearance of characters, objects and the visual style in a new scene.
- Accepted inputs
- Text · Images
- Results
- Video
Available in Ailoot · inputs & methods
Ailoot · Video POST /v1/videos/generations
- Input types
text,image- Output types
video- Output format
- mp4
| Field | Type | Requirement | Values & limits | Default |
|---|---|---|---|---|
Fieldmodel | Typestring | RequirementRequired | Values & limits happyhorse-r2v-latest | Default— |
Fieldprompt | Typestring | RequirementRequired | Values & limits Minimum length: 1 | Default— |
Fieldduration | Typeinteger | RequirementOptional | Values & limits Minimum: 3 Maximum: 15 Unit: seconds | Default5 |
Fieldresolution | Typestring | RequirementOptional | Values & limits 480P, 720P, 1080P | Default720P |
Fieldratio | Typestring | RequirementOptional | Values & limits 16:9, 9:16, 1:1, 4:3, 3:4, 4:5, 5:4, 9:21, 21:9 | Default16:9 |
Fieldimage_urls | Typehttps_url|data_image_url[] | RequirementRequired | Values & limits Minimum items: 1 Maximum items: 9 Maximum decoded bytes: 20,971,520 MIME types: image/jpeg, image/png, image/webp | Default— |
Input material combinations
reference_images_to_video · Required: prompt, image_urls
Method parameters and lifecycle
| Parameter | Contract |
|---|---|
Parametermaterial_types | Contracttext, image |
Parameterrequired | Contractnull |
Parameteroptional_controls | Contractnull |
Lifecycle: submit_once_poll_original
GET /v1/videos/{request_id}
GET /v1/videos/generations/{request_id}
GET /v1/videos/{request_id}/content
GET /v1/videos/generations/{request_id}/content
Method shapes and IDs are exact; supplier capability is separate from admission.
Pricing
Ailoot method rates
POST /v1/videos/generations- Output
- $0.18 per second at 1080p
- Output
- $0.07 per second at 480p
- Output
- $0.14 per second at 720p
Ailoot reserves an estimated amount before a request. After the result, it settles the final charge from measured usage. Streaming settlement uses the final usage record. How reservation and settlement work →
Example requests
Ailoot · Video
set -eu
: "${AILOOT_API_KEY:?Set your Ailoot API key}"
: "${AILOOT_IMAGE_URLS_FILE:?Set a JSON file containing your actual reference-image URLs}"
export AILOOT_IMAGE_URLS_FILE
python3 - <<'PY_REQUEST'
import json,os
from pathlib import Path
p=json.loads('{"model": "happyhorse-r2v-latest", "prompt": "The subject walks slowly toward the camera.", "duration": 5, "resolution": "720P"}')
from urllib.parse import urlsplit
f=Path(os.environ["AILOOT_IMAGE_URLS_FILE"])
if not f.is_file():raise SystemExit("Choose the actual reference URL JSON file")
urls=json.loads(f.read_text())
if not isinstance(urls,list) or not 1<=len(urls)<=9:raise SystemExit("Provide one to nine reference-image URLs")
for u in urls:
z=urlsplit(u) if isinstance(u,str) else None
if not z or z.scheme!="https" or not z.netloc or z.username or z.password:raise SystemExit("Each reference must be an actual HTTPS image URL")
p["image_urls"]=urls
p["ratio"]="16:9"
Path("request.json").write_text(json.dumps(p,ensure_ascii=False))
PY_REQUEST
curl --fail-with-body --silent --show-error https://api.ailoot.ai/v1/videos/generations \
-H "Authorization: Bearer $AILOOT_API_KEY" -H 'Content-Type: application/json' \
--data-binary @request.json -D response-headers.txt -o result.json
python3 - <<'PY_RESULT'
import json
from pathlib import Path
r=json.loads(Path("result.json").read_text())
print(json.dumps(r))
PY_RESULT
Receive and save results
Ailoot · Video
mp4
GET /v1/videos/{request_id}GET /v1/videos/generations/{request_id}GET /v1/videos/{request_id}/contentGET /v1/videos/generations/{request_id}/content
Check job status
set -eu
: "${AILOOT_API_KEY:?Set your Ailoot API key}"
: "${AILOOT_OPERATION_ID:?Set the actual Ailoot operation ID returned by creation}"
export AILOOT_OPERATION_ID
operation_id=$(python3 -c 'import os,urllib.parse;print(urllib.parse.quote(os.environ["AILOOT_OPERATION_ID"],safe=""))')
curl --fail-with-body --silent --show-error "https://api.ailoot.ai/v1/videos/generations/$operation_id" \
-H "Authorization: Bearer $AILOOT_API_KEY" -o status.json
python3 - <<'PY_STATUS'
import json
from pathlib import Path
r=json.loads(Path("status.json").read_text())
print(json.dumps(r))
if r.get("status")=="completed":
for x in r.get("data",[]):print(x)
PY_STATUS
Save all completed assets
set -eu
: "${AILOOT_API_KEY:?Set your Ailoot API key}"
: "${AILOOT_STATUS_FILE:?Set the actual completed status JSON file}"
export AILOOT_STATUS_FILE
python3 - <<'PY_REQUEST'
import json,os
from pathlib import Path
from urllib.parse import urlsplit,urljoin
f=Path(os.environ["AILOOT_STATUS_FILE"])
if not f.is_file():raise SystemExit("Choose the actual completed status file")
r=json.loads(f.read_text())
if r.get("status")!="completed" or not isinstance(r.get("data"),list) or not r["data"]:raise SystemExit("Wait for a completed status with asset paths")
urls=[]
for x in r["data"]:
if not isinstance(x,str) or "\n" in x or "\r" in x:raise SystemExit("Invalid asset path")
u=urljoin("https://api.ailoot.ai",x)
z=urlsplit(u)
if z.scheme!="https" or z.netloc!="api.ailoot.ai" or z.username or z.password:raise SystemExit("Use the actual Ailoot asset paths from status")
urls.append(u)
Path("asset-urls.txt").write_text("\n".join(urls)+"\n")
PY_REQUEST
index=0
while IFS= read -r asset_url; do
curl --fail-with-body --silent --show-error "$asset_url" \
-H "Authorization: Bearer $AILOOT_API_KEY" -o "video-${index}.mp4"
index=$((index + 1))
done < asset-urls.txt
Other content reads
set -eu
: "${AILOOT_API_KEY:?Set your Ailoot API key}"
: "${AILOOT_OPERATION_ID:?Set the actual Ailoot operation ID returned by creation}"
export AILOOT_OPERATION_ID
operation_id=$(python3 -c 'import os,urllib.parse;print(urllib.parse.quote(os.environ["AILOOT_OPERATION_ID"],safe=""))')
curl --fail-with-body --silent --show-error "https://api.ailoot.ai/v1/videos/generations/$operation_id/content" \
-H "Authorization: Bearer $AILOOT_API_KEY" -o video.mp4
Keep all completed results
Save every completed video or returned file; retrieve every actual returned asset URL.
Preserve every returned data item/output index. content_url is first only; fetch every actual content path/asset. GETcontentwithoutindex isnotalloutputs.
If the original response needs checking
Read existing original job; never resubmit unknown send.
Response fields
| Field | Type |
|---|---|
Fieldid | Typestring |
Fieldobject | Typestring |
Fieldmodel | Typestring |
Fieldstatus | Typestring |
Fieldcontent_url | Typesigned URL |
Fielddata[] | Typesigned URL |
Fieldusage | Typeobject |
Fieldresult_pending_check | Typeboolean |
Errors and next steps
| Response | Condition | Next step |
|---|---|---|
Response400 · invalid_request_error | ConditionInvalid required fields, material representation or parameter value | Next stepCorrect the indicated fields before a new creation request. |
Response409 · video_not_ready | ConditionOriginal result content is not yet available | Next stepPoll the original returned ID and respect Retry-After. |
Responseserver_error | ConditionThe returned response says the operation or result requires a check | Next stepKeep the original returned operation/task ID, request headers and response; continue supported reads of that original operation. Do not resubmit the creation request. |
Aliases
Model aliases
Ailoot happyhorse-1.1-r2v, happyhorse-r2v, happyhorse-r2v-latest
Method path aliases
Use the method paths shown above.
Related caller IDs
FAQ · happyhorse-1.1-r2v
- What inputs and results are available?
POST /v1/videos/generations·happyhorse-1.1-r2v:text,image→videoPOST /v1/videos/generations·happyhorse-r2v:text,image→videoPOST /v1/videos/generations·happyhorse-r2v-latest:text,image→video- Which fields does the request use?
POST /v1/videos/generations·happyhorse-1.1-r2v:model,prompt,duration,resolution,ratio,image_urlsPOST /v1/videos/generations·happyhorse-r2v:model,prompt,duration,resolution,ratio,image_urlsPOST /v1/videos/generations·happyhorse-r2v-latest:model,prompt,duration,resolution,ratio,image_urls- What limits apply?
POST /v1/videos/generations·happyhorse-1.1-r2v:duration.minimum:3;duration.maximum:15POST /v1/videos/generations·happyhorse-r2v:duration.minimum:3;duration.maximum:15POST /v1/videos/generations·happyhorse-r2v-latest:duration.minimum:3;duration.maximum:15