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

# Generasi Video Wan3.0

>  - Model video referensi all-in-one Alibaba Cloud Wanxiang 3.0
- Teks-ke-video / frame pertama / frame pertama+terakhir / referensi multimodal / referensi file atau tautan
- Resolusi 480P / 720P / 1080P, durasi 2–30 detik
- Mendukung gambar, video, audio, dokumen, dan halaman web publik sebagai referensi 

```bash cURL theme={null}
curl --request POST \
  --url https://gccai.heqingsong.uk/v1/videos/generations \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "model": "wan3.0-video",
    "prompt": "A kitten runs across a moonlit rooftop, neon lights of the city flicker in the distance, cinematic quality, smooth camera move.",
    "resolution": "720P",
    "size": "16:9",
    "duration": 5
  }'
```

```python Python theme={null}
import requests

url = "https://gccai.heqingsong.uk/v1/videos/generations"

payload = {
    "model": "wan3.0-video",
    "prompt": "A kitten runs across a moonlit rooftop, neon lights of the city flicker in the distance, cinematic quality, smooth camera move.",
    "resolution": "720P",
    "size": "16:9",
    "duration": 5,
}

headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json",
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript JavaScript theme={null}
const url = "https://gccai.heqingsong.uk/v1/videos/generations";

const payload = {
  model: "wan3.0-video",
  prompt: "A kitten runs across a moonlit rooftop, neon lights of the city flicker in the distance, cinematic quality, smooth camera move.",
  resolution: "720P",
  size: "16:9",
  duration: 5,
};

const headers = {
  Authorization: "Bearer <token>",
  "Content-Type": "application/json",
};

fetch(url, {
  method: "POST",
  headers: headers,
  body: JSON.stringify(payload),
})
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((error) => console.error("Error:", error));
```

```go Go theme={null}
package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
)

func main() {
    url := "https://gccai.heqingsong.uk/v1/videos/generations"

    payload := map[string]interface{}{
        "model":      "wan3.0-video",
        "prompt":     "A kitten runs across a moonlit rooftop",
        "resolution": "720P",
        "size":       "16:9",
        "duration":   5,
    }

    jsonData, _ := json.Marshal(payload)
    req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
    req.Header.Set("Authorization", "Bearer <token>")
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, _ := ioutil.ReadAll(resp.Body)
    fmt.Println(string(body))
}
```

```json 200 theme={null}
{
  "code": 200,
  "data": [
    {
      "status": "submitted",
      "task_id": "task_01J9HA7JPQ9A0Z6JZ3V8M9W6PZ"
    }
  ]
}
```

```json 400 theme={null}
{
  "error": {
    "code": 400,
    "message": "Invalid request parameters",
    "type": "invalid_request_error"
  }
}
```

```json 401 theme={null}
{
  "error": {
    "code": 401,
    "message": "Authentication failed, please check your API key",
    "type": "authentication_error"
  }
}
```

```json 402 theme={null}
{
  "error": {
    "code": 402,
    "message": "Insufficient account balance, please top up and try again",
    "type": "payment_required"
  }
}
```

```json 429 theme={null}
{
  "error": {
    "code": 429,
    "message": "Too many requests, please try again later",
    "type": "rate_limit_error"
  }
}
```

## Autentikasi

**Authorization** `string` *required*

Semua endpoint memerlukan autentikasi Bearer Token

Dapatkan API Key Anda dari [Halaman Manajemen API Key](https://gccai.heqingsong.uk/keys):

```
Authorization: Bearer YOUR_API_KEY
```

## Mode Generasi

Nama model adalah **`wan3.0-video`** atau **`wan3.0-video-prime`** (parameter sama). Mode dipilih melalui field permintaan:

| Mode | Input tipikal |
| - | - |
| Teks-ke-video | hanya `prompt` |
| Video frame pertama | satu item di `image_urls` (keluarga frame) |
| Frame pertama + terakhir | dua item di `image_urls`, atau `image_with_roles` dengan `first_frame` / `last_frame` |
| Video referensi | gambar / video / audio referensi; prompt dapat memakai label gaya “图1 / 视频1 / 音频1” |
| Referensi file / halaman | `file_url` atau `link_url` (`prompt` opsional) |

## Parameter Permintaan

### Dasar

**model** `string` *required*

Nama model pembuatan video. Nilai yang diizinkan:

* `wan3.0-video`
* `wan3.0-video-prime`

Kedua model menerima parameter permintaan yang sama persis.

**nsfw\_check** `boolean` (default: false)

Menentukan apakah moderasi konten dijalankan sebelum tugas video dikirim.

* `true`: periksa prompt dan gambar input dengan `omni-moderation-latest`
* `false` atau dihilangkan: tidak mengirim permintaan moderasi, tanpa biaya atau latensi moderasi tambahan (default)

**prompt** `string`

Deskripsi teks. **Wajib kecuali** field media disediakan (setidaknya salah satu dari prompt atau media).

* Maks **20.000** karakter; kelebihan dipotong otomatis (tanpa error)
* Dalam mode referensi, gunakan “图N / 视频N / 音频N” untuk merujuk aset; indeks mengikuti urutan **dalam setiap jenis media**

**resolution** `string` (default: 1080P)

Resolusi keluaran (tidak peka huruf besar/kecil)

* `480P`
* `720P`
* `1080P` (**default**, harga tertinggi)

> [!WARNING]
>
> Menghilangkan `resolution` akan ditagih pada **1080P**. Kirim `480P` atau `720P` secara eksplisit bila biaya penting.

**size** `string` (default: adaptive)

Rasio aspek. `aspect_ratio` juga diterima.

* `adaptive` (default)
* `16:9` / `4:3` / `1:1` / `3:4` / `9:16`

**duration** `integer` (default: 5)

Durasi dalam detik:

* `2`–`30`: durasi keluaran tetap (default `5`)
* `-1`: durasi **ditentukan model**

> [!NOTE]
>
> Jika ada video referensi: total durasi input + output ≤ 30 detik. Dengan `duration: -1`, durasi yang dipilih model tetap harus memenuhi batasan ini.

**audio** `boolean` (default: true)

Apakah keluaran menyertakan trek audio. Default `true`. **Harga sama dengan atau tanpa audio.**

**seed** `integer`

Seed acak di `[0, 2147483647]`

**watermark** `boolean` (default: false)

Apakah menambahkan watermark. Default `false`

**generation\_type** `string`

Cara `image_urls` tanpa peran eksplisit diklasifikasikan:

* `frame` — keluarga frame pertama/terakhir
* `reference` — keluarga referensi

Jika dihilangkan, klasifikasi otomatis (lihat aturan saling eksklusif).

### Input media

**image\_urls** `string[]`

Array URL gambar. Penugasan peran mengikuti aturan saling eksklusif.

Hanya URL publik.

**image\_with\_roles** `object[]`

Gambar dengan peran eksplisit. Setiap item:

* `url`: alamat gambar
* `role`: `first_frame` / `last_frame` / `reference_image` (alias umum diterima)

**video\_urls** `string[]`

Video referensi, hingga **5** klip; masing-masing 1–15 d, **total ≤ 15 d**

**audio\_urls** `string[]`

Audio referensi, hingga **5** klip; masing-masing 1–15 d, **total ≤ 15 d**

**audio\_url** `string`

Audio referensi tunggal (bentuk nilai tunggal dari `audio_urls`)

**file\_url** `string`

URL dokumen referensi, paling banyak **1**. **Tidak dapat digabungkan dengan `link_url`.**

Format meliputi docx / doc / xlsx / xls / pptx / ppt / pdf / txt / key / pages / numbers / md, ≤100MB, ≤50 halaman.

**link\_url** `string`

URL halaman web publik, paling banyak **1**. Hanya halaman tanpa login. **Tidak dapat digabungkan dengan `file_url`.**

## Saling Eksklusif Keluarga Media

Media termasuk salah satu dari dua keluarga dan **tidak boleh digabung** (divalidasi sebelum submit → 400, tanpa tugas, tanpa biaya):

| Keluarga | Anggota | Arti |
| - | - | - |
| **Keluarga frame** | `first_frame`, `last_frame` | Frame pertama / terakhir ketat dari video |
| **Keluarga referensi** | `reference_image`, `reference_video`, `reference_audio`, `file`, `link` | Model menafsirkan konten secara bebas |

### Cara `image_urls` tanpa peran ditetapkan

1. Jika `generation_type` disetel → gunakan itu (`frame` / `reference`)
2. Jika tidak, dan permintaan sudah memiliki input keluarga referensi (`video_urls` / `audio_urls` / `audio_url` / `file_url` / `link_url`) → perlakukan sebagai `reference_image`
3. Jika tidak → keluarga frame: item pertama `first_frame`, kedua `last_frame` (sama seperti `wan2.7`)

Gunakan `image_with_roles` bila Anda membutuhkan kontrol eksplisit.

### Batas dan format media

| Jenis | Batas |
| - | - |
| Frame pertama / terakhir | ≤ 1 masing-masing |
| Gambar referensi | ≤ 10 |
| Video referensi | ≤ 5 klip, 1–15 d masing-masing, total ≤15 d; mp4/mov; tepi 240–4096 px, rasio ≤8:1, ≤100MB |
| Audio referensi | ≤ 5 klip, 1–15 d masing-masing, total ≤15 d; wav/mp3; ≤15MB |
| Gambar | JPEG/JPG/PNG (tanpa alpha) / BMP / WEBP; tepi 240–8000 px, rasio ≤8:1, ≤20MB |
| Dokumen | ≤100MB, ≤50 halaman |
| Halaman web | URL publik, tanpa login |

## Contoh Permintaan

### Teks-ke-video

```json theme={null}
{
  "model": "wan3.0-video",
  "prompt": "A kitten runs across a moonlit rooftop, neon lights of the city flicker in the distance, cinematic quality, smooth camera move.",
  "resolution": "720P",
  "size": "16:9",
  "duration": 5
}
```

### Video frame pertama

```json theme={null}
{
  "model": "wan3.0-video",
  "prompt": "The person in the frame starts freestyle rapping, camera slowly pushes in",
  "image_urls": ["https://example.com/first.png"],
  "resolution": "720P",
  "duration": 5
}
```

### Frame pertama + terakhir

```json theme={null}
{
  "model": "wan3.0-video",
  "prompt": "Smile gradually becomes laughter, background light shifts from cool to warm",
  "image_urls": [
    "https://example.com/first.png",
    "https://example.com/last.jpg"
  ],
  "duration": 5
}
```

Atau dengan `image_with_roles`:

```json theme={null}
{
  "model": "wan3.0-video",
  "prompt": "Smile gradually becomes laughter",
  "image_with_roles": [
    {"url": "https://example.com/first.png", "role": "first_frame"},
    {"url": "https://example.com/last.jpg", "role": "last_frame"}
  ],
  "duration": 5
}
```

### Referensi multimodal

```json theme={null}
{
  "model": "wan3.0-video",
  "prompt": "视频1抱着图1，在图3的椅子上弹奏一支舒缓的乡村民谣，并说道：\"今天的阳光真好。\"",
  "generation_type": "reference",
  "image_urls": [
    "https://example.com/object1.jpg",
    "https://example.com/object2.png",
    "https://example.com/chair.png"
  ],
  "video_urls": ["https://example.com/role.mp4"],
  "resolution": "480P",
  "duration": 5
}
```

> Dengan `video_urls` hadir, `image_urls` tanpa peran otomatis diklasifikasikan sebagai gambar referensi; mengatur `generation_type: "reference"` lebih jelas.

### Video referensi file

`prompt` boleh dihilangkan; generasi didorong oleh dokumen:

```json theme={null}
{
  "model": "wan3.0-video",
  "file_url": "https://example.com/glass.pptx",
  "resolution": "480P",
  "duration": 10
}
```

### Video referensi halaman web

```json theme={null}
{
  "model": "wan3.0-video",
  "prompt": "Turn this article into a short educational video",
  "link_url": "https://example.com/article/123",
  "duration": 15
}
```

## Penagihan

**Per detik × resolusi** (selaras dengan harga resmi). Audio on/off tidak mengubah harga:

| Resolusi | Harga satuan | 5 d | 30 d |
| - | - | - | - |
| 480P | **¥0.30** / d | ¥1.50 | ¥9.00 |
| 720P | **¥0.60** / d | ¥3.00 | ¥18.00 |
| 1080P | **¥1.20** / d | ¥6.00 | ¥36.00 |

* Default adalah **1080P** (paling mahal); kirim `480P` / `720P` bila sensitif biaya
* Detik yang ditagih: untuk `2`–`30`, `duration` yang diminta; untuk `-1`, detik keluaran **aktual**
* `audio: true/false` **tidak** memengaruhi harga

## Batasan dan Catatan

| Item | Catatan |
| - | - |
| Durasi | Bilangan bulat `2`–`30`, atau `-1` (model menentukan durasi) |
| Dengan input video | Total durasi video input + durasi keluaran ≤ 30 d |
| Latensi | Biasanya 1–5 menit; lebih lama untuk klip panjang |
| URL hasil | Dicerminkan ke CDN platform setelah sukses untuk akses jangka panjang |
| Prompt | ≤20.000 karakter; kelebihan dipotong |

## Error Umum

Semua adalah **400 sinkron** (tanpa tugas, tanpa biaya):

| Kasus | Yang harus dilakukan |
| - | - |
| Mencampur keluarga frame dan referensi | Pilih satu keluarga lewat `generation_type`, atau setel peran dengan `image_with_roles` |
| `file_url` dan `link_url` bersamaan | Pilih salah satu |
| `duration` tidak valid | Hanya `2`–`30` atau `-1` |
| Resolusi tidak didukung (mis. 4K) | Hanya `480P` / `720P` / `1080P` |
| Lebih dari 10 gambar referensi | Kurangi menjadi ≤10 |
| `prompt` kosong dan media kosong | Sediakan setidaknya salah satu |

## Respons

**code** `integer`

Kode status; 200 jika sukses

**data** `array`

Array data respons

**Elemen array**

**status** `string`

Status tugas; `submitted` saat dibuat

**task\_id** `string`

ID tugas untuk polling

> [!NOTE]
>
> **Kueri hasil**
>
> Generasi video bersifat asinkron. Poll [Dapatkan Status Tugas](https://gccai.heqingsong.uk/id/api-reference/tasks/status.md) atau `GET /v1/videos/generations/{task_id}`.
>
> Interval yang direkomendasikan 5–10 detik; generasi biasanya memakan waktu 1–5 menit. Saat sukses, gunakan URL di `result.videos`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.