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

# Generación de vídeo Wan3.0

>  - Modelo de vídeo de referencia todo en uno Alibaba Cloud Wanxiang 3.0
- Texto a vídeo / primer fotograma / primer+último fotograma / referencia multimodal / referencia de archivo o enlace
- Resolución 480P / 720P / 1080P, duración 2–30 segundos
- Admite imágenes, vídeo, audio, documentos y páginas web públicas como referencias 

<RequestExample>
  ```bash cURL theme={null}
  curl --request POST \
    --url https://api.apimart.ai/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://api.apimart.ai/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://api.apimart.ai/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://api.apimart.ai/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))
  }
  ```
</RequestExample>

<ResponseExample>
  ```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"
    }
  }
  ```
</ResponseExample>

## Autenticación

<ParamField header="Authorization" type="string" required>
  Todos los endpoints requieren autenticación Bearer Token

  Obtenga su API Key en la [página de gestión de API Keys](https://apimart.ai/keys):

  ```
  Authorization: Bearer YOUR_API_KEY
  ```
</ParamField>

## Modos de generación

El nombre del modelo es fijo: **`wan3.0-video`**. Los modos se seleccionan mediante los campos de la solicitud:

| Modo                            | Entradas típicas                                                                                   |
| ------------------------------- | -------------------------------------------------------------------------------------------------- |
| Texto a vídeo                   | solo `prompt`                                                                                      |
| Vídeo desde el primer fotograma | un elemento en `image_urls` (familia frame)                                                        |
| Primer + último fotograma       | dos elementos en `image_urls`, o `image_with_roles` con `first_frame` / `last_frame`               |
| Vídeo de referencia             | imágenes / vídeos / audio de referencia; el prompt puede usar etiquetas al estilo “图1 / 视频1 / 音频1” |
| Referencia de archivo / página  | `file_url` o `link_url` (`prompt` opcional)                                                        |

## Parámetros de la solicitud

### Básicos

<ParamField body="model" type="string" required>
  Valor fijo: `wan3.0-video`
</ParamField>

<ParamField body="prompt" type="string">
  Descripción textual. **Obligatorio a menos que** se proporcionen campos de medios (al menos uno entre prompt o medios).

  * Máx. **20.000** caracteres; el exceso se trunca automáticamente (sin error)
  * En modo de referencia, use “图N / 视频N / 音频N” para referirse a los assets; los índices siguen el orden **dentro de cada tipo de medio**
</ParamField>

<ParamField body="resolution" type="string" default="1080P">
  Resolución de salida (no distingue mayúsculas/minúsculas)

  * `480P`
  * `720P`
  * `1080P` (**predeterminado**, precio más alto)

  <Warning>
    Omitir `resolution` factura a **1080P**. Pase `480P` o `720P` explícitamente cuando el coste importe.
  </Warning>
</ParamField>

<ParamField body="size" type="string" default="adaptive">
  Relación de aspecto. También se acepta `aspect_ratio`.

  * `adaptive` (predeterminado)
  * `16:9` / `4:3` / `1:1` / `3:4` / `9:16`
</ParamField>

<ParamField body="duration" type="integer" default="5">
  Duración en segundos:

  * `2`–`30`: duración de salida fija (predeterminado `5`)
  * `-1`: la duración la **decide el modelo**

  <Note>
    Con vídeo de referencia: duración total de entrada + salida ≤ 30 s. Con `duration: -1`, la duración elegida por el modelo también debe cumplir esta restricción.
  </Note>
</ParamField>

<ParamField body="audio" type="boolean" default="true">
  Si la salida incluye pista de audio. Predeterminado `true`. **El precio es el mismo con o sin audio.**
</ParamField>

<ParamField body="seed" type="integer">
  Semilla aleatoria en `[0, 2147483647]`
</ParamField>

<ParamField body="watermark" type="boolean" default="false">
  Si se debe añadir una marca de agua. Predeterminado `false`
</ParamField>

<ParamField body="generation_type" type="string">
  Cómo se clasifican los `image_urls` sin rol explícito:

  * `frame` — familia de primer/último fotograma
  * `reference` — familia de referencia

  Si se omite, la clasificación es automática (véanse las reglas de exclusión mutua).
</ParamField>

### Entradas de medios

<ParamField body="image_urls" type="string[]">
  Array de URL de imágenes. La asignación de roles sigue las reglas de exclusión mutua.

  URL pública o Base64 (`data:image/png;base64,...`).
</ParamField>

<ParamField body="image_with_roles" type="object[]">
  Imágenes con roles explícitos. Cada elemento:

  * `url`: dirección de la imagen
  * `role`: `first_frame` / `last_frame` / `reference_image` (se aceptan alias comunes)
</ParamField>

<ParamField body="video_urls" type="string[]">
  Vídeos de referencia, hasta **5** clips; cada uno 1–15 s, **total ≤ 15 s**
</ParamField>

<ParamField body="audio_urls" type="string[]">
  Audio de referencia, hasta **5** clips; cada uno 1–15 s, **total ≤ 15 s**
</ParamField>

<ParamField body="audio_url" type="string">
  Audio de referencia único (forma de valor único de `audio_urls`)
</ParamField>

<ParamField body="file_url" type="string">
  URL de documento de referencia, como máximo **1**. **No se puede combinar con `link_url`.**

  Formatos: docx / doc / xlsx / xls / pptx / ppt / pdf / txt / key / pages / numbers / md, ≤100 MB, ≤50 páginas.
</ParamField>

<ParamField body="link_url" type="string">
  URL de página web pública, como máximo **1**. Solo páginas sin inicio de sesión. **No se puede combinar con `file_url`.**
</ParamField>

## Exclusión mutua de familias de medios

Los medios pertenecen a una de dos familias y **no deben mezclarse** (validado antes del envío → 400, sin tarea, sin cargo):

| Familia                   | Miembros                                                                | Significado                                  |
| ------------------------- | ----------------------------------------------------------------------- | -------------------------------------------- |
| **Familia frame**         | `first_frame`, `last_frame`                                             | Primer / último fotograma estricto del vídeo |
| **Familia de referencia** | `reference_image`, `reference_video`, `reference_audio`, `file`, `link` | El modelo interpreta el contenido libremente |

### Cómo se asignan los `image_urls` sin rol

1. Si `generation_type` está definido → usarlo (`frame` / `reference`)
2. Si no, y la solicitud ya tiene entradas de la familia de referencia (`video_urls` / `audio_urls` / `audio_url` / `file_url` / `link_url`) → tratar como `reference_image`
3. Si no → familia frame: primer elemento `first_frame`, segundo `last_frame` (igual que `wan2.7`)

Use `image_with_roles` cuando necesite control explícito.

### Límites y formatos de medios

| Tipo                      | Límites                                                                                     |
| ------------------------- | ------------------------------------------------------------------------------------------- |
| Primer / último fotograma | ≤ 1 cada uno                                                                                |
| Imágenes de referencia    | ≤ 10                                                                                        |
| Vídeo de referencia       | ≤ 5 clips, 1–15 s cada uno, total ≤15 s; mp4/mov; borde 240–4096 px, relación ≤8:1, ≤100 MB |
| Audio de referencia       | ≤ 5 clips, 1–15 s cada uno, total ≤15 s; wav/mp3; ≤15 MB                                    |
| Imágenes                  | JPEG/JPG/PNG (sin alpha) / BMP / WEBP; borde 240–8000 px, relación ≤8:1, ≤20 MB             |
| Documentos                | ≤100 MB, ≤50 páginas                                                                        |
| Páginas web               | URL públicas, sin inicio de sesión                                                          |

## Ejemplos de solicitud

### Texto a vídeo

```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
}
```

### Vídeo desde el primer fotograma

```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
}
```

### Primer + último fotograma

```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
}
```

O con `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
}
```

### Referencia 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
}
```

> Con `video_urls` presente, los `image_urls` sin rol se clasifican automáticamente como imágenes de referencia; definir `generation_type: "reference"` es más claro.

### Vídeo de referencia por archivo

`prompt` puede omitirse; la generación se basa en el documento:

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

### Vídeo de referencia por página 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
}
```

## Facturación

**Por segundo × resolución** (alineado con el precio oficial). El audio activado/desactivado no cambia el precio:

| Resolución | Precio unitario | 5 s   | 30 s   |
| ---------- | --------------- | ----- | ------ |
| 480P       | **¥0.30** / s   | ¥1.50 | ¥9.00  |
| 720P       | **¥0.60** / s   | ¥3.00 | ¥18.00 |
| 1080P      | **¥1.20** / s   | ¥6.00 | ¥36.00 |

* El valor predeterminado es **1080P** (el más caro); pase `480P` / `720P` cuando el coste sea sensible
* Segundos facturables: para `2`–`30`, la `duration` solicitada; para `-1`, los segundos **reales** de salida
* `audio: true/false` **no** afecta al precio

## Límites y notas

| Elemento             | Notas                                                                        |
| -------------------- | ---------------------------------------------------------------------------- |
| Duración             | Entero `2`–`30`, o `-1` (el modelo decide la duración)                       |
| Con entrada de vídeo | Duración total de los vídeos de entrada + duración de salida ≤ 30 s          |
| Latencia             | Típicamente 1–5 minutos; más larga para clips largos                         |
| URL del resultado    | Reflejada en el CDN de la plataforma tras el éxito para acceso a largo plazo |
| Prompt               | ≤20.000 caracteres; exceso truncado                                          |

## Errores comunes

Todos son **400 síncronos** (sin tarea, sin cargo):

| Caso                                   | Qué hacer                                                                           |
| -------------------------------------- | ----------------------------------------------------------------------------------- |
| Mezclar familias frame y de referencia | Elija una familia mediante `generation_type`, o defina roles con `image_with_roles` |
| `file_url` y `link_url` juntos         | Elija uno                                                                           |
| `duration` no válido                   | Solo `2`–`30` o `-1`                                                                |
| Resolución no admitida (p. ej. 4K)     | Solo `480P` / `720P` / `1080P`                                                      |
| Más de 10 imágenes de referencia       | Reduzca a ≤10                                                                       |
| `prompt` vacío y medios vacíos         | Proporcione al menos uno                                                            |

## Respuesta

<ResponseField name="code" type="integer">
  Código de estado; 200 en caso de éxito
</ResponseField>

<ResponseField name="data" type="array">
  Array de datos de respuesta

  <Expandable title="Elementos del array">
    <ResponseField name="status" type="string">
      Estado de la tarea; `submitted` al crearse
    </ResponseField>

    <ResponseField name="task_id" type="string">
      ID de tarea para el polling
    </ResponseField>
  </Expandable>
</ResponseField>

<Note>
  **Consultar resultados**

  La generación de vídeo es asíncrona. Consulte [Obtener estado de la tarea](/es/api-reference/tasks/status) o `GET /v1/videos/generations/{task_id}`.

  Intervalo recomendado 5–10 segundos; la generación suele tardar 1–5 minutos. En caso de éxito, use las URL en `result.videos`.
</Note>
