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.
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.
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."
}'
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.
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.
type | Tipos aceitos |
|---|---|
| image | image/jpeg, image/png, image/webp |
| audio | audio/aac, audio/mp4, audio/mpeg, audio/amr, audio/ogg |
| document | application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, text/plain |
| video | video/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
urldela 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_type | No upload: tipo fora da tabela, ou corpo que não é multipart. |
| 413 payload_too_large | No upload: arquivo acima de 16 MB. |
| 404 attachment_not_found | No envio: o anexo não existe nesta organização e ambiente, ou venceu. |
| 422 attachment_type_mismatch | No envio: o `type` não é o do arquivo — um PDF não sai como `image`. |
| 422 unsupported_message_type | No envio: o canal da conversa não transporta aquele tipo. |
Escrevemos sobre operação de atendimento, canais e IA no blog da Amivu.