> ## Documentation Index
> Fetch the complete documentation index at: https://docs.yelinai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# SD2.0 Video Generation API

> Use /v1/video/generations to call SD2.0 video generation model, supporting image references, video references, and text-to-video.

**Access Notice**
SD2.0 is not yet available to all users.
Contact LaoZhang API support to request access: Telegram [@laozhang\_cn](https://t.me/laozhang_cn).

**Base URL:** `https://api.yelinai.com`

**Required endpoints:** 2

1. `POST /v1/video/generations`: create a video generation task
2. `GET /v1/video/generations/{task_id}`: query task status and get the result URL

## API Flow

SD2.0 video generation is an asynchronous task API. Create a task first, poll the task by `task_id`, then download the video after the task completes.

1. **Create task**

Call `POST /v1/video/generations` with the model, prompt, video parameters, and optional reference files.

2. **Poll status**

Call `GET /v1/video/generations/{task_id}` and check `status`.

3. **Download video**

When `status=completed`, read the video URL from the response and download the mp4.

Common status progression:

```
pending -> running -> succeeded -> completed
```

Failed tasks usually return `failed` with an `error` field.

## Models

| Model          | Description            | Recommended use                                    |
| -------------- | ---------------------- | -------------------------------------------------- |
| `seedance-2.0` | SD2.0 Video Generation | Video generation, image reference, video reference |

## Create Task

`POST /v1/video/generations`

Create an SD2.0 video generation task.

### Headers

| Header          | Required | Description           |
| --------------- | -------- | --------------------- |
| `Authorization` | Yes      | `Bearer $API_KEY`     |
| `Content-Type`  | Yes      | `multipart/form-data` |

### Request Parameters

| Parameter           | Type    | Required | Description                                                      |
| ------------------- | ------- | -------- | ---------------------------------------------------------------- |
| `model`             | string  | Yes      | Model ID, fixed as `seedance-2.0`                                |
| `prompt`            | string  | Yes      | Video generation prompt, supports referencing uploaded files     |
| `duration`          | integer | No       | Output duration in seconds, default 5 seconds                    |
| `aspect_ratio`      | string  | No       | Output aspect ratio, e.g., `16:9`, `9:16`, `1:1`, default `16:9` |
| `files`             | file    | No       | Reference files, supports images (jpg/png) and videos (mp4)      |
| `first_frame_image` | file    | No       | First frame image file, specifies the opening scene              |
| `last_frame_image`  | file    | No       | Last frame image file, specifies the ending scene                |

### File Reference Syntax

Reference files by upload order in the `prompt`:

| Reference | Meaning                    |
| --------- | -------------------------- |
| `@IMG_1`  | First uploaded image file  |
| `@IMG_2`  | Second uploaded image file |
| `@VID_1`  | First uploaded video file  |
| `@VID_2`  | Second uploaded video file |

### Text-to-video Example

```bash theme={"system"}
curl -X POST https://api.yelinai.com/v1/video/generations \
  -H "Authorization: Bearer $API_KEY" \
  -F "model=seedance-2.0" \
  -F "prompt=Cute cat playing on grass under sunny sky" \
  -F "duration=5" \
  -F "aspect_ratio=16:9"
```

### Image Reference Example

```bash theme={"system"}
curl -X POST https://api.yelinai.com/v1/video/generations \
  -H "Authorization: Bearer $API_KEY" \
  -F "model=seedance-2.0" \
  -F "prompt=@IMG_1 person walking on beach" \
  -F "duration=5" \
  -F "aspect_ratio=16:9" \
  -F "files=@/path/to/image1.jpg"
```

### Multi-asset Reference Example

```bash theme={"system"}
curl -X POST https://api.yelinai.com/v1/video/generations \
  -H "Authorization: Bearer $API_KEY" \
  -F "model=seedance-2.0" \
  -F "prompt=@IMG_1 and @IMG_3 dancing with person from @VID_1" \
  -F "duration=5" \
  -F "aspect_ratio=16:9" \
  -F "files=@/path/to/image1.jpg" \
  -F "files=@/path/to/image2.jpg" \
  -F "files=@/path/to/video1.mp4"
```

### First/Last Frame Control Example

```bash theme={"system"}
curl -X POST https://api.yelinai.com/v1/video/generations \
  -H "Authorization: Bearer $API_KEY" \
  -F "model=seedance-2.0" \
  -F "prompt=A person walking from room to outdoor scene" \
  -F "duration=8" \
  -F "aspect_ratio=16:9" \
  -F "first_frame_image=@/path/to/first_frame.jpg" \
  -F "last_frame_image=@/path/to/last_frame.jpg"
```

### Create Response

```json theme={"system"}
{
  "task_id": "task-20260501120000-abc123",
  "status": "pending",
  "created_at": "2026-05-01T12:00:00Z"
}
```

Response fields:

| Field        | Type   | Description                        |
| ------------ | ------ | ---------------------------------- |
| `task_id`    | string | Task ID used for status polling    |
| `status`     | string | Initial status, commonly `pending` |
| `created_at` | string | Creation time (ISO format)         |

## Query Task

`GET /v1/video/generations/{task_id}`

Query the status of a video generation task.

```bash theme={"system"}
curl https://api.yelinai.com/v1/video/generations/task-20260501120000-abc123 \
  -H "Authorization: Bearer $API_KEY"
```

### Path Parameters

| Parameter | Type   | Required | Description                                        |
| --------- | ------ | -------- | -------------------------------------------------- |
| `task_id` | string | Yes      | The `task_id` returned by the create task response |

### Query Response

In progress:

```json theme={"system"}
{
  "task_id": "task-20260501120000-abc123",
  "status": "running",
  "progress": 50,
  "created_at": "2026-05-01T12:00:00Z",
  "updated_at": "2026-05-01T12:01:00Z"
}
```

Completed:

```json theme={"system"}
{
  "task_id": "task-20260501120000-abc123",
  "status": "completed",
  "video_url": "https://example.com/generated-video.mp4",
  "created_at": "2026-05-01T12:00:00Z",
  "updated_at": "2026-05-01T12:05:00Z"
}
```

Failed:

```json theme={"system"}
{
  "task_id": "task-20260501120000-abc123",
  "status": "failed",
  "error": {
    "code": "GENERATION_FAILED",
    "message": "Video generation failed"
  },
  "created_at": "2026-05-01T12:00:00Z",
  "updated_at": "2026-05-01T12:03:00Z"
}
```

Response fields:

| Field        | Type    | Description                                              |
| ------------ | ------- | -------------------------------------------------------- |
| `task_id`    | string  | Task ID                                                  |
| `status`     | string  | `pending`, `running`, `succeeded`, `completed`, `failed` |
| `progress`   | integer | Task progress (0-100)                                    |
| `video_url`  | string  | Video URL returned after completion                      |
| `created_at` | string  | Creation time                                            |
| `updated_at` | string  | Update time                                              |
| `error`      | object  | Error details for failed tasks                           |

## Download Video

After the query response returns `completed`, read `video_url` and download it directly:

```bash theme={"system"}
curl -L "$VIDEO_URL" -o output.mp4
```

`video_url` is usually a temporary signed URL. Download it immediately or copy it to your own object storage.

## Full Python Example

```python theme={"system"}
import os
import time
import requests

API_KEY = os.environ["API_KEY"]
BASE_URL = "https://api.yelinai.com/v1/video/generations"

headers = {
    "Authorization": f"Bearer {API_KEY}",
}

files = {
    "model": (None, "seedance-2.0"),
    "prompt": (None, "@IMG_1 person walking on beach"),
    "duration": (None, "5"),
    "aspect_ratio": (None, "16:9"),
    "files": open("/path/to/image.jpg", "rb"),
}

create_resp = requests.post(BASE_URL, headers=headers, files=files, timeout=60)
create_resp.raise_for_status()
task_id = create_resp.json()["task_id"]

while True:
    query_resp = requests.get(f"{BASE_URL}/{task_id}", headers=headers, timeout=60)
    query_resp.raise_for_status()
    task = query_resp.json()
    status = task.get("status")

    if status == "completed":
        video_url = task.get("video_url")
        video_resp = requests.get(video_url, timeout=120)
        video_resp.raise_for_status()
        with open(f"{task_id}.mp4", "wb") as f:
            f.write(video_resp.content)
        break

    if status == "failed":
        raise RuntimeError(task.get("error") or task)

    time.sleep(20)
```

## FAQ

What are the file upload limitations?

Currently supports jpg, png image formats and mp4 video format. Individual file size should not exceed 50MB.

How to correctly reference uploaded files?

By upload order, use `@IMG_1`, `@IMG_2` for images, and `@VID_1`, `@VID_2` for videos.

How long does a task take to complete?

Typically 30-120 seconds depending on video duration and server load. Recommended polling interval is 20-30 seconds.
