alibaba/wan-3.0/image-to-videoA partir de 34 créditos por um clipe de 5 segundos· Imagem para vídeo

O image-to-video Wan 3.0 da Alibaba parte de um quadro de abertura e dirige 2 a 30 segundos de movimento com áudio gerado. Um quadro final opcional fixa onde o plano termina, em 480p, 720p ou 1080p.

Chame com o nome de modelo alibaba/wan-3.0/image-to-video em POST /jobs/createTask, a partir de 34 créditos por um clipe de 5 segundos (US$ 0,34). Contas novas ganham 30 créditos grátis para você testar primeiro no Playground.

  • Criar vídeo
  • Imagem para vídeo
  • Referências para vídeo
  • Estender vídeo
  • Até 1080p
  • Clipes de 2 a 30 s
  • Com som
  • Quadro inicial e final
  • Até 10 imagens de referência
  • 5 proporções
Nome do modeloalibaba/wan-3.0/image-to-video
EndpointPOST https://api.popnow.ai/api/v1/jobs/createTask
# 1. Create the task. Keep the Idempotency-Key if you retry after a network error.
export IDEMPOTENCY_KEY="$(uuidgen)"
curl -X POST https://api.popnow.ai/api/v1/jobs/createTask \
  -H "Authorization: Bearer $POPNOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -d '{
  "model": "alibaba/wan-3.0/image-to-video",
  "input": {
    "prompt": "A slow aerial shot drifting over a misty pine forest at sunrise",
    "image_url": "https://media.popnow.ai/influencer/examples/marco.webp",
    "resolution": "720p",
    "duration_seconds": 5
  }
}'

# 2. Copy data.taskId from the response, then poll until state is succeeded, failed, canceled or expired.
TASK_ID="TASK_ID_FROM_RESPONSE"
curl "https://api.popnow.ai/api/v1/jobs/recordInfo?taskId=$TASK_ID" \
  -H "Authorization: Bearer $POPNOW_API_KEY"

O input é montado a partir do schema abaixo, então passa na validação como está. Troque o prompt e os links pelos seus.

Preço

OpçãoCréditos por segundo≈ USD
resolution 480p6,75US$ 0,068
resolution 720p13,5US$ 0,14
resolution 1080p27US$ 0,27

1 crédito = US$ 0,01 · Todas as opções e preços: GET /models/alibaba/wan-3.0/image-to-video

Cada tarefa é arredondada para cima em créditos inteiros, então uma execução no nível mais baixo custa 34 créditos por um clipe de 5 segundos (US$ 0,34).

Limites

Duração do clipe
2–30 s
Resoluções
480p · 720p · 1080p
Proporções
16:9 · 9:16 · 1:1 · 4:3 · 3:4 · adaptive

Parâmetros

Estes campos vêm do mesmo schema que usamos para validar cada requisição. Campos que não estão na lista são rejeitados.

Alguns campos dependem uns dos outros (por exemplo, pelo menos uma referência). O schema bruto no fim tem as regras exatas.

  • image_urlstringObrigatório

    A imagem de partida.

    Faixa
    image/jpeg, image/png, image/webp, image/gif
  • promptstringOpcional

    Describe the subject, action, camera, light, pacing, and boundaries for the shot.

    Faixa
    1 – … chars
  • last_image_urlstringOpcional

    Quadro final opcional, para o clipe terminar exatamente onde você quer.

    Faixa
    image/jpeg, image/png, image/webp, image/gif
  • aspect_ratiostringOpcional

    O formato do quadro: horizontal, quadrado ou vertical.

    Valores aceitos
    "16:9""9:16""1:1""4:3""3:4""adaptive"
  • enable_thinkingbooleanOpcional

    Let the model reason about the brief and the reference material before generating. Helps with complex references; slower. Switches on by itself when a reference file or link is given.

    Padrão
    false
  • resolutionstringOpcionalMuda o preço

    Tamanho de saída. Maior fica mais nítido e custa mais.

    Padrão
    "720p"
    Valores aceitos
    "480p""720p""1080p"
  • duration_secondsintegerOpcionalMuda o preço

    Quanto tempo dura o clipe. Cobrado por segundo.

    Padrão
    5
    Valores aceitos
    -123456789101112131415161718192021222324252627282930
  • generate_audiobooleanOpcional

    Adiciona som combinando com a imagem: vozes, ambiente e efeitos.

    Padrão
    true
  • enable_prompt_expansionbooleanOpcional

    Deixa o modelo completar um prompt curto com detalhes.

    Padrão
    false
  • seedintegerOpcional

    Repetir o mesmo número dá um resultado reproduzível.

    Faixa
    0 – 2147483647
JSON Schema bruto
{
  "additionalProperties": false,
  "allOf": [
    {
      "if": {
        "required": [
          "last_image_url"
        ]
      },
      "then": {
        "required": [
          "image_url"
        ]
      }
    }
  ],
  "properties": {
    "aspect_ratio": {
      "description": "Output aspect ratio. Omit it to let the task adapt to the opening image; adaptive follows the input media and the intent.",
      "enum": [
        "16:9",
        "9:16",
        "1:1",
        "4:3",
        "3:4",
        "adaptive"
      ],
      "type": "string"
    },
    "duration_seconds": {
      "default": 5,
      "description": "Requested output length in seconds. Pass -1 for smart duration: the model picks the length from the prompt and any input media instead of a fixed number.",
      "enum": [
        -1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        15,
        16,
        17,
        18,
        19,
        20,
        21,
        22,
        23,
        24,
        25,
        26,
        27,
        28,
        29,
        30
      ],
      "type": "integer"
    },
    "enable_prompt_expansion": {
      "default": false,
      "description": "Allow the service to expand the submitted creative brief before generation.",
      "type": "boolean"
    },
    "enable_thinking": {
      "default": false,
      "description": "Let the model reason about the brief and the reference material before generating. Helps with complex references; slower. Switches on by itself when a reference file or link is given.",
      "type": "boolean"
    },
    "generate_audio": {
      "default": true,
      "description": "Request generated audio with the video.",
      "type": "boolean"
    },
    "image_url": {
      "contentMediaType": [
        "image/jpeg",
        "image/png",
        "image/webp",
        "image/gif"
      ],
      "description": "Opening-frame image.",
      "type": "string"
    },
    "last_image_url": {
      "contentMediaType": [
        "image/jpeg",
        "image/png",
        "image/webp",
        "image/gif"
      ],
      "description": "Optional last frame: the clip ends exactly on this image. Requires image_url.",
      "type": "string"
    },
    "prompt": {
      "description": "Describe the subject, action, camera, light, pacing, and boundaries for the shot.",
      "minLength": 1,
      "type": "string"
    },
    "resolution": {
      "default": "720p",
      "description": "Output resolution.",
      "enum": [
        "480p",
        "720p",
        "1080p"
      ],
      "type": "string"
    },
    "seed": {
      "description": "Random seed. Keep it fixed only for controlled comparisons, not as a frame-identical guarantee.",
      "maximum": 2147483647,
      "minimum": 0,
      "type": "integer"
    }
  },
  "required": [
    "image_url"
  ],
  "type": "object"
}

Um resultado real do Wan 3.0

PromptThe bottle rotates a quarter turn so the highlight travels across the glass, then returns to its starting angle. Locked camera, single soft key from the left, no music.
A mesma requisição pela API
{
  "model": "alibaba/wan-3.0/image-to-video",
  "input": {
    "prompt": "The bottle rotates a quarter turn so the highlight travels across the glass, then returns to its starting angle. Locked camera, single soft key from the left, no music.",
    "image_url": "https://media.popnow.ai/influencer/examples/marco.webp",
    "resolution": "1080p",
    "duration_seconds": 5,
    "seed": 20260907,
    "generate_audio": false
  }
}

Este resultado partiu de um arquivo enviado: coloque o seu link no lugar do link de exemplo.

Respostas, consultas e callbacks

Todos os modelos funcionam do mesmo jeito: crie uma tarefa e depois consulte ou espere o callback.

Veja o preço antes

cURL
curl -X POST https://api.popnow.ai/api/v1/jobs/quote \
  -H "Authorization: Bearer $POPNOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "alibaba/wan-3.0/image-to-video",
  "input": {
    "prompt": "A slow aerial shot drifting over a misty pine forest at sunrise",
    "image_url": "https://media.popnow.ai/influencer/examples/marco.webp",
    "resolution": "720p",
    "duration_seconds": 5
  }
}'

Mesmo corpo do createTask. Retorna a cobrança esperada e a máxima possível, sem rodar nada.

Aceita

HTTP
HTTP/1.1 202 Accepted

{
  "code": 200,
  "msg": "success",
  "data": {
    "taskId": "task_01k3m8x9q2z4v7n5p6r8s0t1w3",
    "state": "queued"
  },
  "request_id": "req_example_create"
}

HTTP 202 quer dizer que a tarefa foi aceita e os créditos estão reservados, ainda não cobrados. A cobrança final nunca passa da reserva.

Consultar status

cURL
curl "https://api.popnow.ai/api/v1/jobs/recordInfo?taskId=$TASK_ID" \
  -H "Authorization: Bearer $POPNOW_API_KEY"

Consulte a cada poucos segundos, espaçando cada vez mais, e pare quando state for succeeded, failed, canceled ou expired.

Tarefa pronta

JSON
{
  "code": 200,
  "msg": "success",
  "data": {
    "taskId": "task_01k3m8x9q2z4v7n5p6r8s0t1w3",
    "model": "alibaba/wan-3.0/image-to-video",
    "state": "succeeded",
    "output": {
      "assets": [
        {
          "url": "https://cdn.popnow.ai/tasks/task_01k3m8x9q2z4v7n5p6r8s0t1w3/output.mp4?signature=FROM_RESPONSE",
          "expiresAt": "2026-10-17T12:20:00Z",
          "mime": "video/mp4",
          "width": 1280,
          "height": 720,
          "durationSeconds": 5
        }
      ]
    },
    "settled": true
  },
  "request_id": "req_example_record"
}

Baixe pela url antes de expiresAt. Precisa de um link novo depois? Peça com POST /common/download-url.

Verificar um callback

Node.js
import { createHash, createHmac, timingSafeEqual } from "node:crypto";
import express from "express";

const app = express();
// express.raw keeps the exact bytes that were signed; express.json would not match.
app.post("/hooks/popnow", express.raw({ type: "application/json" }), (req, res) => {
  const timestamp = req.header("X-Webhook-Timestamp");
  const signature = req.header("X-Webhook-Signature") ?? "";
  const body = JSON.parse(req.body.toString("utf8"));
  const taskId = body.data?.taskId ?? body.task_id;
  const digest = createHash("sha256").update(req.body).digest("hex");
  const expected = createHmac("sha256", process.env.POPNOW_WEBHOOK_SECRET)
    .update(`${taskId}.${timestamp}.${digest}`)
    .digest("base64");
  const ok = expected.length === signature.length && timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
  // Check the signature first, then reject anything older than five minutes.
  if (!ok || Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return res.status(401).end();
  res.status(200).end(); // answer fast, then fetch the task and store its files
});

Com callBackUrl definida, enviamos a tarefa pronta para você. Confira a assinatura no corpo bruto antes de confiar nela.

Enviar um arquivo local

cURL
curl -X POST https://api.popnow.ai/api/v1/common/upload-url \
  -H "Authorization: Bearer $POPNOW_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"contentType": "image/png", "bytes": 482113}'

# PUT the file bytes to data.uploadUrl with every header in data.headers, then commit it:
curl -X POST https://api.popnow.ai/api/v1/files/$FILE_ID/commit \
  -H "Authorization: Bearer $POPNOW_API_KEY"
# The commit returns a popnow://f/... reference. Put it in any image, video or
# audio field of the task input instead of a public https URL.

Links https públicos funcionam como estão. Arquivos locais passam antes por upload-url e commit.