> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.meshapi.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.meshapi.ai/_mcp/server.

# Video Generation

> Submit and poll async video generation tasks with the Python SDK.

# Video Generation

## Generate a Video

`client.videos.generate` sends `POST /v1/video/generations` and returns a `CreateVideoGenerationResponse` containing the task ID.

```python
from meshapi import MeshAPI, VideoGenerationParams, VideoContentItem
import time

client = MeshAPI(base_url="https://api.meshapi.ai", token="rsk_...")

task = client.videos.generate(
    VideoGenerationParams(
        model="byteplus/dreamina-seedance-2-0",
        content=[
            VideoContentItem(type="text", text="A serene mountain lake at sunrise"),
        ],
    )
)

print(f"Task ID: {task.id}")
```

## Poll Until Complete

```python
while True:
    status = client.videos.retrieve(task.id)
    print(f"Status: {status.status}")
    if status.status in ("succeeded", "failed"):
        break
    time.sleep(5)

if status.status == "succeeded" and status.content:
    for item in status.content:
        if item.type == "video_url":
            print("Video URL:", item.url)
```

## List Tasks

`client.videos.list` sends `GET /v1/video/generations`.

```python
from meshapi import ListVideoGenerationsParams

listing = client.videos.list(ListVideoGenerationsParams(limit=20))
print(f"{listing.total} total tasks")
for task in listing.data:
    print(task.id, task.status)
```

## Retrieve a Task

`client.videos.retrieve` sends `GET /v1/video/generations/{task_id}`.

```python
task = client.videos.retrieve("task-id")
print(task.status)
```

### Async

```python
from meshapi import AsyncMeshAPI, VideoGenerationParams, VideoContentItem

async with AsyncMeshAPI(base_url="https://api.meshapi.ai", token="rsk_...") as client:
    task = await client.videos.generate(
        VideoGenerationParams(
            model="byteplus/dreamina-seedance-2-0",
            content=[VideoContentItem(type="text", text="A futuristic city at night")],
        )
    )
    status = await client.videos.retrieve(task.id)
    print(status.status)
```

## Parameters

### `VideoGenerationParams`

| Field        | Type                     | Notes                                             |
| ------------ | ------------------------ | ------------------------------------------------- |
| `model`      | `str`                    | Required. e.g. `"byteplus/dreamina-seedance-2-0"` |
| `content`    | `list[VideoContentItem]` | Required. Prompt content items.                   |
| `duration`   | `int \| None`            | Duration in seconds                               |
| `resolution` | `str \| None`            | e.g. `"1080p"`                                    |
| `seed`       | `int \| None`            | Reproducibility seed                              |

### `VideoContentItem`

| Field       | Type          | Notes                               |
| ----------- | ------------- | ----------------------------------- |
| `type`      | `str`         | `"text"` or `"image_url"`           |
| `text`      | `str \| None` | Text prompt (when `type="text"`)    |
| `image_url` | `str \| None` | Image URL (when `type="image_url"`) |

### `VideoTaskResponse`

| Field     | Type             | Notes                                               |
| --------- | ---------------- | --------------------------------------------------- |
| `id`      | `str`            | Task ID                                             |
| `status`  | `str`            | `"pending"`, `"running"`, `"succeeded"`, `"failed"` |
| `content` | `list \| None`   | Output items when succeeded                         |
| `error`   | `object \| None` | Error details when failed                           |