AI Video
Create asynchronous AI video generation tasks from text, images, video references, and audio references.
AI Video creates short videos asynchronously. Submit a generation request, then poll the task until it reaches success or failed.
All endpoints on this page use the OpenAPI base URL:
https://api.marswave.ai/openapi.
Workflow
Estimate Credits
Call POST /v1/video-generation/estimate-credits before generation when you need to show cost confirmation.
Create a Task
Call POST /v1/video-generation/generate. The response returns a taskId and episodeId.
Poll for Result
Poll GET /v1/video-generation/tasks/{taskId} until status is success or failed.
Models and Limits
| Model | Best for | Duration | Resolution | Aspect ratios | Rate limit |
|---|---|---|---|---|---|
doubao-seedance-2-fast | Fast text/image/video generation | 4-15s | 480p, 720p | 16:9, 4:3, 1:1, 3:4, 9:16, 21:9 | 2 RPM |
doubao-seedance-2-pro | Higher-quality Seedance generation | 4-15s | 480p, 720p, 1080p | 16:9, 4:3, 1:1, 3:4, 9:16, 21:9 | 2 RPM |
happyhorse | HappyHorse model workflows | 3-15s | 720p, 1080p | 16:9, 4:3, 1:1, 3:4, 9:16, 21:9, 4:5, 5:4 | 5 RPM |
doubao-seedance-2-fast does not support 1080p. Seedance models do not
support 4:5 or 5:4. happyhorse does not support 480p, last_frame, or
audio_url.
Content Items
The content array accepts 1-16 items. It can include at most one text prompt, up to nine images, up to three videos, and up to three audio files.
| Type | Required fields | Role | Notes |
|---|---|---|---|
text | text | None | Max 2500 characters. Seedance models accept up to 500 characters. |
image_url | image_url.url | first_frame, last_frame, reference_image | last_frame requires a first_frame. Frame roles cannot be mixed with reference roles. |
video_url | video_url.url | reference_video | Requires inputVideoDuration. Seedance accepts 2-15s input; HappyHorse accepts 3-60s input. |
audio_url | audio_url.url | reference_audio | Requires at least one image or video item. Not supported by happyhorse. |
Use frame roles (first_frame, optionally last_frame) for image-to-video.
Use reference roles (reference_image, reference_video, reference_audio)
for multimodal reference generation. Do not mix frame roles and reference
roles in one request.
Create Video Task
POST /v1/video-generation/generate
Create an asynchronous video generation task. Credits are charged when the task is created and refunded automatically if generation fails.
Text to Video
curl -X POST "https://api.marswave.ai/openapi/v1/video-generation/generate" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "doubao-seedance-2-fast",
"content": [
{
"type": "text",
"text": "A cinematic aerial shot of a quiet coastal city at sunrise"
}
],
"resolution": "720p",
"ratio": "16:9",
"duration": 5,
"generateAudio": true
}'const response = await fetch(
'https://api.marswave.ai/openapi/v1/video-generation/generate',
{
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.LISTENHUB_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'doubao-seedance-2-fast',
content: [
{
type: 'text',
text: 'A cinematic aerial shot of a quiet coastal city at sunrise',
},
],
resolution: '720p',
ratio: '16:9',
duration: 5,
generateAudio: true,
}),
},
)
const data = await response.json()
console.log('Task ID:', data.data.taskId)import os
import requests
response = requests.post(
'https://api.marswave.ai/openapi/v1/video-generation/generate',
headers={'Authorization': f'Bearer {os.environ["LISTENHUB_API_KEY"]}'},
json={
'model': 'doubao-seedance-2-fast',
'content': [
{
'type': 'text',
'text': 'A cinematic aerial shot of a quiet coastal city at sunrise',
}
],
'resolution': '720p',
'ratio': '16:9',
'duration': 5,
'generateAudio': True,
},
)
data = response.json()
print('Task ID:', data['data']['taskId'])Response:
{
"code": 0,
"message": "",
"data": {
"taskId": "665f1d4e8b3a3f001234abcd",
"episodeId": "665f1d4e8b3a3f001234abce",
"status": "generating"
}
}Image to Video
Use first_frame to start from one image. Add last_frame only when you want to control the ending frame.
curl -X POST "https://api.marswave.ai/openapi/v1/video-generation/generate" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "doubao-seedance-2-pro",
"content": [
{
"type": "text",
"text": "The camera slowly pushes in while mist moves through the scene"
},
{
"type": "image_url",
"role": "first_frame",
"image_url": {
"url": "https://example.com/start-frame.jpg"
}
}
],
"resolution": "1080p",
"ratio": "16:9",
"duration": 5
}'Video Reference
When content contains video_url, set inputVideoDuration to the reference video's duration in seconds.
curl -X POST "https://api.marswave.ai/openapi/v1/video-generation/generate" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "happyhorse",
"content": [
{
"type": "text",
"text": "Restyle the subject as a polished product launch clip"
},
{
"type": "video_url",
"role": "reference_video",
"video_url": {
"url": "https://example.com/reference.mp4"
}
},
{
"type": "image_url",
"role": "reference_image",
"image_url": {
"url": "https://example.com/style-reference.jpg"
}
}
],
"resolution": "720p",
"ratio": "9:16",
"duration": 5,
"inputVideoDuration": 8,
"audioSetting": "auto"
}'Request Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
model | string | No | doubao-seedance-2-fast | doubao-seedance-2-pro, doubao-seedance-2-fast, or happyhorse. |
content | array | Yes | - | Input items. See Content Items. |
resolution | string | No | 720p | 480p, 720p, or 1080p, subject to model limits. |
ratio | string | No | 16:9 | 16:9, 4:3, 1:1, 3:4, 9:16, 21:9, 4:5, or 5:4, subject to model limits. |
duration | integer | No | 5 | Output duration in seconds. Seedance requires 4-15; HappyHorse accepts 3-15. |
generateAudio | boolean | No | true | Whether to generate audio with the video. |
seed | integer | No | -1 | Random seed. Use -1 for random generation. |
inputVideoDuration | integer | No | 0 | Required when using video_url. Seedance accepts 2-15; HappyHorse accepts 3-60. |
audioSetting | string | No | auto | For video-edit workflows. auto generates audio; origin keeps original video audio. |
Get Task
GET /v1/video-generation/tasks/{taskId}
Poll the task detail endpoint until the task reaches a terminal state.
curl "https://api.marswave.ai/openapi/v1/video-generation/tasks/{taskId}" \
-H "Authorization: Bearer $LISTENHUB_API_KEY"Task statuses:
| Status | Meaning |
|---|---|
pending | Task created and waiting to be submitted. |
generating | Provider generation is in progress. |
uploading | Provider output is ready and ListenHub is storing it. |
success | Video is ready. Use videoUrl for the stored output. |
failed | Generation failed. Credits are refunded automatically when applicable. |
Response:
{
"code": 0,
"message": "",
"data": {
"id": "665f1d4e8b3a3f001234abcd",
"taskId": "665f1d4e8b3a3f001234abcd",
"episodeId": "665f1d4e8b3a3f001234abce",
"status": "success",
"model": "doubao-seedance-2-fast",
"params": {
"content": [
{
"type": "text",
"text": "A cinematic aerial shot of a quiet coastal city at sunrise"
}
],
"resolution": "720p",
"ratio": "16:9",
"duration": 5,
"generateAudio": true,
"seed": -1
},
"videoUrl": "https://assets.listenhub.ai/video-generation/output.mp4",
"coverUrl": "https://assets.listenhub.ai/video-generation/cover.jpg",
"providerVideoUrl": "https://provider.example/video.mp4",
"duration": 5,
"resolution": "720p",
"ratio": "16:9",
"seed": 123456,
"creditCharged": 12,
"enabledShare": false,
"createdAt": 1700000000000,
"updatedAt": 1700000300000
}
}List Tasks
GET /v1/video-generation/tasks
List the current API user's video generation tasks in reverse chronological order.
curl "https://api.marswave.ai/openapi/v1/video-generation/tasks?page=1&pageSize=20&status=success" \
-H "Authorization: Bearer $LISTENHUB_API_KEY"Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
page | integer | No | 1 | Page number. |
pageSize | integer | No | 20 | Items per page, max 100. |
status | string | No | - | Optional filter: pending, generating, uploading, success, or failed. |
Response:
{
"code": 0,
"message": "",
"data": {
"items": [
{
"id": "665f1d4e8b3a3f001234abcd",
"episodeId": "665f1d4e8b3a3f001234abce",
"status": "success",
"model": "doubao-seedance-2-fast",
"title": "A cinematic aerial shot of a quiet coastal city at sunrise",
"prompt": "A cinematic aerial shot of a quiet coastal city at sunrise",
"params": {
"content": [],
"resolution": "720p",
"ratio": "16:9",
"duration": 5,
"generateAudio": true,
"seed": -1
},
"videoUrl": "https://assets.listenhub.ai/video-generation/output.mp4",
"coverUrl": "https://assets.listenhub.ai/video-generation/cover.jpg",
"providerVideoUrl": "https://provider.example/video.mp4",
"seed": 123456,
"creditCharged": 12,
"createdAt": 1700000000000
}
],
"page": 1,
"pageSize": 20,
"total": 1
}
}Estimate Credits
POST /v1/video-generation/estimate-credits
Estimate the credit cost before creating a task.
curl -X POST "https://api.marswave.ai/openapi/v1/video-generation/estimate-credits" \
-H "Authorization: Bearer $LISTENHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "doubao-seedance-2-fast",
"resolution": "720p",
"duration": 5,
"hasVideoInput": false,
"ratio": "16:9"
}'Request Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
model | string | Yes | - | doubao-seedance-2-pro, doubao-seedance-2-fast, or happyhorse. |
resolution | string | Yes | - | 480p, 720p, or 1080p, subject to model limits. |
duration | integer | Yes | - | Output duration in seconds. |
hasVideoInput | boolean | No | false | Set to true when the generation request includes video_url. |
inputVideoDuration | integer | No | 0 | Required when hasVideoInput is true. |
ratio | string | No | 16:9 | Aspect ratio. |
Response:
{
"code": 0,
"message": "",
"data": {
"tokens": 155520,
"credits": 12
}
}Errors
| HTTP status | Meaning |
|---|---|
400 | Invalid parameters, unsupported model/ratio/resolution combination, or missing required media duration. |
402 | Not enough credits. |
403 | The task exists but does not belong to the current API user. |
404 | Task not found. |
429 | Rate limit exceeded. |