Anúncios · Imagens
As mídias do anúncio (as imagens e o vídeo) seguem o fluxo padrão da plataforma: suba uma vez pela Mídia, receba o ID, vincule onde precisar. Esta página cobre só o lado do anúncio: upload, formatos, limites e ciclo de vida estão no guia de Mídia.
O fluxo em duas chamadas
- Upload: POST/api/media/upload com o arquivo em
multipart/form-data. A resposta traz oidda imagem, já processada em todos os tamanhos. - Vínculo: no create/simulate do anúncio, referencie esse
id.
{
"title": "Caixa de Som JBL Go!",
"images": [ // galeria do anúncio
{ "id": "01K8PBIMG00001VWXYZ12345678" },
{ "id": "01K8PBIMG00002VWXYZ12345678" }
],
"variations": [
{
"seller_sku": "FK-JBL-2000-AZUL",
"images": [ // fotos específicas desta variação
{ "id": "01K8PBIMG00003VWXYZ12345678" }
]
}
]
}images[](nível do anúncio): a galeria principal.variations[].images[]: fotos da variação (a foto azul na variação azul). É aqui que oprimary_attributeda geração de combinações ajuda: ele agrupa as fotos pelo atributo que muda a aparência.
Quem vira a capa
A capa (thumbnail) é escolhida nesta ordem, na própria criação:
- o
thumbnail_idque você mandar no corpo: capa explícita, sempre vence; - sem ele, a primeira imagem de
images[]; - sem galeria e sem capa explícita, a primeira foto de variação, e assim o anúncio nunca nasce sem imagem no card.
Depois de criado, dá para trocar a capa mandando outro thumbnail_id na edição do anúncio.
O que volta nas respostas
Imagens do anúncio retornam como { id, resources[] }, onde resources são as variações de tamanho geradas no upload:
{
"images": [
{
"id": "01K8PBIMG00001VWXYZ12345678",
"resources": [
{ "name": "sm", "size": "200x200", "url": "https://cdn…/sm_…webp" },
{ "name": "lg", "size": "800x800", "url": "https://cdn…/lg_…webp" }
]
}
],
"thumbnail": { "id": "01K8PBIMG00001VWXYZ12345678", "resource": { "name": "sm", "url": "…" } }
}Nas variações, os resources vêm filtrados para os tamanhos sm e lg: suficientes pra listagem e zoom.
Regras práticas
- Publicação exige imagem. O checklist tem o check
image: pelo menos 1 imagem na galeria (ou thumbnail definida) pra sair dedraft. - O ID precisa existir. O create valida a existência do ID da imagem na plataforma. ID errado derruba a chamada. Suba a imagem antes de criar o anúncio.
- Imagem em uso fica protegida. Vinculada ao anúncio, a imagem passa a
in_use: truena Mídia. Excluir retorna 409 até você remover o vínculo. Detalhes no ciclo de vida da Mídia. - Mesma imagem, vários lugares. O mesmo ID pode servir à galeria do produto e ao anúncio (é o ponto do upload compartilhado): não suba o arquivo duas vezes.
- Imagem solta expira. Imagem sem vínculo é limpa pela rotina da plataforma (~72h). Não acumule uploads "pra usar depois".
Vídeo do anúncio
O anúncio aceita um vídeo, no campo video_id do corpo do create e do update. O upload é feito pela Mídia, em três chamadas e com URL pré-assinada. O passo a passo, os limites (MP4 H.264, 100 MB, 90 s) e os estados do processamento estão em Mídia › Vídeos.
Aqui só interessa o vínculo. Regra de ouro: o vídeo precisa estar ready antes de você mandar o video_id.
Os três estados do campo
O video_id se comporta como o gtin: o que decide não é só o valor, é a presença da chave no corpo.
| No corpo | Efeito |
|---|---|
| Chave ausente | Mantém o vídeo atual (no create, nasce sem vídeo). |
"video_id": "01K8PB..." | Vincula esse vídeo ao anúncio (substituindo o anterior, se houver). |
"video_id": null | Remove o vídeo do anúncio. O vídeo volta ao pool e, se não for reaproveitado, é limpo pela rotina (~72h). |
{
"title": "Caixa de Som JBL Go!",
"images": [
{ "id": "01K8PBIMG00001VWXYZ12345678" }
],
"video_id": "01K8PBVID00001VWXYZ12345678" // opcional, um vídeo por anúncio
}O que volta na resposta
O anúncio devolve o campo video (ou null quando não há). Como é a sua visão, ele traz também status, rejection_reason e size_bytes:
{
"video": {
"id": "01K8PBVID00001VWXYZ12345678",
"url": "https://cdn…/video_01K8PBVID….mp4",
"duration_seconds": 32.5,
"width": 1080,
"height": 1920,
"poster": { // capa extraída do vídeo; pode vir null
"id": "01K8PBIMG00009VWXYZ12345678",
"original_source": "https://cdn…/original_01K8PBIMG….webp",
"resources": [
{ "name": "sm", "size": "200x200", "url": "https://cdn…/sm_01K8PBIMG….webp" }
]
},
"status": "ready",
"rejection_reason": null,
"size_bytes": 8342100
}
}Na vitrine, o mesmo vídeo aparece semstatus, rejection_reason e size_bytes. E um vídeo que não esteja ready simplesmente não é exibido.
Erros
| Código | Quando |
|---|---|
| 422 | O video_id não existe na plataforma (erro de validação do campo), ou o vídeo ainda não está ready (está processando, ou foi rejected/failed). |
| 404 | O vídeo existe, mas não pertence à sua loja. |
| 409 | O vídeo já está vinculado a outro anúncio ou produto. |
No create, qualquer um desses erros desfaz o anúncio inteiro: ele não é criado pela metade, sem vídeo.
Aproveitar o vídeo do produto
Um vídeo pertence a um único recurso: o vídeo que está no SKU não pode ser vinculado direto ao anúncio. Use POST/api/media/videos/clone-from-sku para gerar uma cópia independente (arquivo e capa próprios, já em ready) e mande o id dela no video_id. É o análogo em vídeo do clone de fotos por SKU.
Regras práticas
- Publicação não exige vídeo. Diferente da imagem, o vídeo é opcional e não entra no checklist de publicação.
- Vídeo em uso fica protegido. Vinculado ao anúncio, ele passa a
in_use: true: excluir retorna 409 até você mandarvideo_id: nullno anúncio. - Vídeo solto expira. Assim como a imagem, vídeo que nunca foi vinculado é limpo pela rotina (~72h), e um intent que nunca recebeu upload sai em ~1h.

