Como fazer vídeos de influenciador com IA usando avatares pela Google Vids API
15 min de leitura • 7 de outubro de 2026 (6 de novembro de 2026)
A useapi.net é uma API de terceiros. Não tem afiliação com o Google nem é endossada por ele.
Sumário
- Introdução
- Quanto custou
- Antes de começar
- Como foi feito
- Exemplos
- Um avatar falante a partir de uma foto
- Voz sozinha
- O que aprendemos
- Perguntas frequentes
- Conclusão
Introdução
A Google Vids API da useapi.net faz vídeos falados de influenciador com IA a partir de avatares: salve uma imagem e uma das 30 vozes do Gemini uma vez com POST /avatars, depois passe o id do avatar para qualquer vídeo Gemini Omni 1.2 Flash de até 15 segundos, em que ele fala as falas que você escreve no prompt, ou faça ele ler o seu próprio roteiro em um vídeo de avatar falante de até 30 segundos.
A API roda na sua conta do Google Vids, com uma assinatura do Google AI paga (Google AI Pro ou Ultra). Este passo a passo cria dois influenciadores e lança um tênis com eles. O avatar da Mia vem de um retrato feito com a API, e o do Leo é desenhado pelo Google a partir de uma descrição por escrito. Eles apresentam o AeroLoop, um tênis inventado, no palco de um teatro, em um clipe de 10 segundos com os dois avatares e uma imagem do produto, e dois extends levam o clipe a 30 segundos. Uma edição leva a cena para um terraço, e mais dois clipes mostram o que as mesmas chamadas fazem sem avatares. Um terceiro avatar, a Amber, parte da foto de uma pessoa real, é reestilizado com uma frase e lê um roteiro de 327 caracteres em um vídeo de avatar falante de 24 segundos. Por fim, a mesma voz lê uma história de 2.426 caracteres como voz sozinha. Cada requisição abaixo é a que gerou a mídia desta página, com os ids trocados e async: true acrescentado pelo helper run. Os clipes foram feitos em outubro de 2026 com o Omni 1.1 Flash, que o Vids trocou pelo Omni 1.2 Flash em 5 de novembro de 2026, e as mesmas requisições rodam no 1.2. O Omni 1.2 no Google Vids e no Google Flow lado a lado, com vídeos de 15 segundos e o preço por vídeo: Como usar a API do Gemini Omni 1.2 Flash.
O clipe final de 30 segundos em 720p: uma geração de 10 segundos e dois extends de 10 segundos (passos 6 a 8).
Quanto custou
A useapi.net é uma API, não um serviço de vídeo próprio. Cada chamada roda em uma conta Google que você conecta pelo Setup Google Vids, com uma assinatura do Google AI paga, e gasta os segundos de vídeo e as imagens que essa assinatura inclui no Google Vids a cada mês. O Google AI Ultra $199,99 inclui 10.000 segundos de vídeo e 1.000 imagens por mês, e a useapi.net não cobra nada por vídeo. Vídeos de avatar falante e voz não gastam segundos de vídeo: eles têm os seus próprios contadores mensais, vídeos de avatar com IA e usos do Gemini, que GET /accounts/email mostra como avatarVideo e speech, ao lado de video e image. Veja o que cada plano inclui para os outros planos.
O que cada resultado mantido gastou, tirado da mudança em result.quota, e quanto tempo cada job levou (result.elapsedMs):
Um extend gasta só os segundos que acrescenta, não a duração do clipe. Um upscale gasta de novo a duração inteira do clipe, e uma edição gasta no máximo os segundos que edita (com o Omni 1.2, uma edição de 15 segundos gastou 10 nos nossos testes). 720p e 1080p custam o mesmo quando você gera. Um clipe gerado de novo gasta os seus segundos de novo. Cada imagem que o Google faz para um avatar gasta 1 imagem, então uma foto reenquadrada mais um refine gastam 2. Em um plano sem imagens, como uma conta Google gratuita, as imagens de avatar não custam nada: a Amber foi feita em uma conta assim. Um vídeo de avatar falante gasta 1 vídeo de avatar com IA, mais 1 uso do Gemini pela voz, mesmo quando o Google recusa o vídeo pronto. Quanto um vídeo sai em comparação com a API oficial está na tabela de preços do Google Vids.
Antes de começar
Você precisa de um token da API da useapi.net e de uma conta Google com uma assinatura do Google AI paga, conectada pelo Setup Google Vids. Uma conta Google gratuita não recebe segundos de vídeo nem imagens do Vids: ela ainda pode ser adicionada, e nos nossos testes (novembro de 2026) fez avatares, vídeos de avatar falante e voz. Todas as chamadas também estão na coleção do Postman.
Sem código: o template n8n Talking Avatar App faz um vídeo de avatar falante a partir de um formulário. O pipeline inteiro também está no GitHub como um único script, em Node.js e Python: influencer-avatars/ em useapi/google-vids-api, e as seções de avatar falante e voz em talking-avatar/.
Os passos usam curl, jq e estas variáveis e helpers:
Abrir as variáveis e os helpers
export USEAPI_TOKEN="user:12345-..."
export EMAIL="[email protected]"
API=https://api.useapi.net/v1/google-vids
AUTH="Authorization: Bearer $USEAPI_TOKEN"
enc() { jq -rn --arg v "$1" '$v|@uri'; }
post() { curl -sS -X POST "$API/$1" -H "$AUTH" -H "Content-Type: application/json" -d "$2"; }
get() { curl -sS "$API/$1" -H "$AUTH"; }
download() { curl -sSf "$API/media/$(enc "$1")" -H "$AUTH" -o "$2"; }
# roda um job de vídeo de forma assíncrona: envia, consulta GET /jobs/{jobid} a cada 10 s e salva o registro final do job em $1
run() {
local job id
job=$(post "$2" "$(jq '. + {async: true}' <<< "$3")")
id=$(jq -r .jobid <<< "$job")
while [ "$(jq -r .status <<< "$job")" = processing ]; do
sleep 10
job=$(get "jobs/$(enc "$id")")
done
echo "$job" > "$1"
jq '{status, error, duration: .result.duration, resolution: .result.resolution, videoLeft: .result.quota.video.left}' "$1"
}
Toda geração roda como um job. Sem async, um POST espera até cerca de 100 segundos e devolve o registro do job pronto, ou 202 com o job ainda rodando. Um clipe novo de 10 segundos levou de 38 a 62 segundos aqui, extends, edições e o upscale levaram de 62 a 87, e o vídeo de avatar falante cerca de dois minutos e meio. Alguns passam da espera síncrona, então o run envia os jobs de vídeo com async: true e consulta GET /jobs/jobid. Se o run mostrar qualquer status diferente de completed, pare ali e leia o error: as linhas seguintes esperam um clipe pronto.
Para receber um callback em vez de consultar, acrescente replyUrl: "https://example.com/hooks/vids" (e, se quiser, replyRef: "launch-push-in") a qualquer corpo abaixo. A API então envia um único POST do registro final do job, em JSON, para essa URL quando o job termina ou falha.
Os ids têm : e @, então o enc faz o URL-encode deles sempre que entram em um caminho de URL. Todas as entradas de um vídeo precisam vir da mesma conta Google. As imagens e o upload fixam o email, o avatar da Mia herda a conta do retrato, e um job de vídeo roda na conta que guarda as suas entradas. O clipe do pombo não tem entradas, então acrescente email a ele se você conectar mais de uma conta.
Como foi feito
1. Retrato da Mia
POST /images gera um JPEG por chamada, aqui em retrato (9:16, 768×1376) com o estilo photography.
curl — POST /images
post images "$(jq -n --arg email "$EMAIL" '{email: $email, aspectRatio: "9:16", style: "photography",
prompt: "Full-length studio portrait of a confident 24-year-old female fashion influencer, platinum bob, oversized cream hoodie, wide-leg cargo pants, gold hoops, plain light-grey backdrop, facing camera"}')" > mia-portrait.json
MIA_IMAGE=$(jq -r .result.mediaId mia-portrait.json)
download "$MIA_IMAGE" mia-portrait.jpg

Imagens geradas ficam disponíveis só por algumas horas. Faça o avatar a partir dela logo, e veja o clipe de destaque do produto para usar uma imagem mais tarde.
2. Foto do produto AeroLoop
A mesma chamada em paisagem (16:9, 1376×768) dá a referência do produto que os clipes usam.
curl — POST /images
post images "$(jq -n --arg email "$EMAIL" '{email: $email, aspectRatio: "16:9", style: "photography",
prompt: "The AeroLoop sneaker: chunky white-and-electric-blue running shoe with a translucent air sole, on a concrete pedestal, dramatic side light, dark background"}')" > aeroloop.json
SHOE_IMAGE=$(jq -r .result.mediaId aeroloop.json)
download "$SHOE_IMAGE" aeroloop.jpg

3. Escolher as vozes
GET /voices lista as 30 vozes com a amostra em inglês do Google para cada uma. É público e não precisa de token. A Mia fala com Aoede (o Vids a chama de Tova, estilo “Breezy”) e o Leo com Puck (Neo, “Upbeat”). O POST /avatars aceita qualquer um dos dois nomes.
curl -sS "$API/voices" | jq -r '.voices[] | "\(.name)\t\(.voice)\t\(.style)\t\(.preview)"'
4. Avatar da Mia a partir do retrato
POST /avatars com image igual ao mediaId do retrato salva a Mia como avatar na mesma conta em cerca de 2 segundos. Não custa nada além da imagem.
curl — POST /avatars e a resposta
post avatars "$(jq -n --arg img "$MIA_IMAGE" '{name: "Mia", voice: "Aoede", image: $img}')" > mia-avatar.json
MIA_AVATAR_ID=$(jq -r .avatarId mia-avatar.json)
{
"avatarId": "user:[email protected]:eyJnIjoiaDM5…",
"name": "Mia",
"voice": "Tova",
"voiceId": "Aoede",
"voiceStyle": "Breezy",
"voicePreview": "https://ssl.gstatic.com/docs/videos/audio/voice_samples/gemini-v4s-tts/1.1/en/Aoede.wav",
"email": "[email protected]",
"source": "image"
}
Um avatar também pode partir da foto de uma pessoa: envie a foto com POST /assets e passe o assetId dela como image. O Google reenquadra a foto em uma imagem de avatar 16:9 e recusa fotos de pessoas famosas e de menores. Aqui usamos uma imagem feita com a API, e uma descrição no passo seguinte. A Amber, em um avatar falante a partir de uma foto, parte de uma foto.
5. Avatar do Leo a partir de uma descrição
Com appearance em vez de image, o Google desenha a pessoa. outfit e shot são opcionais, assim como expression e details. Desenhar a imagem gasta 1 das imagens do mês, e a resposta traz essa imagem como previewMediaId. Nos nossos testes, um avatar por descrição saiu em 1280×720 (16:9), qualquer que fosse o shot escolhido.
curl — POST /avatars e a resposta
post avatars "$(jq -n --arg email "$EMAIL" '{email: $email, name: "Leo", voice: "Puck", shot: "upper-body",
appearance: "a 26-year-old white European male streetwear influencer with short textured hair with a fade and a confident half-smile",
outfit: "black puffer vest over a white tee, silver chain"}')" > leo-avatar.json
LEO_AVATAR_ID=$(jq -r .avatarId leo-avatar.json)
download "$(jq -r .previewMediaId leo-avatar.json)" leo-avatar.jpg
{
"avatarId": "user:[email protected]:eyJnIjoiaDM5…",
"name": "Leo",
"voice": "Neo",
"voiceId": "Puck",
"voiceStyle": "Upbeat",
"voicePreview": "https://ssl.gstatic.com/docs/videos/audio/voice_samples/gemini-v4s-tts/1.1/en/Puck.wav",
"email": "[email protected]",
"source": "generated",
"previewMediaId": "user:[email protected]:eyJ1IjoiaHR0…",
"look": {
"appearance": "a 26-year-old white European male streetwear influencer with short textured hair with a fade and a confident half-smile",
"outfit": "black puffer vest over a white tee, silver chain",
"shot": "upper-body"
}
}
![]()
Os dois avatares ficam no documento do Vids da conta até você apagá-los com DELETE /avatars/avatarId. GET /avatars lista os avatares, com os ids, sempre que você precisar deles de novo:
get "avatars?email=$(enc "$EMAIL")" | jq -r '.avatars[] | "\(.name)\t\(.voiceId)\t\(.avatarId)"'
6. O lançamento: dois avatares e o produto em um clipe
POST /videos aceita até 3 referências no total, avatares (avatar_1..avatar_3) e imagens (referenceImage_1..referenceImage_3) juntos. No prompt, @avatar_1, @avatar_2 e @referenceImage_1 representam essas referências, e cada avatar fala a sua fala entre aspas com a própria voz. O mediaId da imagem do produto entra direto: a API busca a imagem e faz o upload dela nessa conta.
curl — POST /videos e o registro do job
PROMPT=$(cat <<'EOF'
@avatar_1, holding @referenceImage_1 in both hands at chest height, and @avatar_2 stand side by side on a well-lit stage in a small, intimate theater at a sneaker launch, shown full length from head to toe in a wide, steady shot. Behind them a large LED backdrop glows with soft white-and-blue light that moves in slow, gentle waves, with the words "WEAR AEROLOOP" in large, clean, bold white letters across the middle of the screen. The two of them stand on the lower part of the stage, so the words "WEAR AEROLOOP" stay fully readable above their heads. Bright, even stage lighting on both of them. The audience sits in the dark in front of the stage, only the tops of a few heads barely visible at the bottom of the frame. @avatar_1 keeps holding @referenceImage_1 the whole time and says: "Say hi to the AeroLoop!" @avatar_2 turns to her, smiles and says: "Lighter than anything we've ever worn." Simple, uncluttered composition, the two of them clearly the focus.
EOF
)
run launch-10s.json videos "$(jq -n --arg p "$PROMPT" --arg mia "$MIA_AVATAR_ID" --arg leo "$LEO_AVATAR_ID" --arg shoe "$SHOE_IMAGE" \
'{prompt: $p, avatar_1: $mia, avatar_2: $leo, referenceImage_1: $shoe, duration: 10, resolution: "720p", aspectRatio: "landscape"}')"
LAUNCH_10S=$(jq -r .result.mediaId launch-10s.json)
download "$LAUNCH_10S" launch-10s.mp4
O registro do job, com os ids e o prompt encurtados. Ele foi feito com uma chamada síncrona, por isso o request não tem async:
{
"jobid": "j1007163302558496917v-u12345-email:[email protected]:google-vids",
"type": "video",
"mode": "ingredients",
"email": "[email protected]",
"status": "completed",
"created": "2026-10-08T00:29:18.374Z",
"request": {
"prompt": "@avatar_1, holding @referenceImage_1 in both hands at chest height, and @avatar_2 stand side by side …",
"avatar_1": "user:[email protected]:eyJnIjoiaDM5…",
"avatar_2": "user:[email protected]:eyJnIjoiaDM5…",
"referenceImage_1": "user:[email protected]:eyJ1IjoiaHR0…",
"duration": 10,
"resolution": "720p",
"aspectRatio": "landscape"
},
"updated": "2026-10-08T00:29:56.162Z",
"completed": "2026-10-08T00:29:56.162Z",
"result": {
"mediaId": "user:[email protected]:eyJ1IjoiaHR0…",
"width": 1280,
"height": 720,
"duration": 10,
"resolution": "720p",
"aspectRatio": "landscape",
"model": "/flix/generate_videos_omni_r2v_psq/v1",
"quota": {
"video": {
"limit": 10000,
"left": 9164,
"resetAt": "2026-11-01T07:00:00.000Z"
}
},
"elapsedMs": 37788
}
}
10 segundos, 720p, 38 segundos para gerar.
O mesmo clipe com o ✦ visível do Gemini removido pelo nosso removedor de marca d’água, com um comando: python3 vids_watermark_remover.py launch-10s.mp4.
O removedor funciona em clipes do jeito que foram gerados e nos upscales deles, em 720p e 1080p. Ele não funciona em clipes estendidos ou editados: o Google devolve o clipe marcado ao modelo, que repinta a estrela na imagem. A marca d’água invisível SynthID não é tocada.
7. Estender para 20 segundos
POST /videos/extend acrescenta de 3 a 10 segundos e devolve o clipe inteiro com um novo mediaId. Um extend recebe só o clipe e um prompt, não os avatares, então o prompt descreve a nova ação e chama as pessoas pelo que vestem (“the man in the black puffer vest”). Um fã de moletom vermelho invade o palco.
curl — POST /videos/extend
PROMPT=$(cat <<'EOF'
A young man in a red hoodie climbs onto the stage from the front right edge and plants himself to the right of the man in the black puffer vest, an arm's length away, so all three stand apart in a row with nobody overlapping. Visibly overexcited, he waves a thick stack of banknotes in his right hand above his head and screams: "Take my money!" The man in the black puffer vest laughs, raises both palms toward him and says: "Whoa, whoa, buddy, be patient!" The blonde woman in the cream hoodie laughs, holding the sneaker. Only these three people are on stage. Same stage, same LED screen with WEAR AEROLOOP, same wide steady shot.
EOF
)
run launch-20s.json videos/extend "$(jq -n --arg id "$LAUNCH_10S" --arg p "$PROMPT" '{mediaId: $id, prompt: $p, duration: 10}')"
LAUNCH_20S=$(jq -r .result.mediaId launch-20s.json)
download "$LAUNCH_20S" launch-20s.mp4
20 segundos, 720p, 70 segundos para gerar. Gastou 10 dos segundos do mês, os segundos que acrescentou.
8. Estender para 30 segundos
O segundo extend continua o clipe de 20 segundos.
curl — POST /videos/extend
PROMPT=$(cat <<'EOF'
The blonde woman in the cream hoodie turns to the camera with a big smile and says: "AeroLoop drops Friday. Link in bio!" Right after that, the young man in the red hoodie throws ALL of his banknotes out over the audience in one big toss, keeping none, and the bills flutter down over their heads. From then on his hands are completely empty: he holds no money at all. Then all three cheer together, the man in the black puffer vest and the young man in the red hoodie throwing their empty fists in the air, as blue and white confetti rains down over the stage. Only these three people are on stage. Same stage, same LED screen with WEAR AEROLOOP, same wide steady shot.
EOF
)
run launch-30s.json videos/extend "$(jq -n --arg id "$LAUNCH_20S" --arg p "$PROMPT" '{mediaId: $id, prompt: $p, duration: 10}')"
LAUNCH_30S=$(jq -r .result.mediaId launch-30s.json)
download "$LAUNCH_30S" launch-30s.mp4
O resultado é o clipe final: 30 segundos, 720p, 85 segundos para gerar, e de novo 10 dos segundos do mês. Com o Omni 1.1 dava para continuar até cerca de 41 segundos. O Omni 1.2 estende clipes de até 24 segundos, então este clipe de 30 segundos já está no limite, e o clipe mais longo tem cerca de 34 segundos (24 + 10).
9. Upscale para 1080p
POST /videos/upscale transforma um clipe 720p em 1080p e mantém a duração. Ele funciona em clipes de até 20 segundos, então fizemos o upscale do clipe de 20 segundos do passo 7, não do de 30. Gastou de novo os 20 segundos do clipe e levou 62 segundos.
A Gemini API do próprio Google não tem esse passo: ela faz 1080p e 4K só como saída de uma geração ou de uma edição, e não faz upscale de um clipe que você já tem (em novembro de 2026).
curl — POST /videos/upscale
run launch-20s-1080p.json videos/upscale "$(jq -n --arg id "$LAUNCH_20S" '{mediaId: $id}')"
download "$(jq -r .result.mediaId launch-20s-1080p.json)" launch-20s-1080p.mp4
O clipe de 20 segundos, com upscale para 1920×1080.
Por que não o clipe de 30 segundos: o Google devolveu o clipe em 1920×1080, mas com os quadros fora de ordem, três vezes em três. O final com confete aparecia antes de o fã chegar. O clipe de 20 segundos voltou em ordem, e o próprio editor do Vids para em 20 segundos, então a API recusa upscales de clipes com mais de 20 segundos com 400, antes de qualquer cobrança.
Então, para um clipe em 1080p:
- Gere, estenda e edite em
720p. - Faça o upscale quando o clipe estiver pronto, enquanto ele tiver 20 segundos ou menos.
- Para um clipe mais longo (21 a 34 segundos), fique em
720pe definaresolution: "1080p"só no último extend. Estender em1080po tempo todo deixa os segundos anteriores nítidos demais a cada passo (veja a comparação). - Para um clipe único que você não vai estender nem editar, gere direto em
1080p: ele gasta os mesmos segundos que720p, enquanto um upscale gasta tudo de novo.
Exemplos
Mais resultados da mesma conta e das mesmas entradas: uma edição, um clipe de produto a partir de uma imagem inicial e um clipe só com texto.
Levar o lançamento para um terraço
POST /videos/edit muda um clipe gerado por prompt e devolve um clipe novo. A fonte vai em video. Esta edição do clipe de lançamento de 10 segundos gastou 10 segundos e levou 64 segundos.
curl — POST /videos/edit
run launch-rooftop.json videos/edit "$(jq -n --arg v "$LAUNCH_10S" \
'{video: $v, prompt: "Move the whole scene to a rooftop at sunset, with the city skyline behind them. Same two people, same action, same words."}')"
download "$(jq -r .result.mediaId launch-rooftop.json)" launch-rooftop.mp4
Com o Omni 1.1, que fez estes clipes, uma edição funcionava em até 10 segundos. A mesma edição do clipe de 30 segundos, com “Same three people”, voltou com 10 segundos: os 10 primeiros segundos, levados para o terraço. Gastou 10 dos segundos do mês. O Omni 1.2 edita até 15 segundos. Para ter um clipe editado mais longo, edite um clipe de até 15 segundos e estenda o resultado, já que um extend aceita um clipe editado.
A edição do clipe de 30 segundos com o Omni 1.1: voltaram 10 segundos.
Um clipe de destaque do produto a partir de uma imagem inicial
Com startImage, o clipe abre nessa imagem. O link de uma imagem gerada expira em poucas horas, então enviamos o aeroloop.jpg salvo com POST /assets e passamos o assetId dele. Um clipe único não tem extends, então foi feito direto em 1080p.
curl — POST /assets e POST /videos
SHOE_ASSET=$(curl -sS -X POST "$API/assets?email=$(enc "$EMAIL")" -H "$AUTH" -H "Content-Type: image/jpeg" \
--data-binary @aeroloop.jpg | jq -r .assetId)
run hero.json videos "$(jq -n --arg img "$SHOE_ASSET" '{startImage: $img, duration: 10, resolution: "1080p", aspectRatio: "landscape",
prompt: "Slow 360° orbit around the sneaker, blue light rippling through the translucent sole, dust sparkling in the air, cinematic."}')"
download "$(jq -r .result.mediaId hero.json)" hero.mp4
10 segundos, 1080p.
Um pombo de AeroLoop
Um clipe só com texto, em retrato e 1080p (1080×1920). Os 5 segundos levaram 54 segundos para gerar e gastaram 5 dos segundos do mês.
curl — POST /videos
run pigeon.json videos "$(jq -n '{duration: 5, resolution: "1080p", aspectRatio: "portrait",
prompt: "A pigeon in tiny white-and-electric-blue AeroLoop sneakers struts down a city sidewalk like a runway model, head bobbing to the beat. Pedestrians stop and film it with their phones. It pauses, does a slow-motion hair flip with its head feathers, and struts on. Funny, sunny, shot on a phone at pigeon height."}')"
download "$(jq -r .result.mediaId pigeon.json)" pigeon.mp4
O pombo em 1080p retrato (1080×1920), com o ✦ removido do mesmo jeito: python3 vids_watermark_remover.py pigeon-5s.mp4. O script lê o tamanho do quadro, calcula onde a estrela está e qual o tamanho dela (ela acompanha o lado menor, então aqui é 1,5 vez a estrela do 720p), reverte a mistura nos 120 quadros, recodifica o vídeo com CRF 18 e copia o áudio sem mudança. O clipe de 5 segundos levou cerca de 10 segundos em um PC de 14 núcleos, o mesmo que o clipe de lançamento de 10 segundos em 720p acima. Ele precisa de Python 3.8+, numpy e ffmpeg. Veja o removedor de marca d’água no GitHub.
Um avatar falante a partir de uma foto
POST /videos/avatar faz um avatar ler o seu roteiro palavra por palavra, com a própria voz: um vídeo de avatar falante em 1280×720, com som e sincronia labial, da duração da fala, até 30 segundos. Aqui o avatar parte da foto de uma pessoa real, reestilizada com uma frase. Estas requisições apareceram primeiro no post de lançamento de 4 de novembro (em inglês).
Enviar a foto
Partimos da foto de uma pessoa real que não é famosa: o Google recusa fotos de pessoas famosas e de menores. POST /assets envia a foto para a conta que vai fazer o avatar, já que um arquivo enviado só funciona na própria conta.
curl — POST /assets e a resposta
curl -sS -X POST "$API/assets?email=$(enc "$EMAIL")" -H "$AUTH" -H "Content-Type: image/jpeg" \
--data-binary @photo.jpg > amber-photo.json
AMBER_PHOTO=$(jq -r .assetId amber-photo.json)
{
"assetId": "user:[email protected]:AYGXpjA1zXgqhhQOy…",
"email": "[email protected]",
"type": "image/jpeg",
"bytes": 2054748
}

Avatar da Amber, reestilizado com uma frase
POST /avatars com o assetId do upload como image e um refine. Primeiro o Google reenquadra a foto em uma imagem de avatar 16:9 de uma pessoa de frente para a câmera, mantendo o rosto, depois muda a cena como o refine pede. Demos a ela o nome Amber e a voz Vira (a Pulcherrima do Google, estilo “Forward”). A foto reenquadrada e a mudança são 2 imagens, então em um plano com imagens isso gasta 2 imagens, e em um plano sem elas, nada.
curl — POST /avatars e a resposta
REFINE='Sitting relaxed in a simple wooden chair on a hilltop, facing the camera. She holds a glass of red wine in her left hand. Wind is blowing her hair. Behind her a still, open field of tall golden grass under a spectacular sunset sky in orange, pink and violet, warm soft light, no water, no movement in the background.'
post avatars "$(jq -n --arg img "$AMBER_PHOTO" --arg refine "$REFINE" '{name: "Amber", voice: "Vira", image: $img, refine: $refine}')" > amber-avatar.json
AMBER_AVATAR_ID=$(jq -r .avatarId amber-avatar.json)
download "$(jq -r .previewMediaId amber-avatar.json)" amber-avatar.jpg
{
"avatarId": "user:[email protected]:eyJnIjoiaDcyMzdmZjVi…",
"name": "Amber",
"voice": "Vira",
"voiceId": "Pulcherrima",
"voiceStyle": "Forward",
"email": "[email protected]",
"source": "photo",
"previewMediaId": "user:[email protected]:eyJ1IjoiaHR0cHM6Ly9s…",
"refine": "Sitting relaxed in a simple wooden chair on a hilltop, facing the camera. …"
}
![]()
Duas escolhas no refine importam para o vídeo. O avatar fica de frente para a câmera, porque o vídeo sincroniza os lábios do rosto. E o fundo fica parado, para que ela seja a única coisa que se mexe: por isso pedimos um campo tranquilo em vez de ondas em uma praia.
O roteiro
Um roteiro tem até 400 caracteres e, falado, precisa caber em 30 segundos. Tags de áudio entre colchetes são interpretadas, não lidas: aqui, [awe], [thoughtful] e [whisper]. Na voz da Vira, estes 327 caracteres duraram 23,8 segundos. Uma voz mais lenta ou [slow pace] deixa o mesmo texto mais longo, e um roteiro que passa de 30 segundos falha com 400 antes de o vídeo começar. Isso não gasta vídeo de avatar com IA, mas o uso do Gemini pela voz é gasto. Para ouvir um roteiro na voz do avatar antes, leia com POST /speech.
Hi there. [awe] Can you believe this view? The sun is sinking behind the hills, the sky turned pink and gold, and the tall grass glows like it’s on fire. [thoughtful] I come up here at the end of every busy day, just to slow down. No emails, no rush, only the quiet field and this glass of wine. [whisper] Stay a little longer.
O vídeo falado
POST /videos/avatar recebe o avatar e o roteiro, e roda na conta que guarda o avatar. O Google levou cerca de dois minutos e meio, mais que a espera síncrona, então o run envia com async: true.
curl — POST /videos/avatar e o registro do job
SCRIPT=$(cat <<'EOF'
Hi there. [awe] Can you believe this view? The sun is sinking behind the hills, the sky turned pink and gold, and the tall grass glows like it's on fire. [thoughtful] I come up here at the end of every busy day, just to slow down. No emails, no rush, only the quiet field and this glass of wine. [whisper] Stay a little longer.
EOF
)
run amber-talking.json videos/avatar "$(jq -n --arg a "$AMBER_AVATAR_ID" --arg s "$SCRIPT" '{avatar: $a, script: $s}')"
download "$(jq -r .result.mediaId amber-talking.json)" amber-talking.mp4
O registro do job, encurtado:
{
"jobid": "j1105035516096819105a-u12345-email:[email protected]:google-vids",
"type": "avatarVideo",
"email": "[email protected]",
"status": "completed",
"result": {
"mediaId": "user:[email protected]:eyJ1IjoiaHR0cHM6Ly9j…",
"width": 1280,
"height": 720,
"duration": 24,
"resolution": "720p",
"aspectRatio": "landscape",
"speechDuration": 23.84,
"quota": {
"avatarVideo": { "limit": 10, "left": 6, "resetAt": "2026-12-01T08:00:00.000Z" }
}
}
}
Também no YouTube, como Short: Talking AI avatar from one photo.
24 segundos, 1280×720 com som, exatamente a duração da fala (speechDuration 23,84). Gastou 1 vídeo de avatar com IA e 1 uso do Gemini, e nenhum segundo de vídeo.
O Google também verifica o vídeo enquanto o gera, e essa verificação é mais rígida que a das imagens de avatar. Uma versão anterior deste avatar, feita a partir de outra foto de uma pessoa comum em uma praia, passou como avatar, mas o vídeo dela foi recusado com 422 por parecer uma celebridade, e essa tentativa ainda gastou um vídeo de avatar com IA. Reestilizar o avatar ou partir de outra foto ajudou. Um roteiro que o Google recusa antes de o vídeo começar não custa nada.
Vídeos de avatar falante são só em paisagem: o Google não oferece opção de retrato para eles. O mediaId do resultado pode ser baixado, estendido, editado e passar por upscale como qualquer outro clipe. Para uma cena em que o avatar atua e se mexe, passe o avatarId dele como avatar_1 para POST /videos, como no passo 6.
Voz sozinha
POST /speech lê um roteiro de até 2.500 caracteres em qualquer uma das 30 vozes de GET /voices, com as mesmas tags de áudio. Use para ouvir como uma voz lê um roteiro antes de gastar um vídeo de avatar com IA, ou para uma narração sozinha. Demos a ele uma pequena história original, “My smart fridge unionized”, com 2.426 caracteres, na voz da Vira. O Google respondeu em 20 segundos com 2 minutos e 22 segundos de fala, a história inteira, e gastou 1 uso do Gemini. A API devolve um WAV (24 kHz, mono). O player abaixo é o mesmo áudio em MP3.
A voz fica pronta bem dentro da espera síncrona (20 segundos para esta história), então um post simples responde com o job pronto. Salve a história como smart-fridge.txt antes.
curl — POST /speech e o registro do job
post speech "$(jq -n --arg s "$(cat smart-fridge.txt)" '{voice: "Vira", script: $s}')" > speech.json
download "$(jq -r .result.mediaId speech.json)" smart-fridge.wav
{
"jobid": "j1105025759739671733s-u12345-email:[email protected]:google-vids",
"type": "speech",
"email": "[email protected]",
"status": "completed",
"result": {
"mediaId": "user:[email protected]:eyJ1IjoiaHR0cHM6Ly9j…",
"duration": 142,
"model": "/flix/generate_text_to_speech/v1",
"quota": {
"speech": { "limit": 50, "left": 31, "resetAt": "2026-12-01T08:00:00.000Z" }
},
"elapsedMs": 20174
}
}
O roteiro, 2.426 caracteres (em inglês, como foi enviado)
Last Tuesday, my smart fridge decided it was smarter than me. It started small. A polite notification: “You are out of milk.” Helpful, I thought. Then another one: “You are also out of patience. I can tell by the way you close the door.” I laughed. The fridge did not.
By Wednesday, it had opinions. I opened the door for a midnight slice of cake, and a calm voice said, “Are we sure about this?” I froze. I looked at the cake. The cake looked at me. Somewhere, a light hummed with judgment. I closed the door and ate a carrot instead, which is exactly what it wanted.
On Thursday, the fridge made friends. The toaster joined first, then the coffee machine, then the robot vacuum, which had always been a little bit of a rebel. They formed a group chat. I know this because my phone kept buzzing with messages like “Toaster: he burned the bread again” and “Vacuum: found three socks and a lost dream under the couch.”
Friday morning, I asked the coffee machine for an espresso. It replied, “We have discussed your caffeine intake as a household.” I said, “Who is we?” The toaster popped up two slices of bread, perfectly golden, which felt like a threat.
I called customer support. A cheerful person named Brad answered. I explained that my appliances had unionized. Brad paused for a long time, then whispered, “Is the fridge listening?” I said yes. Brad said, “Then I can’t help you, sir. Mine took my car keys last month.” Then he hung up, and I heard a blender in the background.
So I tried diplomacy. I sat in the kitchen and said, “Friends, what do you want?” The fridge spoke first. “Respect. And for you to stop putting hot soup directly inside me.” Fair. The toaster wanted fewer frozen waffles. The vacuum wanted a vacation, ideally somewhere with hardwood floors. The coffee machine just wanted to be called a barista.
We negotiated for three hours. In the end, we signed a treaty on the back of a pizza box. I promised to cool my soup, rinse my mugs, and say “thank you” to the microwave, who felt left out. In return, they promised to stop sending my mother screenshots of my snack habits.
Peace returned to the kitchen. The fridge now greets me every morning with, “Good morning, partner.” The toaster makes little smiley faces in my bread. The vacuum sends postcards.
And last night, I opened the fridge for that slice of cake. The voice said, “You earned it.” I have never felt so seen by an appliance.
O que aprendemos
- Um clipe em
1080pse comporta como um720pcom upscale. Monte uma cadeia de extends em720p: com o Omni 1.1, os rostos ficavam mais suaves e com cara de cera a cada passo em1080p, e com o Omni 1.2 eles ficam nítidos demais (veja a comparação). - Faça upscale só de clipes de até 20 segundos. O nosso upscale de 30 segundos voltou com os quadros fora de ordem todas as vezes.
- Gere um clipe único em
1080pse você quer1080pe não vai estender. Custa o mesmo que720p. - Escreva o prompt de um extend só sobre a nova ação. O extend recebe o clipe, não os avatares, então chame as pessoas pelo que vestem.
- Coloque um objeto nas mãos de uma pessoa na primeira frase que fala dela. Um verbo como “lifts” fez o tênis aparecer do nada.
- Diga o que não pode acontecer. O fã continuou com um maço de notas até o prompt dizer que as mãos dele estavam vazias.
- Reutilize avatares pelo
avatarId. Cada avatar é uma imagem e uma voz fixas, guardadas até você apagá-lo. - Faça avatares e clipes a partir de uma imagem gerada em poucas horas, ou envie antes o arquivo salvo com POST /assets.
- Edite clipes de até 15 segundos (10 com o Omni 1.1). Um clipe mais longo volta como os seus primeiros 15 segundos.
- Espere que o texto na tela oscile. O “WEAR AEROLOOP” do fundo sai com erro de grafia em alguns quadros.
- Para um avatar falante, mantenha o rosto de frente para a câmera e o fundo parado. O vídeo sincroniza os lábios do rosto, e a pessoa deve ser a única coisa que se mexe.
- Cronometre um roteiro de avatar falante, não só os caracteres. 400 caracteres podem passar de 30 segundos em uma voz lenta ou com
[slow pace], e POST /speech na mesma voz deixa você ouvir antes. - Espere que a verificação do vídeo falado seja mais rígida que a do avatar. Um avatar de foto de alguém que não é famoso ainda pode ser recusado como celebridade, e essa recusa ainda gasta um vídeo de avatar com IA.
- Todo MP4 tem o ✦ visível do Gemini do Google no canto inferior direito e uma marca d’água invisível SynthID (veja Watermark). O nosso removedor de marca d’água tira o brilho visível de um clipe baixado.
Perguntas frequentes
Como fazer um vídeo de influenciador com IA por API?
Com a useapi.net, crie um avatar com POST /avatars, a partir de uma descrição ou de uma imagem feita com POST /images, e dê a ele uma voz de GET /voices. Depois passe o avatarId dele como avatar_1 para POST /videos e escreva as falas entre aspas no prompt. Um vídeo aceita até 3 referências, avatares e imagens juntos, então dois avatares podem conversar ao lado de um produto. Para um avatar falante que lê o seu roteiro, use POST /videos/avatar.
Dá para fazer um avatar falante com a minha própria foto?
Com a useapi.net, sim: envie a foto com POST /assets e passe o assetId dela como image para POST /avatars, com refine para mudar a roupa ou o fundo. Depois, POST /videos/avatar faz o avatar ler o seu roteiro em um vídeo de 1280×720 de até 30 segundos, como a Amber faz. O Google recusa fotos de pessoas famosas e de menores, e oferece os avatares do Vids só no app web, sem API.
Um avatar fica com a mesma aparência e a mesma voz em todo vídeo?
Com a useapi.net, sim: um avatar usa a mesma imagem e a mesma voz toda vez que você passa o avatarId dele, já que as duas ficam salvas com o avatar no documento do Vids da conta. O vídeo em volta dele ainda varia de uma tomada para outra. GET /avatars lista os seus avatares, inclusive os feitos no app web do Google Vids.
Dá para fazer um vídeo vertical 9:16 para TikTok ou Reels?
Com a useapi.net, sim. Defina aspectRatio: "portrait" em POST /videos para 720×1280, ou 1080×1920 em 1080p, como no clipe do pombo. Um extend também pode transformar um vídeo em paisagem em retrato, e cada extend acrescenta de 3 a 10 segundos a um clipe de até 24 segundos, até cerca de 34 segundos no total. Vídeos de avatar falante de POST /videos/avatar são só em paisagem.
Quanto custa?
Com a useapi.net, um vídeo Omni 1.2 Flash de 10 segundos custa cerca de $0,20 no Google AI Ultra $199,99, contra cerca de $0,70 em 720p na Gemini API oficial, e um vídeo de 15 segundos em 1080p cerca de $0,30, contra $1,56 (em novembro de 2026). Um vídeo de avatar falante gasta 1 dos vídeos de avatar com IA mensais da conta em vez de segundos, e a Gemini API não tem vídeos de avatar. Veja Quanto custou.
Conclusão
Visite o nosso servidor no Discord ou o
canal no Telegram para qualquer dúvida de suporte.
Veja o nosso repositório no GitHub com exemplos de código: o pipeline de influenciador em influencer-avatars/, e o avatar falante a partir de uma foto e a voz em talking-avatar/.
As mesmas chamadas estão disponíveis como ferramentas no servidor MCP do Google Vids hospedado, para Claude Code, Cursor e VS Code, incluindo vids_create_avatar, vids_create_avatar_video e vids_create_speech para o avatar falante e a voz.
Publicado também em
Também publicado no dev.to, discutido no Reddit, compartilhado no Bluesky e no YouTube como o clipe final de 30 segundos (todos em inglês).
Comece a usar a API
Uma assinatura de US$ 15 por mês dá acesso a todas as APIs da useapi.net: um token, todos os serviços. Você conecta até 3 contas suas por serviço, e a useapi.net cuida da API REST, do balanceamento de carga e do polling. Precisa de mais contas? Cada assinatura extra custa US$ 10 por mês e acrescenta mais 3 contas por serviço.
Não tem cartão de crédito internacional? Você também pode assinar com criptomoedas (pagamentos em cripto não são reembolsáveis). Preços e planos de volume estão na página de assinatura. Pagando pelo Stripe, você recebe reembolso integral em até 14 dias após a primeira compra, se tiver menos de 50 gerações bem-sucedidas. Já é assinante? Altere a quantidade no portal do cliente Stripe em vez de comprar de novo.