ListenHubOpenAPI
API Reference

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

ModelBest forDurationResolutionAspect ratiosRate limit
doubao-seedance-2-fastFast text/image/video generation4-15s480p, 720p16:9, 4:3, 1:1, 3:4, 9:16, 21:92 RPM
doubao-seedance-2-proHigher-quality Seedance generation4-15s480p, 720p, 1080p16:9, 4:3, 1:1, 3:4, 9:16, 21:92 RPM
happyhorseHappyHorse model workflows3-15s720p, 1080p16:9, 4:3, 1:1, 3:4, 9:16, 21:9, 4:5, 5:45 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.

TypeRequired fieldsRoleNotes
texttextNoneMax 2500 characters. Seedance models accept up to 500 characters.
image_urlimage_url.urlfirst_frame, last_frame, reference_imagelast_frame requires a first_frame. Frame roles cannot be mixed with reference roles.
video_urlvideo_url.urlreference_videoRequires inputVideoDuration. Seedance accepts 2-15s input; HappyHorse accepts 3-60s input.
audio_urlaudio_url.urlreference_audioRequires 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

ParameterTypeRequiredDefaultDescription
modelstringNodoubao-seedance-2-fastdoubao-seedance-2-pro, doubao-seedance-2-fast, or happyhorse.
contentarrayYes-Input items. See Content Items.
resolutionstringNo720p480p, 720p, or 1080p, subject to model limits.
ratiostringNo16:916:9, 4:3, 1:1, 3:4, 9:16, 21:9, 4:5, or 5:4, subject to model limits.
durationintegerNo5Output duration in seconds. Seedance requires 4-15; HappyHorse accepts 3-15.
generateAudiobooleanNotrueWhether to generate audio with the video.
seedintegerNo-1Random seed. Use -1 for random generation.
inputVideoDurationintegerNo0Required when using video_url. Seedance accepts 2-15; HappyHorse accepts 3-60.
audioSettingstringNoautoFor 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:

StatusMeaning
pendingTask created and waiting to be submitted.
generatingProvider generation is in progress.
uploadingProvider output is ready and ListenHub is storing it.
successVideo is ready. Use videoUrl for the stored output.
failedGeneration 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

ParameterTypeRequiredDefaultDescription
pageintegerNo1Page number.
pageSizeintegerNo20Items per page, max 100.
statusstringNo-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

ParameterTypeRequiredDefaultDescription
modelstringYes-doubao-seedance-2-pro, doubao-seedance-2-fast, or happyhorse.
resolutionstringYes-480p, 720p, or 1080p, subject to model limits.
durationintegerYes-Output duration in seconds.
hasVideoInputbooleanNofalseSet to true when the generation request includes video_url.
inputVideoDurationintegerNo0Required when hasVideoInput is true.
ratiostringNo16:9Aspect ratio.

Response:

{
  "code": 0,
  "message": "",
  "data": {
    "tokens": 155520,
    "credits": 12
  }
}

Errors

HTTP statusMeaning
400Invalid parameters, unsupported model/ratio/resolution combination, or missing required media duration.
402Not enough credits.
403The task exists but does not belong to the current API user.
404Task not found.
429Rate limit exceeded.

On this page