ModelSell Docs
VideosSeedance 2.0 / 2.5

Python Polling and Download

Create Seedance 2.0 / 2.5 tasks, handle channel-specific success responses, and stop on failure, cancellation, or expiry.

This native-route example handles Ark succeeded / content.video_url, Service Inference / Max top-level completed / outputs[0], and generic video_url responses used by some channels. Poll with the returned ModelSell public id.

The default model is doubao-seedance-2-5-260628; set MODELSELL_VIDEO_MODEL to an available model. For edit/extend request bodies, see Request and Response Parameters. A local timeout does not cancel the upstream task; retain its ID for later queries.

pip install requests
import os
import time
import requests

BASE_URL = os.environ.get("MODELSELL_BASE_URL", "https://api.modelsell.com").rstrip("/")
API_KEY = os.environ["MODELSELL_API_KEY"]
MODEL = os.environ.get("MODELSELL_VIDEO_MODEL", "doubao-seedance-2-5-260628")
HEADERS = {"Authorization": f"Bearer {API_KEY}"}


def create_task(prompt: str) -> str:
    response = requests.post(
        f"{BASE_URL}/api/v3/contents/generations/tasks",
        headers=HEADERS,
        json={
            "model": MODEL,
            "content": [{"type": "text", "text": prompt}],
            "resolution": "720p",
            "ratio": "16:9",
            "duration": 5,
            "generate_audio": True,
        },
        timeout=180,
    )
    response.raise_for_status()
    return response.json()["id"]


def wait_for_result(task_id: str, max_wait: int = 900, interval: int = 10) -> str:
    deadline = time.monotonic() + max_wait
    while time.monotonic() < deadline:
        response = requests.get(
            f"{BASE_URL}/api/v3/contents/generations/tasks/{task_id}",
            headers=HEADERS,
            timeout=60,
        )
        response.raise_for_status()
        data = response.json()
        status = data.get("status")
        print(f"status={status}")

        if status in {"succeeded", "completed"}:
            content = data.get("content") or {}
            metadata = data.get("metadata") or {}
            outputs = data.get("outputs") or []
            video_url = (
                content.get("video_url")
                or data.get("video_url")
                or metadata.get("url")
                or (outputs[0] if outputs else None)
            )
            if not video_url:
                raise RuntimeError("Task succeeded but no video URL was returned")
            return video_url
        if status in {"failed", "cancelled", "expired"}:
            error = data.get("error")
            if isinstance(error, dict):
                raise RuntimeError(f"{error.get('code', status)}: {error.get('message', '')}")
            raise RuntimeError(f"{status}: {error or 'Task did not complete'}")
        time.sleep(min(interval, max(0, deadline - time.monotonic())))

    raise TimeoutError(f"Local polling deadline exceeded: {task_id}")


def download_video(video_url: str, save_path: str) -> None:
    with requests.get(video_url, stream=True, timeout=120) as response:
        response.raise_for_status()
        with open(save_path, "wb") as file:
            for chunk in response.iter_content(chunk_size=8192):
                if chunk:
                    file.write(chunk)


if __name__ == "__main__":
    task_id = create_task("A golden Shiba Inu runs under cherry blossoms as the camera rises")
    video_url = wait_for_result(task_id)
    download_video(video_url, "seedance-output.mp4")

Official video URLs expire after 24 hours; 2.5 URLs permit at most 100 downloads. Other channel limits may differ; save results promptly.

Generation Mode Examples

Previous Page

Video Generation

使用 Seedance 2.0 / 2.5 官方 `content[]` 格式创建异步视频生成任务。支持文生视频、图生视频、视频生视频、图像与音频组合、视频与音频组合,以及图像、视频、音频全模态引用。 **素材支持自动上传。** 在 `content[].image_url.url`、`content[].video_url.url` 或 `content[].audio_url.url` 中直接传入公网可访问的 `https://` 链接,系统会自动识别并上传素材,无需提前调用 `/api/assets/upload`。 若希望使用 ModelSell 的通用视频格式,也可以调用 `/v1/video/generations` 或 `/v1/videos`,通过 `prompt`、`image`、`images`、`metadata.video_url`、`metadata.audio_url` 等字段提交。 需要通过素材 ID 复用图片、视频或音频时,也可以手动调用 `/api/assets/upload` 上传素材,素材状态为 `Active` 后可在 `content[].*_url.url` 中传入 `asset://<asset_id>`。 Seedance 2.5 新增 `omni_reference_task_type`,默认 `auto`,可选 `reference`、`edit`、`extend`。编辑要求 `reference_video`、`ratio: adaptive` 和 `duration: -1`;延长要求 `reference_video` 和 `ratio: adaptive`。完整约束与渠道差异见 [请求与返回参数](/docs/api-reference/seedance-2/parameters)。 官方字段已于 2026-09-07 核对 https://docs.volcengine.com/docs/82379/1520757 和 https://docs.volcengine.com/docs/82379/1521309。高级字段需所选渠道支持,通用格式不能假定透传全部原生字段。