Geração de mídia
POST /api/media/generate — geração assíncrona de imagens, vídeo, TTS, música e 3D. Parâmetros model, prompt, opts. Faça polling com GET /api/media/jobs/{id}.
Geração assíncrona de mídia: imagens, vídeo, locução (TTS), conversão de fala em texto, música e 3D. Você cria uma tarefa e consulta o resultado. A lista completa de modelos está no catálogo de media-models; webhooks, erros e faturamento estão na seção de webhook.
Criar parâmetros
| Parâmetro | Tipo | Descrição |
|---|---|---|
modelreq. | string | Um nome de modelo de mídia, por exemplo veo-3.1 ou gpt-image-2 (consulte o catálogo). |
promptreq. | string | Descrição textual. |
opts | object | Opções adicionais de geração (dependentes do modelo): resolução, duração e assim por diante. |
Criar e consultar
A criação retorna 202 com { ok: true, jobId, status: "processing" }. Consulte GET /api/media/jobs/{jobId} até status: "success" e, em seguida, obtenha o resultUrls.
# 1. create a generation job
curl https://getvibeapi.com/api/media/generate \
-H "Authorization: Bearer $GETVIBE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "veo-3.1",
"prompt": "a cat on a skateboard, slow motion"
}'
# → {"ok":true,"jobId":"...","status":"processing"}ok: false e nenhuma cobrança será feita. Os preços do site são indicativos; a cobrança exata é retornada no cabeçalho x-pv-cost-rub de cada resposta aceita. Os corpos dos streams permanecem inalterados por padrão; envie x-pv-cost: 1 para adicionar o custo ao evento final de uso desse protocolo.Parâmetros avançados (opts)
Além de model e prompt, você pode passar opções extras em opts. O conjunto depende do modelo. O contrato completo legível por máquina está disponível em GET /api/model-capabilities (ou em GET /api/model-capabilities/{model} para um modelo específico).
| Parâmetro | Tipo | Descrição |
|---|---|---|
aspect_ratio | string | Aspect ratio: 1:1, 16:9, 9:16, 4:3, 3:4. |
duration | string|number | Duração do vídeo em segundos (5, 10, 15). |
resolution | string | Resolution: 480p, 720p, 1080p, 4K. |
image_url | string (URL) | Imagem de origem para I2V / imagem para imagem. |
negative_prompt | string | O que excluir da geração (qwen-image, wan-2-7). |
guidance | number | Escala de orientação — aderência ao prompt (flux-2, qwen-image, seedance). |
seed | number | Seed para um resultado reproduzível (flux-2). |
stability | number | Estabilidade 0–1 (hailuo, happyhorse, seedance, TTS). |
camera | string | Movimento da câmera, por exemplo, "pan left" (kling-3.0, hailuo). |
first_frame_url | string (URL) | First frame for I2V (kling-3.0, wan-2-7). |
last_frame_url | string (URL) | Último quadro para I2V (seedance, kling-3.0, wan-2-7). |
reference_image | string (URL) | Referência de estilo/personagem (happyhorse). |
similarity_boost | number | Similaridade da voz de 0–1 (ElevenLabs TTS). |
speed | number | Taxa de fala 0.5–2 (ElevenLabs TTS). |
GET /api/model-capabilities/{model}.Seus próprios arquivos: base64 em vez de um link
As opções de URL (image_url, input_urls, mask_url e as demais) são links que o provedor busca, portanto aceitam apenas endereços https:// públicos. Uma string data:image/...;base64,… inline em um desses campos é rejeitada com 400.
Para enviar seu próprio arquivo, use o campo *_base64 correspondente: o serviço armazena os bytes, publica o arquivo e repassa o link resultante ao provedor. Até 16 arquivos por solicitação em input_base64.
| Parâmetro | Tipo | Descrição |
|---|---|---|
image_base64 | string | Imagem de origem. Substitui image_url. |
mask_base64 | string | Máscara de inpainting (somente image/*). Substitui mask_url. |
input_base64 | string[] | Referências para image-to-image e múltiplas entradas. Substitui input_urls. |
audio_base64 | string | Áudio de origem. Substitui audio_url. |
video_base64 | string | Vídeo de origem. Substitui video_url. |
data:image/png;base64,… completa, incluindo o prefixo — o tipo de arquivo é lido dela.Contrato da solicitação: strict, quote_id, max_price_rub
POST /api/media/generate e POST /api/media/price aceitam o mesmo corpo, então você pode fazer uma cotação e depois enviá-lo sem alterações. Não há outros campos de nível superior: um campo desconhecido é recusado em ambos os endpoints com 400 e o código unknown_field informando seu nome (field, fields), com ou sem strict. Os parâmetros de geração ficam dentro de opts.
| Parâmetro | Tipo | Descrição |
|---|---|---|
modelreq. | string | ID público do modelo ou uma de suas rotas (base:alias). |
prompt | string | Texto; obrigatório somente quando a operação do modelo exigir isso. |
opts | object | Opções do modelo. Esquema exato: operations[].requestJsonSchema em GET /v1/model-capabilities/{model}. |
strict | boolean | Modo estrito (ou o cabeçalho x-getvibe-strict: 1): uma solicitação que não fosse executada exatamente como escrita (um parâmetro removido, um valor limitado, uma chave fora do contrato do modelo) é recusada com 422 strict_validation_failed e uma lista de violações, antes de qualquer cotação ou cobrança. Um campo documentado que o modelo aceita e ignora (duration em modelos baseados no comprimento da fonte) não é uma violação: ele retorna com um aviso param_ignored. |
quote_id | string | mq_… de POST /api/media/price. O job é executado somente nesse preço; uma cotação obsoleta, usada ou redirecionada é recusada com 409/422 antes de qualquer execução. |
max_price_rub | number | Limite máximo para este trabalho na moeda da conta. Se a cotação for maior: 422 media_max_price_exceeded e nada será executado. Um trabalho medido nunca será cobrado acima desse limite. |
webhook_url | string | URL https pública que recebe uma notificação de conclusão assinada. |
Arquivos por id (API de arquivos)
Qualquer arquivo de origem pode ser enviado de três maneiras: como um link (image_url, audio_url, video_url…), como bytes inline (image_base64, audio_base64, video_base64…) ou como o id do seu próprio arquivo enviado por POST /v1/files. Os campos de id estão listados no requestJsonSchema de cada operação e são aceitos no modo estrito.
| Parâmetro | Tipo | Descrição |
|---|---|---|
image_file_id | string | Em vez de image_url. |
audio_file_id | string | Em vez de audio_url. |
video_file_id | string | Em vez de video_url. |
mask_file_id | string | Em vez de mask_url. |
first_frame_file_id / last_frame_file_id | string | Instead of first_frame_url / last_frame_url. |
input_file_ids | string[] | Anexado a input_urls. |
reference_*_file_ids | string[] | Appended to reference_image_urls / reference_audio_urls / reference_video_urls. |
Vídeo cobrado de acordo com a duração do arquivo de entrada
Para modelos cuja duração de saída segue a duração de uma faixa enviada — kling-ai-avatar, omnihuman-v2, omnihuman-2-0, omnihuman-v1.5, omnihuman-1-5, volcengine-lipsync (audio), kling-motion-control, wan-animate, topaz-video-upscale, p-video-edit (video), lipsync-2-pro, sync-3, react-1 (ambas as entradas) — /api/media/price e a verificação prévia de max_price_rub em /api/media/generate medem esse arquivo no servidor (link, URI data:, base64 ou *_file_id) e calculam o preço com base nos segundos medidos. A resposta inclui sourceSeconds (outputSeconds para lip-sync), e estimateReason informa que a duração foi medida. Se não for possível ler o arquivo, o preço mantém sua base anterior (um segundo, a estimativa do catálogo ou o máximo da rota), e estimateReason informa isso. A cobrança corresponde à taxa por segundo × os segundos efetivamente renderizados, nunca acima de max_price_rub. opts.duration nesses modelos é aceito e ignorado, com um aviso param_ignored.
Clonagem de voz
Create: { name, consent: true, engine, audio_url | audio_base64 } or several recordings samples: [{ audio_url } | { audio_base64 }, …] (engine: "elevenlabs" only). An ElevenLabs voice is used by voice-clone-tts and by the Voice Changer (elevenlabs-voice-changer). Appending recordings to an ElevenLabs voice is free. Every recording is downloaded and measured before the supplier is called: a refusal changes and charges nothing.
| Parâmetro | Tipo | Descrição |
|---|---|---|
one recording | ≤ 10 MB | wav/mp3, up to 60 s. Larger: 422 voice_sample_too_large / voice_sample_invalid. |
recordings per voice | ≤ 25 | Contabilizando os já adicionados. Mais: 422 voice_samples_limit. |
voice length | ≤ 300 s | Todas as gravações juntas, incluindo as já adicionadas. Mais longo: 422 voice_samples_limit; mais curto que o mínimo do mecanismo: 422 voice_samples_invalid. |
recordings size | ≤ 50 MB | Todas as gravações de uma solicitação juntas. Mais informações: 422 voice_samples_too_large. |
request body | ≤ 70 953 644 B | 50 MB de gravações como base64 (×4/3), mais JSON. Maior: 413 payload_too_large (JSON, com max_body_bytes). Envie conjuntos longos em partes via …/samples ou como links audio_url. |
additions per 24 h | 20 | Por cliente. Mais informações: 429 voice_samples_rate_limited. |
Alterador de voz e alinhamento forçado
| Parâmetro | Tipo | Descrição |
|---|---|---|
elevenlabs-voice-changer | model | opts.voice_id (your ElevenLabs voice) + the source recording opts.audio_url | audio_base64 | audio_file_id, up to 5 minutes. Priced on the measured length: 1 minute = 1000 characters. |
forced-alignment | model | prompt is the transcript, opts.audio_url | audio_base64 | audio_file_id the recording. Result: word timings in resultMeta.words and an SRT file in resultUrls. Priced per 1000 characters of text. |
Sandbox: resultado do envio desconhecido
Quando a confirmação de início do fornecedor não chega, o job permanece com status: "submitting", stage: "submission_unknown", errorCode: "media_submission_uncertain" e failure.advice: "reconcile_first" — continue consultando o mesmo jobId e não crie uma duplicata. Para testar esse caminho sem custo, envie POST /api/media/generate com uma chave de sandbox e o header x-pv-sandbox-outcome: submission_uncertain. A resposta é um 202 normal com um jobId; consultá-lo responde como um envio desconhecido por 60 segundos e, depois, como um job que nunca foi iniciado (failure.code: "submission_not_started", charged: false). Nada é armazenado, enviado a um fornecedor ou cobrado. Uma chave normal com esse header recebe 400 sandbox_outcome_requires_sandbox_key.
Conversão de fala em texto (transcrição)
Mesmo endpoint do restante da geração: coloque o nome do modelo STT em model, deixe prompt como uma string vazia e passe a gravação em opts.audio_url. A transcrição chega em resultText em GET /api/media/jobs/{id}; resultUrls permanece vazio — a transcrição não produz nenhum arquivo.
# speech-to-text: create the job, then read the transcript
curl https://getvibeapi.com/api/media/generate \
-H "Authorization: Bearer $GETVIBE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "whisper-large-v3-turbo",
"prompt": "",
"opts": {
"audio_url": "https://example.com/meeting.mp3",
"language_code": "en"
}
}'
# → {"ok":true,"jobId":"JOB_ID","status":"processing","priceRub":0.03}
curl https://getvibeapi.com/api/media/jobs/JOB_ID \
-H "Authorization: Bearer $GETVIBE_API_KEY"
# → {"status":"success","resultText":"the transcribed text…","resultUrls":[],"priceRub":0.03}Modelos
whisper-large-v3-turbo— $0.00025 por minuto de áudio. Mais barato e mais rápido, 99 idiomas.nemotron-asr-multilingual— $0.00025 por minuto. ASR multilíngue da NVIDIA, com pontuação automática.whisper-large-v3— $0.000563 por minuto. Whisper completo: mais lento que o turbo, mais preciso em áudio com ruído.universal-2— $0.003125 por minuto.speech-to-text— $0.01 por minuto (ElevenLabs Scribe). Oferece diarização de locutores e tags de eventos de áudio.
Parâmetros
| Parâmetro | Tipo | Descrição |
|---|---|---|
audio_urlreq. | string (URL) | Link https público que disponibiliza o arquivo diretamente. Redirecionamentos e endereços de redes privadas são recusados. Use audio_base64 se o arquivo não estiver online. |
audio_base64 | string | A gravação diretamente no formato data:audio/mpeg;base64,… Substitui audio_url. |
language_code | string | Código do idioma (en, ru, …). Detectado automaticamente quando omitido. |
duration_minutes | number | Duração da gravação em minutos — usada para a estimativa de preço antecipada. A cobrança final é medida (veja abaixo). |
diarize | boolean | Diarização de falantes (universal-2, conversão de fala em texto). |
tag_audio_events | boolean | Marque eventos de áudio, como risadas ou aplausos (conversão de fala em texto). |
keyterms | string[] | Lista de termos e nomes para dicas (fala para texto; preço +30%). |
Formatos e limites
mp3, wav, m4a/mp4, flac, ogg/opus e webm são aceitos. O tamanho do arquivo é de 25 MB no máximo — aproximadamente 26 minutos de mp3 a 128 kbps ou várias horas de fala em opus. Qualquer arquivo maior é recusado imediatamente com uma mensagem explícita e não é cobrado; divida a gravação.
whisper-large-v3-turbo, whisper-large-v3 e nemotron-asr-multilingual, o valor final é calculado com base na duração medida da gravação, obtida da transcrição — não com base no valor que você passou em duration_minutes. A cobrança mínima é de um copeque. O valor exato é sempre retornado como priceRub no trabalho concluído.Webhook de prontidão (em vez de polling)
Para evitar o polling, registre um endereço mediaWebhookUrl no seu dashboard. Quando a tarefa for concluída (com sucesso ou erro), o serviço fará até cinco tentativas de entrega de um POST com um corpo JSON:
// POST to your mediaWebhookUrl when a job finishes
{
"jobId": "...",
"status": "success", // or "fail"
"model": "veo-3.1",
"kind": "video", // image | video | audio | music | 3d
"resultUrls": ["https://getvibeapi.com/api/media/file/..."],
"failMsg": null,
"createdAt": "2026-06-17T10:00:00.000Z"
}Buscando o arquivo: /api/media/file/{id}/{idx}
A URL do resultado da geração (imagem, vídeo, áudio ou modelo 3D) de resultUrls. Use-a como retornada pelo serviço: ela abre sem uma chave de API e funciona em <img>, <video> ou em um navegador. O provedor fica oculto: o endereço upstream é resolvido no lado do servidor, e o cliente nunca o vê.
| Parâmetro | Tipo | Descrição |
|---|---|---|
idreq. | string (path) | ID da tarefa (jobId) da resposta de /api/media/jobs/{id}. |
idxreq. | integer (path) | Índice do resultado (baseado em 0). Para um único resultado — 0. |
query params | como em resultUrls | Não crie a URL por conta própria nem modifique os parâmetros retornados pelo serviço. |
download | string (query) | download=1 retorna o arquivo como um anexo cujo nome e extensão seguem o conteúdo (.glb para um modelo 3D). Sem ele, o arquivo é aberto no navegador. |
# The signed URL is returned in resultUrls of the /api/media/jobs/{id} response
# or in the webhook body. Opens directly in the browser / <img> — no key needed.
https://getvibeapi.com/api/media/file/JOB_ID/0?sig=HMAC_SIGNATUREresultsExpireAt de /api/media/jobs/{id}). O arquivo concluído é copiado para o nosso armazenamento e resultUrls mudam para um endereço permanente no formato https://getvibeapi.com/media/r/…; uma URL /api/media/file/… retornada anteriormente continua funcionando também. Ambas aceitam solicitações Range (para avançar em vídeos e áudios). Após 7 dias, o arquivo é excluído e a URL responde 410 Gone com o código media_result_expired — baixe o que você precisar antes disso.