> ## 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.

# Geração de vídeo Wan3.0

>  - Modelo de vídeo de referência all-in-one Alibaba Cloud Wanxiang 3.0
- Texto-para-vídeo / primeiro frame / primeiro+último frame / referência multimodal / referência por arquivo ou link
- Resolução 480P / 720P / 1080P, duração 2–30 segundos
- Suporta imagens, vídeo, áudio, documentos e páginas web públicas como referências 

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

## Autenticação

<ParamField header="Authorization" type="string" required>
  Todos os endpoints exigem autenticação Bearer Token

  Obtenha sua API Key na [página de gerenciamento de API Keys](https://apimart.ai/keys):

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

## Modos de geração

O nome do modelo é fixo em **`wan3.0-video`**. Os modos são selecionados pelos campos da requisição:

| Modo                             | Entradas típicas                                                                              |
| -------------------------------- | --------------------------------------------------------------------------------------------- |
| Texto-para-vídeo                 | apenas `prompt`                                                                               |
| Vídeo a partir do primeiro frame | um item em `image_urls` (família frame)                                                       |
| Primeiro + último frame          | dois itens em `image_urls`, ou `image_with_roles` com `first_frame` / `last_frame`            |
| Vídeo de referência              | imagens / vídeos / áudio de referência; o prompt pode usar rótulos no estilo “图1 / 视频1 / 音频1” |
| Referência por arquivo / página  | `file_url` ou `link_url` (`prompt` opcional)                                                  |

## Parâmetros da requisição

### Básicos

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

<ParamField body="prompt" type="string">
  Descrição textual. **Obrigatório a menos que** campos de mídia sejam fornecidos (pelo menos um entre prompt ou mídia).

  * Máx. **20.000** caracteres; o excesso é truncado automaticamente (sem erro)
  * No modo de referência, use “图N / 视频N / 音频N” para endereçar assets; os índices seguem a ordem **dentro de cada tipo de mídia**
</ParamField>

<ParamField body="resolution" type="string" default="1080P">
  Resolução de saída (sem distinção de maiúsculas/minúsculas)

  * `480P`
  * `720P`
  * `1080P` (**padrão**, preço mais alto)

  <Warning>
    Omitir `resolution` cobra em **1080P**. Passe `480P` ou `720P` explicitamente quando o custo importar.
  </Warning>
</ParamField>

<ParamField body="size" type="string" default="adaptive">
  Proporção. `aspect_ratio` também é aceito.

  * `adaptive` (padrão)
  * `16:9` / `4:3` / `1:1` / `3:4` / `9:16`
</ParamField>

<ParamField body="duration" type="integer" default="5">
  Duração em segundos:

  * `2`–`30`: duração de saída fixa (padrão `5`)
  * `-1`: a duração é **definida pelo modelo**

  <Note>
    Com vídeo de referência: duração total de entrada + saída ≤ 30 s. Com `duration: -1`, a duração escolhida pelo modelo ainda deve respeitar esse limite.
  </Note>
</ParamField>

<ParamField body="audio" type="boolean" default="true">
  Se a saída inclui faixa de áudio. Padrão `true`. **O preço é o mesmo com ou sem áudio.**
</ParamField>

<ParamField body="seed" type="integer">
  Semente aleatória em `[0, 2147483647]`
</ParamField>

<ParamField body="watermark" type="boolean" default="false">
  Se deve adicionar marca d’água. Padrão `false`
</ParamField>

<ParamField body="generation_type" type="string">
  Como `image_urls` sem papel explícito são classificadas:

  * `frame` — família primeiro/último frame
  * `reference` — família de referência

  Se omitido, a classificação é automática (veja as regras de exclusão mútua).
</ParamField>

### Entradas de mídia

<ParamField body="image_urls" type="string[]">
  Array de URLs de imagem. A atribuição de papéis segue as regras de exclusão mútua.

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

<ParamField body="image_with_roles" type="object[]">
  Imagens com papéis explícitos. Cada item:

  * `url`: endereço da imagem
  * `role`: `first_frame` / `last_frame` / `reference_image` (aliases comuns aceitos)
</ParamField>

<ParamField body="video_urls" type="string[]">
  Vídeos de referência, até **5** clips; cada um 1–15 s, **total ≤ 15 s**
</ParamField>

<ParamField body="audio_urls" type="string[]">
  Áudio de referência, até **5** clips; cada um 1–15 s, **total ≤ 15 s**
</ParamField>

<ParamField body="audio_url" type="string">
  Áudio de referência único (forma de valor único de `audio_urls`)
</ParamField>

<ParamField body="file_url" type="string">
  URL de documento de referência, no máximo **1**. **Não pode ser combinado com `link_url`.**

  Formatos incluem 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, no máximo **1**. Apenas páginas sem login. **Não pode ser combinado com `file_url`.**
</ParamField>

## Exclusão mútua das famílias de mídia

A mídia pertence a uma de duas famílias e **não deve ser misturada** (validado antes do envio → 400, sem tarefa, sem cobrança):

| Família                   | Membros                                                                 | Significado                               |
| ------------------------- | ----------------------------------------------------------------------- | ----------------------------------------- |
| **Família frame**         | `first_frame`, `last_frame`                                             | Primeiro / último frame estrito do vídeo  |
| **Família de referência** | `reference_image`, `reference_video`, `reference_audio`, `file`, `link` | O modelo interpreta o conteúdo livremente |

### Como `image_urls` sem papel explícito são atribuídas

1. Se `generation_type` estiver definido → usá-lo (`frame` / `reference`)
2. Caso contrário, se a requisição já tiver entradas da família de referência (`video_urls` / `audio_urls` / `audio_url` / `file_url` / `link_url`) → tratar como `reference_image`
3. Caso contrário → família frame: primeiro item `first_frame`, segundo `last_frame` (igual a `wan2.7`)

Use `image_with_roles` quando precisar de controle explícito.

### Limites e formatos de mídia

| Tipo                    | Limites                                                                                  |
| ----------------------- | ---------------------------------------------------------------------------------------- |
| Primeiro / último frame | ≤ 1 cada                                                                                 |
| Imagens de referência   | ≤ 10                                                                                     |
| Vídeo de referência     | ≤ 5 clips, 1–15 s cada, total ≤15 s; mp4/mov; borda 240–4096 px, proporção ≤8:1, ≤100 MB |
| Áudio de referência     | ≤ 5 clips, 1–15 s cada, total ≤15 s; wav/mp3; ≤15 MB                                     |
| Imagens                 | JPEG/JPG/PNG (sem alpha) / BMP / WEBP; borda 240–8000 px, proporção ≤8:1, ≤20 MB         |
| Documentos              | ≤100 MB, ≤50 páginas                                                                     |
| Páginas web             | URLs públicas, sem login                                                                 |

## Exemplos de requisição

### Texto-para-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 a partir do primeiro frame

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

### Primeiro + último frame

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

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

### Referência 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
}
```

> Com `video_urls` presente, `image_urls` sem papel explícito classificam-se automaticamente como imagens de referência; definir `generation_type: "reference"` fica mais claro.

### Vídeo de referência por arquivo

`prompt` pode ser omitido; a geração é conduzida pelo documento:

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

### Vídeo de referência 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
}
```

## Cobrança

**Por segundo × resolução** (alinhado ao preço oficial). Áudio ligado/desligado não altera o preço:

| Resolução | Preço unitário | 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 |

* O padrão é **1080P** (mais caro); passe `480P` / `720P` quando o custo for sensível
* Segundos faturáveis: para `2`–`30`, a `duration` solicitada; para `-1`, os segundos **reais** de saída
* `audio: true/false` **não** afeta o preço

## Limites e observações

| Item                 | Observações                                                            |
| -------------------- | ---------------------------------------------------------------------- |
| Duração              | Inteiro `2`–`30`, ou `-1` (o modelo define a duração)                  |
| Com entrada de vídeo | Duração total dos vídeos de entrada + duração de saída ≤ 30 s          |
| Latência             | Tipicamente 1–5 minutos; mais longo para clips longos                  |
| URL do resultado     | Espelhada no CDN da plataforma após sucesso para acesso de longo prazo |
| Prompt               | ≤20.000 caracteres; excesso truncado                                   |

## Erros comuns

Todos são **400 síncronos** (sem tarefa, sem cobrança):

| Caso                                 | O que fazer                                                                          |
| ------------------------------------ | ------------------------------------------------------------------------------------ |
| Misturar famílias frame e referência | Escolher uma família via `generation_type`, ou definir papéis com `image_with_roles` |
| `file_url` e `link_url` juntos       | Escolher um                                                                          |
| `duration` inválido                  | Apenas `2`–`30` ou `-1`                                                              |
| Resolução não suportada (ex. 4K)     | Apenas `480P` / `720P` / `1080P`                                                     |
| Mais de 10 imagens de referência     | Reduzir para ≤10                                                                     |
| `prompt` vazio e mídia vazia         | Fornecer pelo menos um                                                               |

## Resposta

<ResponseField name="code" type="integer">
  Código de status; 200 em caso de sucesso
</ResponseField>

<ResponseField name="data" type="array">
  Array de dados da resposta

  <Expandable title="Elementos do array">
    <ResponseField name="status" type="string">
      Status da tarefa; `submitted` na criação
    </ResponseField>

    <ResponseField name="task_id" type="string">
      ID da tarefa para polling
    </ResponseField>
  </Expandable>
</ResponseField>

<Note>
  **Consultar resultados**

  A geração de vídeo é assíncrona. Consulte [Obter status da tarefa](/pt/api-reference/tasks/status) ou `GET /v1/videos/generations/{task_id}`.

  Intervalo recomendado 5–10 segundos; a geração normalmente leva 1–5 minutos. Em caso de sucesso, use as URLs em `result.videos`.
</Note>
