Símbolo da AmivuSímbolo da AmivuDevelopers

Anexos e mídia

Suba o arquivo uma vez e envie imagem, vídeo, áudio ou documento por qualquer conversa.

Mídia sai em duas chamadas. Primeiro o arquivo sobe e vira um anexo (att_…); depois uma mensagem o envia. Separar as duas deixa o envio em JSON, idempotente e igual para todos os tipos — e permite subir o catálogo uma vez e mandá-lo para muitas conversas.

Subir o arquivo

POST /v1/uploads recebe multipart/form-data com o arquivo no campo file. O alcance exigido é o mesmo do envio, messages:write: subir não tem efeito nenhum além de poder enviar.

Terminal
curl https://api.amivu.com.br/v1/uploads \
  -H "Authorization: Bearer $AMIVU_API_KEY" \
  -F "file=@catalogo.pdf;type=application/pdf"
{
  "object": "attachment",
  "id": "att_01K7ZFA5X8Q2M4N6P8R0T2V4W6",
  "filename": "catalogo.pdf",
  "content_type": "application/pdf",
  "size": 482113,
  "url": "https://api.amivu.com.br/v1/attachments/att_01K7ZFA5X8Q2M4N6P8R0T2V4W6/content",
  "expires_at": "2026-09-26T14:03:11.000Z",
  "created_at": "2026-09-25T14:03:11.000Z"
}

O tipo vale o que a parte declara. Quando ela chega genérica (application/octet-stream, que é o que o curl manda para extensões que não conhece), vale a extensão do nome. Imagens são limpas de metadados (EXIF, GPS) e, acima de 400 KB, reduzidas para 1600px no maior lado — por isso content_type e size da resposta podem diferir do arquivo enviado.

Enviar

Com o att_… em mãos, POST /v1/messages com o type do arquivo e, se quiser, uma legenda em text. O caminho de envio é o mesmo que o atendente usa no painel — ver Mensagens.

Terminal
curl https://api.amivu.com.br/v1/messages \
  -H "Authorization: Bearer $AMIVU_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-8291-catalogo" \
  -d '{
    "conversation_id": "conv_01K7ZFA5X8Q2M4N6P8R0T2V4W6",
    "type": "document",
    "attachment_id": "att_01K7ZFA5X8Q2M4N6P8R0T2V4W6",
    "text": "Segue o catálogo."
  }'
Idempotência fica no envio
POST /v1/uploads ignora Idempotency-Key: o corpo multipart muda a cada tentativa, e subir de novo só cria outro anexo, que vence sem uso. Quem não pode duplicar é a mensagem — mande a chave nela.

Baixar

Todo anexo traz em url o endereço do arquivo, e ele se baixa com a mesma chave, com o alcance messages:read. Vale para o que você subiu e para a mídia das mensagens — inclusive a recebida do cliente, que é o que o webhook message.received entrega.

Terminal
curl https://api.amivu.com.br/v1/attachments/att_01K7ZFA5X8Q2M4N6P8R0T2V4W6/content \
  -H "Authorization: Bearer $AMIVU_API_KEY" \
  -o comprovante.jpg

A resposta são os bytes, com Content-Type, o nome original em Content-Disposition e Cache-Control: private — o arquivo é de um cliente, e nenhum cache compartilhado no caminho deve guardá-lo. Só alcança o que é da organização e do ambiente da chave; o resto é 404 attachment_not_found. Guarde o id, não o endereço.

Tipos e tamanho

As regras são as do painel, lidas da mesma lista: o que o atendente consegue anexar, a API aceita; o que ele não consegue, ela recusa. O limite é 16 MB por arquivo, em qualquer tipo.

typeTipos aceitos
imageimage/jpeg, image/png, image/webp
audioaudio/aac, audio/mp4, audio/mpeg, audio/amr, audio/ogg
documentapplication/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, text/plain
videovideo/mp4, video/3gpp

O canal da conversa também precisa transportar aquele tipo: o chat do site é só texto, e mídia nele volta 422 unsupported_message_type. Leia as capacidades do canal antes. No WhatsApp oficial, fora da janela de 24 horas a mensagem é aceita e falha depois, como o texto — por message.failed.

De quem é, e até quando

  • O anexo pertence à organização e ao ambiente da chave que o subiu. Um att_… do sandbox não existe para uma chave de produção, e o de outra conta não existe para ninguém — quem garante é o banco, não um filtro.
  • Ele vale por 24 horas (expires_at). Dentro desse prazo, pode ser enviado a quantas conversas quiser.
  • Vencer não tira nada de quem já recebeu: a mensagem enviada guarda o arquivo, e o url dela continua baixável. O anexo vencido deixa de existir; o arquivo dele só é apagado quando nenhuma mensagem saiu com ele.

Quando recusa

415 unsupported_media_typeNo upload: tipo fora da tabela, ou corpo que não é multipart.
413 payload_too_largeNo upload: arquivo acima de 16 MB.
404 attachment_not_foundNo envio: o anexo não existe nesta organização e ambiente, ou venceu.
422 attachment_type_mismatchNo envio: o `type` não é o do arquivo — um PDF não sai como `image`.
422 unsupported_message_typeNo envio: o canal da conversa não transporta aquele tipo.

Escrevemos sobre operação de atendimento, canais e IA no blog da Amivu.