HiAPI
Blogue

Tutorial

Como usar a API kling-3.0-omni/transformation: repintura de vídeo com curl e Python

Oct 14, 2026
Como usar a API kling-3.0-omni/transformation: repintura de vídeo com curl e Python

kling-3.0-omni/transformation é o modelo de vídeo para vídeo do Kling 3.0 Omni: você fornece um vídeo de origem e um prompt de texto, e ele reescreve a aparência desse vídeo — cena, estilo, sujeito — preservando o movimento e a temporalidade originais. No hiapi, você o chama pelo mesmo endpoint assíncrono unificado de todos os outros modelos de geração: POST /v1/tasks. Este guia traz uma tabela de parâmetros verificada na prática, requisições curl prontas para copiar e colar, um cliente Python completo (que faz polling e baixa o resultado) e os padrões de produção necessários antes de integrá-lo a uma aplicação real (callback, idempotência, tratamento de erros).

Cada nome de campo, valor de enum e estrutura de resposta abaixo foi conferido contra a API real.

O que você vai construir + pré-requisitos

Um pequeno programa: envia uma tarefa de repintura, aguarda a conclusão e baixa o .mp4 repintado. Você precisa de duas coisas:

  1. Uma chave de API do hiapi. Crie uma no console do hiapi — o formato é semelhante a sk-.... Toda requisição usa Authorization: Bearer sk-<your-key>.
  2. Uma URL de vídeo de origem acessível publicamente. O modelo baixa seu vídeo no lado do servidor, então ela deve ser uma URL http(s) pública (seu próprio CDN, R2/S3 com objeto público etc.), e não um caminho de arquivo local. Apenas uma URL é permitida.

O modelo e seus parâmetros

A estrutura externa da requisição é {"model": ..., "input": {...}}. O schema de input é estrito — aceita apenas os três campos a seguir, e qualquer campo extra é rejeitado com 400.

Campo Tipo Obrigatório Descrição
prompt string Sim Descreve o estilo/cena/sujeito desejados. A intensidade da repintura também é ajustada aqui — não há parâmetros numéricos strength/fidelity.
video_urls array Sim Exatamente uma URL pública de vídeo de origem (minItems = 1, maxItems = 1).
resolution enum string Sim Um de 720p, 1080p, 4k.

Alguns pontos que costumam causar erro:

  • Não há parâmetro duration. A duração e a proporção da saída seguem o vídeo de origem (3–17,5 segundos), e a cobrança é feita pela duração final da saída.
  • O id do modelo já contém -omni: kling-3.0-omni/transformation (alguns outros endpoints Omni usam kling-3.0/...). Use esse id diretamente como valor de model.
  • A intensidade da repintura é guiada pelo prompt. Para uma alteração leve, escreva "repintura leve, preserve traços faciais e iluminação"; para uma alteração drástica, escreva "reimagine completamente como desenho animado 2D estilo cel-shading".

Exemplo mínimo funcional (curl)

# 1) Criar uma tarefa de repintura
curl -s https://api.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer sk-<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kling-3.0-omni/transformation",
    "input": {
      "prompt": "Repinte esta cena no estilo de animação em aquarela feita à mão, com textura suave de papel e luz quente de entardecer; preserve o movimento de câmera e o sujeito originais.",
      "video_urls": ["https://your-cdn.example.com/source-clip.mp4"],
      "resolution": "720p"
    }
  }'
# -> {"code":200,"data":{"taskId":"tk-hiapi-01..."},"message":"success"}

# 2) Fazer polling da tarefa até o estado terminal
curl -s https://api.hiapi.ai/v1/tasks/tk-hiapi-01... \
  -H "Authorization: Bearer sk-<your-key>"
# data.status passa por: queued -> handling -> archiving -> success
# Em caso de sucesso, data.output[0].url é o .mp4 repintado

O id de tarefa que você usa no polling vem de data.taskId na resposta de criação — não do id de nível superior. Os estados são queued / handling / archiving / success (terminal) ou fail; não presuma succeeded/completed.

Cliente Python completo (criar → polling → baixar)

import os
import time
import requests

API_KEY = os.environ["HIAPI_KEY"]            # sua chave sk-...
BASE = "https://api.hiapi.ai"
HEADERS = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json",
}


def create_restyle(source_video_url: str, prompt: str, resolution: str = "720p") -> str:
    body = {
        "model": "kling-3.0-omni/transformation",
        "input": {
            "prompt": prompt,
            "video_urls": [source_video_url],   # exatamente uma URL pública
            "resolution": resolution,           # "720p" | "1080p" | "4k"
        },
    }
    r = requests.post(f"{BASE}/v1/tasks", json=body, headers=HEADERS, timeout=30)
    r.raise_for_status()
    data = r.json()
    if data.get("code") != 200:
        raise RuntimeError(f"Envio rejeitado: {data}")
    return data["data"]["taskId"]


def wait_for_video(task_id: str, poll_s: int = 10, timeout_s: int = 900) -> str:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        r = requests.get(f"{BASE}/v1/tasks/{task_id}", headers=HEADERS, timeout=30)
        r.raise_for_status()
        data = r.json()["data"]
        status = data["status"]
        if status == "success":
            return data["output"][0]["url"]
        if status == "fail":
            raise RuntimeError(f"Tarefa falhou: {data.get('error')}")
        time.sleep(poll_s)                      # queued / handling / archiving
    raise TimeoutError(f"{task_id} não foi concluída em {timeout_s} segundos")


if __name__ == "__main__":
    task_id = create_restyle(
        source_video_url="https://your-cdn.example.com/source-clip.mp4",
        prompt=(
            "Repinte esta cena no estilo de animação em aquarela feita à mão, com textura suave de papel "
            "e luz quente de entardecer; preserve o movimento de câmera e o sujeito originais."
        ),
        resolution="720p",
    )
    print("Tarefa:", task_id)

    url = wait_for_video(task_id)
    print("URL do vídeo:", url)

    # O arquivo de saída fica em temp.hiapi.ai e expira (cerca de 7 dias). Baixe agora.
    clip = requests.get(url, timeout=120).content
    with open("restyled.mp4", "wb") as f:
        f.write(clip)
    print("restyled.mp4 salvo", len(clip), "bytes")

Coloque a chave em uma variável de ambiente e execute:

export HIAPI_KEY=sk-<your-key>
python restyle.py

Padrões de produção

Use callback em vez de polling frequente

Para qualquer cenário além de scripts, registre um webhook para não precisar manter um laço de polling. callback é um campo de nível superior — no mesmo nível de model e input, nunca dentro de input:

{
  "model": "kling-3.0-omni/transformation",
  "input": {
    "prompt": "Repinte esta cena no estilo de desenho animado 2D cel-shading, com contornos grossos; preserve o movimento original.",
    "video_urls": ["https://your-cdn.example.com/source-clip.mp4"],
    "resolution": "1080p"
  },
  "callback": { "url": "https://your-app.example.com/hooks/hiapi", "when": "final" }
}
  • callback.when aceita apenas final (o padrão). Quando a tarefa atinge o estado terminal, ele é enfileirado uma vez e dispara tanto em sucesso quanto em falha. A semântica de entrega é pelo menos uma vez, então o mesmo callback ainda pode chegar várias vezes (veja abaixo).
  • O corpo do POST entregue é idêntico ao objeto data obtido via GET /v1/tasks/<id> — assim, seu handler pode ler status, output[].url e error sem buscar novamente.
  • Colocar callback dentro de input falha no envio com o erro additional properties 'callback' not allowed (o schema de input de cada modelo é estrito).

Idempotência e semântica de entrega

Callbacks são pelo menos uma vez, e não exatamente uma vez — o mesmo taskId pode chegar várias vezes. Use taskId como chave do seu handler e torne a etapa "marcar como concluído + armazenar o vídeo" idempotente. O hiapi tenta novamente callbacks que retornam não 2xx/timeout no ritmo imediatamente → +1 minuto → +5 minutos → +20 minutos, no máximo 4 tentativas; seu endpoint deve retornar HTTP 2xx para interromper as tentativas.

Baixe a saída imediatamente

data.output[0].url aponta para temp.hiapi.ai e inclui expireAt (timestamp Unix, TTL de cerca de 7 dias). Após expirar, o objeto é apagado e a URL retorna 404 — consultar a tarefa novamente retorna a mesma URL, mas não regenera o arquivo. Assim que a tarefa for concluída com sucesso, copie os bytes para o seu próprio armazenamento imediatamente.

Tratamento de erros

Três formas de falha que você precisa tratar com branches distintos:

  • Erro de requisição (HTTP 400) — estrutura plana, nenhuma tarefa criada: {"code":400,"data":null,"error_code":"INVALID_REQUEST","message":"invalid input: resolution: value must be one of '720p', '1080p', '4k'"}
  • Falha de autenticação (HTTP 401) — estrutura aninhada: {"error":{"code":"permission_denied","type":"hiapi_error", ...}}
  • Falha da tarefa — o envio retorna 200 e um taskId, mas a consulta posterior mostra data.status == "fail", com data.error. Tarefas com falha não são cobradas (o valor pré-reservado é reembolsado quando a tarefa falha definitivamente). Casos em que a URL de origem está inacessível ou não pode ser baixada aparecem aqui.

Custos

kling-3.0-omni/transformation é cobrado por segundo de saída, com tarifa que varia conforme a resolução solicitada (720p a $0,143/s, 1080p a $0,193/s, 4k a $0,479/s, verificado em 21 de outubro de 2026). Antes de processar vídeos em lote, consulte a página de preços do hiapi para ver as tarifas por segundo atuais — os custos de tarefas de vídeo acumulam muito mais rápido que os de tarefas de imagem.

Leitura relacionada

Perguntas frequentes

Como controlar a intensidade da repintura? Por meio do prompt, não de parâmetros. Não há campos strength, fidelity ou creativity. Para edições leves, escreva "repintura leve, preserve rosto e iluminação"; para edições drásticas, escreva "reimagine completamente como

Artigos relacionados

Ver todos os artigos →

Comece a criar com artefactos de IA persistentes

Obtenha a sua chave de API e chame modelos de imagem, vídeo e áudio através de uma única API baseada em tasks.

Ler a documentação da API