Pular para o conteúdo principal
A geração de vídeo é assíncrona. Envie um job, salve o queue_id e depois faça polling em /video/retrieve até a resposta ser video/mp4.

Endpoints

EndpointFinalidadeObrigatório
POST /video/quoteObter preço em USD antes de gerarNão
POST /video/queueEnviar requisição de geraçãoSim
POST /video/retrieveVerificar status ou baixar vídeoSim
POST /video/completeExcluir vídeo do storageNão

Passo 1: Coloque a geração na fila

Requisição:
POST https://api.venice.ai/api/v1/video/queue
Authorization: Bearer $VENICE_API_KEY
Content-Type: application/json

{
  "model": "wan-2.5-preview-text-to-video",
  "prompt": "A gondola gliding through Venice canals at sunset",
  "duration": "5s",
  "resolution": "720p",
  "aspect_ratio": "16:9"
}
Resposta (200):
{
  "model": "wan-2.5-preview-text-to-video",
  "queue_id": "123e4567-e89b-12d3-a456-426614174000"
}
Para modelos Grok Imagine Private, a resposta de fila inclui um campo extra download_url:
{
  "model": "grok-imagine-text-to-video-private",
  "queue_id": "123e4567-e89b-12d3-a456-426614174000",
  "download_url": "https://private-share.venice.ai/v1/share/read/..."
}
O download_url é uma URL pré-assinada que você usa para baixar o vídeo finalizado em vez de lê-lo na resposta de retrieve. É retornado apenas uma vez na resposta de fila, então persista-o ao lado do queue_id. Isso se aplica às quatro variantes Grok Imagine Private:
  • grok-imagine-text-to-video-private
  • grok-imagine-image-to-video-private
  • grok-imagine-reference-to-video-private
  • grok-imagine-video-to-video-private
Ao contrário das variantes públicas grok-imagine-*-video, modelos Grok Imagine Private não são cobrados por rejeições de moderação de conteúdo, então você só paga por gerações bem-sucedidas. Salve model, queue_id e download_url (se presente) para todas as chamadas subsequentes. Para modelos privados, download_url é como você busca o arquivo finalizado quando o job está concluído. O link é de curta duração e propósito único: está ali para entregar o MP4 a você, não para servir como URL de longo prazo ou amplamente compartilhada. Se um download for interrompido, você pode repetir o mesmo GET algumas vezes do mesmo ambiente até o arquivo concluir. Essas tentativas são para recuperar de instabilidades de rede — não para fazer polling do mesmo link indefinidamente, compartilhá-lo entre muitos clientes ou embuti-lo como uma URL de mídia permanente. Padrões assim normalmente aparecem como 429 ou 410, o que pode ser surpreendente se você esperava que o link se comportasse como hospedagem de arquivos normal. Para confiabilidade, as requisições GET devem ter origem de uma única rede cliente. Há alguma flexibilidade se seu IP mudar uma vez (por exemplo, você desconecta uma VPN e tenta de novo), mas grande variação nos IPs de origem geralmente não funciona. A URL permanece válida por até 24 horas ou até o objeto ser removido.
Se você precisa de uma URL estável, reprodução pública ou acesso repetido ao longo do tempo, salve o arquivo no seu próprio storage primeiro e sirva a partir de lá.
Privacidade: revogue o link com DELETE Quando terminar de buscar o arquivo — ou se decidir não mantê-lo — você pode chamar DELETE na mesma download_url. Nenhuma chave de API Venice é necessária nessa requisição. Isso é opcional, mas recomendado quando a privacidade importa, porque alguns proxies e middleboxes fora da Venice mantêm logs de URLs completas, e excluir o link é a maneira mais simples de reduzir a janela em que a URL pré-assinada existe.
curl -X DELETE "$DOWNLOAD_URL"
Fluxo: faça polling em /video/retrieve até COMPLETED → faça GET no download_url (tente novamente de leve se a transferência cair) → salve o arquivo onde você precisa → DELETE no download_url se quiser invalidar o link → opcionalmente chame /video/complete se ainda usa limpeza baseada em fila.

Passo 2: Polling para conclusão

Requisição:
POST https://api.venice.ai/api/v1/video/retrieve
Authorization: Bearer $VENICE_API_KEY
Content-Type: application/json

{
  "model": "wan-2.5-preview-text-to-video",
  "queue_id": "123e4567-e89b-12d3-a456-426614174000"
}
A resposta depende do status:
Content-TypeSignificadoAção
application/jsonAinda processandoAguarde 5s, faça polling novamente
video/mp4ConcluídoO corpo da resposta é o arquivo de vídeo
application/json com "COMPLETED"Concluído, vídeo não inlineFaça GET no download_url da resposta de fila
Resposta de processamento (200, application/json):
{
  "status": "PROCESSING",
  "average_execution_time": 145000,
  "execution_duration": 53200
}
Os tempos estão em milissegundos. Use average_execution_time para estimar a espera restante. Resposta de conclusão (200, video/mp4): O corpo da resposta é dado binário cru de vídeo. Salve no arquivo. Resposta de conclusão (200, application/json com "COMPLETED"): Para modelos que retornaram um download_url na fila, o retrieve sempre retorna JSON. Busque o vídeo com GET download_url (sem cabeçalho de autenticação). Veja Links de download privados para como essas URLs funcionam, retries e DELETE opcional.

Passo 3: Limpeza (opcional)

Ou exclua automaticamente na recuperação:
{
  "model": "wan-2.5-preview-text-to-video",
  "queue_id": "123e4567-e89b-12d3-a456-426614174000",
  "delete_media_on_completion": true
}
Ou chame /video/complete após salvar:
POST https://api.venice.ai/api/v1/video/complete
Authorization: Bearer $VENICE_API_KEY
Content-Type: application/json

{
  "model": "wan-2.5-preview-text-to-video",
  "queue_id": "123e4567-e89b-12d3-a456-426614174000"
}
Resposta (200):
{
  "success": true
}

Exemplo completo

import os
import time
import requests

API_KEY = os.environ.get("VENICE_API_KEY")
BASE_URL = "https://api.venice.ai/api/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"}

# Enfileira
resp = requests.post(f"{BASE_URL}/video/queue", headers=HEADERS, json={
    "model": "wan-2.5-preview-text-to-video",
    "prompt": "A gondola gliding through Venice canals at sunset",
    "duration": "5s",
    "resolution": "720p",
    "aspect_ratio": "16:9"
})
data = resp.json()
model, queue_id = data["model"], data["queue_id"]
download_url = data.get("download_url")

# Polling
while True:
    resp = requests.post(f"{BASE_URL}/video/retrieve", headers=HEADERS,
                         json={"model": model, "queue_id": queue_id})
    if "video/mp4" in resp.headers.get("Content-Type", ""):
        with open("output.mp4", "wb") as f:
            f.write(resp.content)
        break
    if resp.json().get("status") == "COMPLETED" and download_url:
        with open("output.mp4", "wb") as f:
            f.write(requests.get(download_url).content)
        break
    time.sleep(5)

# Limpeza
requests.post(f"{BASE_URL}/video/complete", headers=HEADERS,
              json={"model": model, "queue_id": queue_id})

Parâmetros da requisição

Requisição de fila

ParâmetroTipoObrigatórioPadrãoDescrição
modelstringSim-ID do modelo. Use wan-2.5-preview-text-to-video para text-to-video, wan-2.5-preview-image-to-video para image-to-video
promptstringSim-O que gerar. Máximo de 2500 caracteres
negative_promptstringNão"low resolution, error, worst quality, low quality, defects"O que evitar
durationstringSim-"5s" ou "10s"
resolutionstringNão"720p""480p", "720p" ou "1080p"
aspect_ratiostringCondicional-Dependente do modelo. Obrigatório para modelos que expõem opções de aspect ratio; omita para modelos que não suportam seleção de aspect ratio
audiobooleanCondicionaltrue (quando suportado)Apenas válido para modelos com supportsAudioConfig: true; omita para modelos sem suporte a configuração de áudio
image_urlstringApenas para image-to-video-URL ou data URL base64 da imagem de origem
audio_urlstringCondicional-URL ou data URL base64 de áudio de referência para modelos que suportam entrada de áudio
A validação da fila é específica do modelo. Verifique /models?type=video para os campos de requisição suportados por cada modelo antes de chamar /video/queue.

Requisição de cotação

ParâmetroTipoObrigatórioPadrãoDescrição
modelstringSim-ID do modelo para precificar
durationstringSim-"5s" ou "10s"
resolutionstringNão"720p""480p", "720p" ou "1080p"
aspect_ratiostringCondicional-Inclua quando o modelo selecionado suportar ou exigir seleção de aspect ratio
audiobooleanCondicionaltrue (quando suportado)Apenas válido para modelos com supportsAudioConfig: true

Requisição de retrieve

ParâmetroTipoObrigatórioPadrãoDescrição
modelstringSim-Da resposta de fila
queue_idstringSim-Da resposta de fila
delete_media_on_completionbooleanNãofalseExclui vídeo após recuperação bem-sucedida

Requisição de complete

ParâmetroTipoObrigatórioDescrição
modelstringSimDa resposta de fila
queue_idstringSimDa resposta de fila

Image to Video

Para modelos image-to-video, passe a imagem de origem via image_url. O prompt descreve o movimento desejado, não o conteúdo da imagem.
{
  "model": "wan-2.5-preview-image-to-video",
  "prompt": "Camera slowly zooms in as leaves rustle in the wind",
  "image_url": "https://example.com/image.jpg",
  "duration": "5s"
}
Ou com base64:
{
  "model": "wan-2.5-preview-image-to-video",
  "prompt": "Camera slowly zooms in as leaves rustle in the wind",
  "image_url": "data:image/jpeg;base64,/9j/4AAQ...",
  "duration": "5s"
}

Cotação de preço

Obtenha o custo exato antes de gerar. Envie apenas inputs de preço (model, duration e opcionalmente resolution, aspect_ratio, audio): Requisição:
{
  "model": "wan-2.5-preview-text-to-video",
  "duration": "10s",
  "resolution": "1080p"
}
Resposta:
{
  "quote": 0.085
}
A cotação está em USD.

Erros

StatusRetornado porSignificadoAção
400queue, quote, retrieve, completeParâmetros inválidosVerifique o corpo da requisição contra o schema
401queue, retrieve, completeFalha de autenticaçãoVerifique a chave de API
402queueSaldo insuficienteAdicione fundos
404retrieve, download_urlMídia não encontrada (inválida, expirada ou excluída)Verifique model/queue_id ou re-enfileire
410download_urlURL pré-assinada expirou, foi totalmente usada ou revogada (por exemplo, após DELETE)Inicie uma nova geração se precisar de outro arquivo; cada link é intencionalmente de curta duração
429download_urlLimite de taxa — frequentemente por muitos retries ou buscas repetidas do mesmo linkConclua o download (algumas tentativas são aceitáveis se a conexão cair), salve uma cópia local e use DELETE se quiser limpar o link; mantenha acesso contínuo no seu próprio storage
413queuePayload muito grandeReduza o tamanho da imagem/áudio
422queue, retrieveViolação de conteúdoModifique o prompt
500queue, retrieve, completeFalha de inferência/processamentoTente novamente com backoff; contate o suporte se persistir
503retrieveModelo em capacidade máximaTente novamente com backoff

Estratégia de polling

  1. Faça polling de /video/retrieve em um intervalo (por exemplo, a cada 5 segundos)
  2. Se Content-Type for application/json e status for "PROCESSING", aguarde e faça polling novamente. Use average_execution_time e execution_duration (milissegundos) para estimar o tempo restante
  3. Se Content-Type for video/mp4, salve o corpo da resposta como seu arquivo de saída
  4. Se Content-Type for application/json e status for "COMPLETED", faça GET no download_url da resposta de fila para buscar o vídeo (veja Links de download privados)
  5. Se você usou download_url, considere DELETE nessa URL quando terminar para reduzir por quanto tempo a URL pré-assinada existe; depois opcionalmente defina delete_media_on_completion: true no retrieve ou chame /video/complete para limpeza baseada em fila
  6. Trate 404 como mídia inválida, expirada ou excluída; trate 500/503 com retries/backoff

Modelos disponíveis

Veja Modelos de vídeo para a lista de modelos atual e preços.