Pular para o conteúdo
Testar o chatObter chave de API

Vídeo

Geração de vídeo é assíncrona. Diferente dos outros endpoints, uma chamada não te dá um resultado direto: você enfileira um job, consulta seu progresso, e libera a mídia armazenada quando termina.

Copia as instruções de configuração desta página, para colar no seu agente de código.
Ver o prompt
Me ajude a configurar isto para usar a Bayle AI, uma API compatível com a OpenAI. Guia completo: https://docs.bayle.ai/pt-br/guides/video/

Objetivo: gerar um vídeo pela Bayle a partir deste projeto: cotar, enfileirar, consultar, salvar, liberar.

1. Escolha um modelo de vídeo: curl -s "https://api.bayle.ai/models?type=video" | jq -r '.data[].id'
   Me mostre a lista e deixe eu escolher o VIDEO_MODEL_ID.
2. Cote o job primeiro. Esta chamada não precisa de key:
   curl https://api.bayle.ai/video/quote -H "Content-Type: application/json" -d '{"model": "VIDEO_MODEL_ID", "duration": "5s", "resolution": "720p", "audio": false}'
   Me mostre o preço e espere meu aval antes de gastar qualquer coisa.
3. Enfileire: POST https://api.bayle.ai/video/queue com uma key bearer e {"model": "VIDEO_MODEL_ID", "prompt": "A paper boat drifting down a rain gutter.", "duration": "5s"}. Guarde o `queue_id` devolvido. Para imagem para vídeo, adicione `image_url` (uma URL https pública ou um data: URI).
4. Um 409 com o código needs_consent significa que o modelo exige uma atestação de consentimento para rostos. Nada foi cobrado. Me mostre `consent.policy_text` e só reenvie o corpo idêntico com o objeto `consents` (os três booleanos true) se eu confirmar que a pessoa na mídia consentiu.
5. Consulte POST /video/retrieve com {"model": "VIDEO_MODEL_ID", "queue_id": "QUEUE_ID"} a cada uns 10 segundos. Um 200 é JSON (ainda rodando: `status`, `execution_duration`) ou `video/mp4` (pronto). Ramifique pelo Content-Type da resposta, nunca por um campo do corpo. Alguns modelos devolvem no JSON uma `download_url` pré-assinada: baixe-a direto, sem credencial. Trate os dois casos e salve o vídeo como out.mp4.
6. Libere a mídia armazenada: POST /video/complete com o mesmo model e queue_id. Um 400 informando que o job não foi encontrado é esperado depois de um modelo que devolveu os bytes inline; não trate como falha.
7. Teste: rode o fluxo inteiro uma vez com a menor duração e me mostre o tamanho do out.mp4.

Regras:
1. A base URL é https://api.bayle.ai exatamente como está escrita. Não acrescente nenhum caminho a ela.
2. Leia a key da variável de ambiente BAYLE_API_KEY. Nunca escreva a key em um arquivo que você criar, em um comando, em um commit nem no chat. Onde a ferramenta guarda a key na própria tela de configurações, me diga onde colar. Se BAYLE_API_KEY não estiver definida, pare e peça que eu crie uma key em https://chat.bayle.ai/developers e a exporte.
3. Pegue os ids de modelo só de GET https://api.bayle.ai/models (sem key). Nunca chute um.
4. Termine com uma requisição de teste de verdade, me mostre o resultado e liste os arquivos que você alterou.

Quatro endpoints, em ordem:

Endpoint Finalidade Key exigida
POST /video/quote Cotar um job antes de confirmá-lo Não
POST /video/queue Iniciar o job, obter um queue_id Sim
POST /video/retrieve Consultar o progresso, depois obter o vídeo Sim
POST /video/complete Liberar a mídia armazenada Sim
  1. Nenhuma credencial necessária, então você pode cotar um job antes de ter uma.

    Janela do terminal
    curl https://api.bayle.ai/video/quote \
    -H "Content-Type: application/json" \
    -d '{"model": "VIDEO_MODEL_ID", "duration": "5s", "resolution": "720p", "audio": false}'

    O preço decimal é retornado exatamente como calculado, nunca decodificado e recodificado, então é seguro compará-lo ou armazená-lo ao pé da letra.

  2. Janela do terminal
    curl https://api.bayle.ai/video/queue \
    -H "Authorization: Bearer $BAYLE_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
    "model": "VIDEO_MODEL_ID",
    "prompt": "A paper boat drifting down a rain gutter.",
    "duration": "5s"
    }'

    Você recebe um queue_id de volta. Guarde-o: as próximas duas chamadas precisam dele.

    Para image-to-video, adicione image_url, uma URL https pública ou uma data: URI.

    Se isso retornar 409, veja Consentimento abaixo.

  3. Consulte a cada 10 segundos, aproximadamente. Geração de vídeo demora consideravelmente mais que os endpoints síncronos, então não espere que a primeira chamada já esteja pronta.

    Janela do terminal
    curl https://api.bayle.ai/video/retrieve \
    -H "Authorization: Bearer $BAYLE_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"model": "VIDEO_MODEL_ID", "queue_id": "QUEUE_ID"}'

    Esse endpoint retorna uma de duas coisas completamente diferentes sob o mesmo status 200, e qual delas você recebe depende de o job ter terminado ou não. Veja Trate pelo Content-Type.

  4. Janela do terminal
    curl https://api.bayle.ai/video/complete \
    -H "Authorization: Bearer $BAYLE_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"model": "VIDEO_MODEL_ID", "queue_id": "QUEUE_ID"}'

    A Bayle não mantém registro de um queue_id, então chamar isso duas vezes é respondido pelo seu próprio mérito em vez de interrompido antecipadamente.

POST /video/retrieve retorna um documento JSON de status ou o vídeo bruto, ambos com 200. Trate pelo Content-Type da resposta, não por um campo do corpo. Fazer parse da resposta como JSON incondicionalmente vai falhar no vídeo.

Content-Type Significado
application/json Ainda rodando. Carrega status, average_execution_time, execution_duration.
video/mp4 Terminado. O corpo é o vídeo.
import time, httpx, pathlib
body = {"model": "VIDEO_MODEL_ID", "queue_id": queue_id}
headers = {"Authorization": f"Bearer {api_key}"}
while True:
res = httpx.post("https://api.bayle.ai/video/retrieve", json=body, headers=headers, timeout=120)
res.raise_for_status()
if res.headers["content-type"].startswith("video/"):
pathlib.Path("out.mp4").write_bytes(res.content)
break
status = res.json()
# Some models put a download_url here instead of returning the bytes above.
if url := status.get("download_url"):
pathlib.Path("out.mp4").write_bytes(httpx.get(url, timeout=300).content)
break
print(status.get("status"), status.get("execution_duration"))
time.sleep(10)

A Bayle não envia header de retry-delay e não impõe uma cadência de consulta. A cifra de 10 segundos é uma orientação para você, não um sinal a ser interpretado.

Alguns modelos entregam o vídeo finalizado através de um download_url no documento de status em vez de como bytes vindos de retrieve. É uma URL pré-assinada que seu próprio client busca diretamente: ela não exige credencial, e não passa de volta pela Bayle. Trate as duas formas, como os exemplos acima fazem.

Alguns modelos exigem um atestado de consentimento antes de gerar mídia contendo um rosto. A primeira chamada a queue volta 409, e nada é cobrado:

{
"error": { "code": "needs_consent", "message": "..." },
"consent_flow": "...",
"face_media_roles": ["..."],
"consent": { "consent_version": "...", "policy_text": "..." },
"docs_url": "https://docs.bayle.ai"
}

consent.policy_text é o texto a ser mostrado para a pessoa cuja imagem aparece na mídia, e face_media_roles indica quais partes da sua requisição precisam dessa confirmação.

Para prosseguir, reenvie o corpo da requisição idêntico ao mesmo endpoint com um objeto consents adicionado. Os três booleanos precisam ser literalmente true:

{
"model": "VIDEO_MODEL_ID",
"prompt": "A paper boat drifting down a rain gutter.",
"duration": "5s",
"consents": {
"seedance": {
"confirmed_terms_and_privacy": true,
"confirmed_legal_right": true,
"confirmed_screening_acknowledged": true
}
}
}

Não existe um token de consentimento para carregar, nenhuma versão para você enviar de volta, e nenhum endpoint separado para a nova tentativa. É a mesma chamada POST /video/queue com mais um campo. A chave dentro de consents nomeia a família do modelo, que o corpo do 409 informa.

Só ateste em nome de alguém que realmente deu consentimento. É para isso que a confirmação existe.