minimax/h3-lora/video-extendA partir de 38 créditos por um clipe de 5 segundos· Estender vídeo

Continue um clipe com MiniMax H3 LoRA: o último quadro do seu vídeo abre um segmento novo de 3 a 15 segundos e você recebe um arquivo só, com o original e a continuação unidos, em 480p, 540p, 768p ou 1080p.

Chame com o nome de modelo minimax/h3-lora/video-extend em POST /jobs/createTask, a partir de 38 créditos por um clipe de 5 segundos (US$ 0,38). 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 3 a 15 s
  • Quadro inicial e final
  • Até 9 imagens de referência
  • 7 proporções
  • Carrega seus próprios LoRAs
Nome do modelominimax/h3-lora/video-extend
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": "minimax/h3-lora/video-extend",
  "input": {
    "prompt": "A slow aerial shot drifting over a misty pine forest at sunrise",
    "video_url": "https://media.popnow.ai/effects/flower-bloom-1abd6efb.mp4",
    "resolution": "480p",
    "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 480p7,5US$ 0,075
resolution 540p11,25US$ 0,11
resolution 768p15US$ 0,15
resolution 1080p30US$ 0,30

1 crédito = US$ 0,01 · Todas as opções e preços: GET /models/minimax/h3-lora/video-extend

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

Limites

Duração do clipe
3–15 s
Resoluções
480p · 540p · 768p · 1080p
Tamanho do prompt (caracteres)
7,000
Clipe de entrada mais longo
60 s

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.

  • promptstringObrigatório

    Describe what happens next: the action that follows, the camera move and the sound.

    Faixa
    1 – 7000 chars
  • video_urlstringObrigatório

    O clipe a ser trabalhado.

    Faixa
    1 – … chars · video/mp4, video/webm, video/quicktime
  • last_image_urlstringOpcional

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

    Faixa
    image/jpeg, image/png, image/webp, image/gif
  • resolutionstringOpcionalMuda o preço

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

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

    Quanto tempo dura o clipe. Cobrado por segundo.

    Padrão
    5
    Faixa
    3 – 15
  • lorasarray<object>Opcional

    Carregue seus arquivos LoRA para fixar um estilo ou personagem.

    Padrão
    []
    Faixa
    0 – 3 items
    Campos internos
    • loras[].pathstringObrigatório

      Direct URL of a LoRA weights file.

      Faixa
      1 – … chars · application/octet-stream
    • loras[].scalenumberObrigatório

      Weight strength from zero to four.

      Padrão
      1
      Faixa
      0 – 4
  • seedintegerOpcional

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

    Faixa
    0 – 2147483647
JSON Schema bruto
{
  "additionalProperties": false,
  "properties": {
    "duration_seconds": {
      "default": 5,
      "description": "Length of the new segment in whole seconds, from 3 to 15. The source clip is added on top and is not billed.",
      "maximum": 15,
      "minimum": 3,
      "type": "integer"
    },
    "last_image_url": {
      "contentMediaType": [
        "image/jpeg",
        "image/png",
        "image/webp",
        "image/gif"
      ],
      "description": "Optional target end frame: the new segment comes to rest on this picture.",
      "format": "uri",
      "type": "string"
    },
    "loras": {
      "default": [],
      "description": "Up to three LoRA weight files trained for MiniMax H3, each with its own strength, applied to the new segment. Reuse the ones used for the source clip to keep the style consistent.",
      "items": {
        "additionalProperties": false,
        "properties": {
          "path": {
            "contentMediaType": [
              "application/octet-stream"
            ],
            "description": "Direct URL of a LoRA weights file.",
            "format": "uri",
            "minLength": 1,
            "type": "string"
          },
          "scale": {
            "default": 1,
            "description": "Weight strength from zero to four.",
            "maximum": 4,
            "minimum": 0,
            "type": "number"
          }
        },
        "required": [
          "path",
          "scale"
        ],
        "type": "object"
      },
      "maxItems": 3,
      "type": "array"
    },
    "prompt": {
      "description": "Describe what happens next: the action that follows, the camera move and the sound.",
      "maxLength": 7000,
      "minLength": 1,
      "type": "string"
    },
    "resolution": {
      "default": "480p",
      "description": "Resolution of the new segment. Match your source clip; it sets how sharp the new part is generated.",
      "enum": [
        "480p",
        "540p",
        "768p",
        "1080p"
      ],
      "type": "string"
    },
    "seed": {
      "description": "Random seed for controlled comparisons.",
      "maximum": 2147483647,
      "minimum": 0,
      "type": "integer"
    },
    "video_url": {
      "contentMediaType": [
        "video/mp4",
        "video/webm",
        "video/quicktime"
      ],
      "description": "The clip to continue: MP4, MOV or WebM, up to 60 seconds. Its last frame opens the new segment, and the result is your clip with the new segment joined on.",
      "format": "uri",
      "minLength": 1,
      "type": "string"
    }
  },
  "required": [
    "prompt",
    "video_url"
  ],
  "type": "object"
}

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": "minimax/h3-lora/video-extend",
  "input": {
    "prompt": "A slow aerial shot drifting over a misty pine forest at sunrise",
    "video_url": "https://media.popnow.ai/effects/flower-bloom-1abd6efb.mp4",
    "resolution": "480p",
    "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": "minimax/h3-lora/video-extend",
    "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.