---
title: "Mídia no webhook WhatsApp: baixar arquivo e limites"
description: "O webhook traz a referência da mídia, não o arquivo. Como baixar imagem, áudio, vídeo e documento pela API, em base64 ou binário, e os limites de tamanho de WhatsApp, Instagram e Messenger."
url: "https://api-wa.me/blog/midia-webhook-whatsapp-baixar-limites"
language: "pt-BR"
og:type: "article"
og:site_name: "WAME API"
---

[Início](https://api-wa.me/)/[Blog da API do WhatsApp](https://api-wa.me/blog)/Mídia no webhook do WhatsApp: como receber, baixar e os limites de tamanho por canal

Raphael Serafim· Publicado em 25 de setembro de 2026· 8 min de leitura

Compartilhar

# Mídia no webhook do WhatsApp: como receber, baixar e os limites de tamanho por canal

O webhook traz a referência da mídia, não o arquivo. Como baixar imagem, áudio, vídeo e documento pela API, em base64 ou binário, e os limites de tamanho de WhatsApp, Instagram e Messenger.

Copiar para LLM[Ver como Markdown](https://api-wa.me/blog/midia-webhook-whatsapp-baixar-limites.md)

**O webhook não traz o arquivo. Traz a referência da mídia, e o arquivo você baixa com um GET em `/{key}/message/{messageId}/media`, em base64 ou em binário.** Imagem, áudio, vídeo, documento e figurinha funcionam do mesmo jeito. O que varia é o canal: no WhatsApp você baixa pela API da instância, e no Instagram e no Messenger baixa direto do CDN da Meta. Cada canal também tem o próprio limite de tamanho.

Este guia usa o webhook no formato `meta`, o mesmo envelope para os três canais. Se ainda não configurou, comece por [um webhook para WhatsApp, Instagram e Messenger](https://api-wa.me/blog/webhook-whatsapp-instagram-messenger-padrao-meta).

## O que chega no webhook quando o cliente manda uma mídia

A mensagem de mídia chega com `type` igual ao tipo de arquivo (`image`, `video`, `audio`, `document` ou `sticker`) e um bloco com o mesmo nome. Veja um documento recebido pelo WhatsApp:

json

Copiar

```
{
  "from": "5511988887777",
  "id": "WAMID_DOC",
  "timestamp": "1700000000",
  "type": "document",
  "document": {
    "id": "WAMID_DOC",
    "url": "https://us.api-wa.me/YOUR_KEY/message/WAMID_DOC/media",
    "mime_type": "application/pdf",
    "sha256": "YWJj",
    "filename": "orcamento.pdf",
    "caption": "Segue o orçamento"
  }
}
```

Os campos do bloco mudam um pouco conforme o tipo:

| Tipo | Campos |
| --- | --- |
| `image`, `video` | `id`, `url`, `mime_type`, `sha256`, `caption` |
| `audio` | `id`, `url`, `mime_type`, `sha256`, `voice` |
| `document` | `id`, `url`, `mime_type`, `sha256`, `filename`, `caption` |
| `sticker` | `id`, `url`, `mime_type`, `sha256`, `animated` |

Três deles fazem diferença na integração:

- **`url`** já aponta para o endpoint de download da sua instância, com a mensagem certa no caminho. No WhatsApp você não precisa montar a URL.
- **`filename`** só existe em `document` e guarda o nome original do arquivo. Guarde esse valor, porque o download não o devolve (mais sobre isso abaixo).
- **`sha256`** é o hash SHA-256 do arquivo. Serve para conferir a integridade depois de baixar e para reconhecer o mesmo arquivo enviado duas vezes.

O evento não traz tamanho do arquivo. Para saber o tamanho antes de ler o corpo, use o `Content-Length` da resposta em binário.

## Baixando pelo endpoint: json ou binary

O endpoint é um só, e o parâmetro `format` escolhe a forma da resposta.

### `format=json` (o padrão)

bash

Copiar

```
curl "https://us.api-wa.me/YOUR_KEY/message/WAMID_IMG/media"
```

json

Copiar

```
{
  "messageId": "3EB05344D9E03CFCA3A09B",
  "mimetype": "image/jpeg",
  "base64": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD..."
}
```

O campo `base64` não traz só o base64: ele vem como **data URL**, com o prefixo `data:<mimetype>;base64,` na frente. Algumas APIs aceitam a data URL direto, e para essas basta repassar o campo. Se o destino espera base64 puro, corte tudo até a primeira vírgula, e não pelo `;` do prefixo, porque o mimetype de áudio de voz é `audio/ogg; codecs=opus` e tem um `;` no meio:

javascript

Copiar

```
const puro = json.base64.slice(json.base64.indexOf(",") + 1);
```

### `format=binary`

bash

Copiar

```
curl -o arquivo "https://us.api-wa.me/YOUR_KEY/message/WAMID_IMG/media?format=binary"
```

A resposta é o arquivo, com `Content-Type` igual ao mimetype, `Content-Length` e `Content-Disposition: attachment`. Aberta no navegador, a URL baixa o arquivo direto. Para guardar a mídia, prefira binary: o base64 ocupa cerca de um terço a mais, e no seu servidor é preciso decodificar de volta antes de salvar.

O nome que vem no `Content-Disposition` é `<messageId>.<extensão>`, com a extensão tirada do mimetype (`image/jpeg` vira `.jpeg`). **O nome original do documento não vem no download.** Se o nome importa, e em documento quase sempre importa, pegue o `filename` do webhook.

Qualquer valor de `format` que não seja `binary` devolve JSON.

## O handler completo

Juntando tudo, este handler recebe o evento, baixa a mídia de WhatsApp em binário e salva com o nome certo:

javascript

Copiar

```
import express from "express";
import { createHash } from "node:crypto";
import { writeFile } from "node:fs/promises";

const TIPOS_MIDIA = ["image", "video", "audio", "document", "sticker"];
const app = express();
app.use(express.json());

app.post("/webhook/wame", async (req, res) => {
  res.sendStatus(200); // confirme antes de baixar: download leva tempo

  const body = req.body;
  const msg = body?.entry?.[0]?.changes?.[0]?.value?.messages?.[0];
  if (!msg || !TIPOS_MIDIA.includes(msg.type)) return;

  const midia = msg[msg.type];
  try {
    if (body.provider === "whatsapp") {
      await baixarWhatsApp(msg.id, midia);
    } else {
      await baixarCdnMeta(msg.id, midia); // Instagram e Messenger, veja abaixo
    }
  } catch (e) {
    console.error("falha ao baixar mídia", msg.id, e);
  }
});

async function baixarWhatsApp(messageId, midia) {
  const r = await fetch(`${midia.url}?format=binary`);
  if (!r.ok) throw new Error(`download ${r.status}`);

  const buffer = Buffer.from(await r.arrayBuffer());

  // Confere se chegou o arquivo que o evento descreveu
  // (aceita o hash em base64 ou em hex)
  const hash = createHash("sha256").update(buffer).digest();
  const confere = [hash.toString("base64"), hash.toString("hex")].includes(midia.sha256);
  if (midia.sha256 && !confere) throw new Error("sha256 não confere");

  const ext = midia.mime_type.split("/")[1].split(";")[0];
  const nome = midia.filename ?? `${messageId}.${ext}`;
  await writeFile(`./midias/${nome}`, buffer);
}
```

Em produção, troque o `writeFile` pelo seu storage (S3, R2, GCS) e jogue o download numa fila em vez de rodar dentro do handler. Não confie no `filename` como caminho: ele vem do cliente e pode trazer `../`. O mesmo evento também pode chegar duas vezes, e a solução para isso está em [idempotência e retry de webhook](https://api-wa.me/blog/webhook-producao-assinatura-retry-idempotencia).

Com os SDKs oficiais, o download é uma linha. Em Node, `wa.message.getMedia(messageId, "binary")` ([SDK JavaScript/TypeScript](https://api-wa.me/blog/sdk-javascript-typescript-whatsapp)). Em PHP, `$wa->message->downloadMedia($messageId, 'binary')` ([SDK PHP](https://api-wa.me/blog/sdk-php-whatsapp-instagram-messenger)).

## Instagram e Messenger: o arquivo vem do CDN da Meta

Nesses dois canais, o bloco de mídia chega mais enxuto:

json

Copiar

```
"image": {
  "url": "https://cdn.instagram.com/img.jpg",
  "mime_type": "image/jpeg",
  "caption": "foto"
}
```

O bloco não tem `id` nem `sha256`, e a `url` é do CDN da própria Meta, não da API da instância. O endpoint `/message/{messageId}/media` atende mensagens de WhatsApp. Para Instagram e Messenger, baixe da `url`:

javascript

Copiar

```
async function baixarCdnMeta(messageId, midia) {
  const r = await fetch(midia.url);
  if (!r.ok) throw new Error(`cdn ${r.status}`);
  const buffer = Buffer.from(await r.arrayBuffer());
  const ext = midia.mime_type.split("/")[1];
  await writeFile(`./midias/${messageId}.${ext}`, buffer);
}
```

Duas diferenças mudam o código:

- **O `mime_type` aqui é deduzido da extensão da URL**, não informado pela Meta. Se o tipo exato importa (converter áudio, validar formato), confira o `Content-Type` da resposta do CDN.
- **Reel ou post compartilhado não traz um arquivo.** A `url` é o link da publicação, uma página HTML. Trate como link e não tente salvar como imagem.

## Limites de tamanho por canal

Estes são os limites que a Meta documenta para envio de mídia por API:

| Canal | Imagem | Vídeo | Áudio | Documento |
| --- | --- | --- | --- | --- |
| WhatsApp | 5 MB | 16 MB | 16 MB | 100 MB |
| Instagram | 8 MB | 25 MB | 25 MB | não aceita |
| Messenger | 25 MB | 25 MB | 25 MB | 25 MB |

Figurinha no WhatsApp é `webp`, com até 100 KB (estática) ou 500 KB (animada).

Na hora de **receber**, esses números não mudam o seu código: o que chega é o que o app do cliente deixou enviar, e você baixa do jeito descrito acima. Eles importam quando você **devolve ou repassa** o arquivo, e o caso típico é o atendimento omnichannel. Um vídeo de 20 MB recebido no Messenger não sai pelo WhatsApp, porque passa dos 16 MB. Um PDF recebido no WhatsApp não sai pelo Instagram, que não aceita documento. Cheque o tamanho (`Content-Length` ou `buffer.length`) e o tipo antes de reenviar. Quando o arquivo não couber, mande um link para ele no seu storage em vez de mandar o arquivo.

O áudio a WAME já valida no envio: acima de 16 MB no WhatsApp ou de 25 MB no Instagram e no Messenger, o envio volta com erro em vez de falhar do lado da Meta.

## O que quebra em produção

**Deixar o download para depois.** A mídia fica nos servidores do WhatsApp e da Meta, e eles descartam arquivo antigo. Um download feito dias depois pode voltar `404` com `Media expired or unavailable on WhatsApp servers`. Se o arquivo vai ser usado depois (anexo de ticket, comprovante, histórico do CRM), baixe quando o evento chegar e guarde no seu storage.

**Tratar todo erro do mesmo jeito.** O endpoint devolve `404` com uma mensagem que diz o motivo: `Message not found` (o id não existe para essa instância), `Media not available or message is not a media message` (a mensagem não é mídia) ou mídia expirada. Nenhum desses se resolve tentando de novo. Uma falha `5xx` pode ser passageira: tente de novo poucas vezes, com espera entre as tentativas, e depois desista e registre.

**Baixar tudo de uma vez.** O endpoint passa pelo rate limit da instância. Um backfill de mil mensagens em `Promise.all` estoura o limite e metade volta com erro. Use uma fila com concorrência baixa, [como num disparo](https://api-wa.me/blog/fila-rate-limit-retry-disparo-whatsapp).

**Expor a URL de download.** A `url` que chega no WhatsApp leva a `key` da instância no caminho. Não mande essa URL para o front-end, não grave em log aberto e não passe para terceiros. Quem tiver a URL tem a sua chave. O front-end deve receber a URL do arquivo no seu storage. Mais sobre isso em [segurança de token e webhook](https://api-wa.me/blog/seguranca-api-whatsapp-token-webhook).

**Confiar no mimetype para escolher o que fazer.** O áudio de voz do WhatsApp chega como `audio/ogg; codecs=opus`, e um `mime_type === "audio/ogg"` falha. Compare o prefixo (`startsWith("audio/")`) ou use o `type` da mensagem. Para voz, o bloco `audio` traz `voice: true`, e é o caminho para [transcrever o áudio com IA](https://api-wa.me/blog/transcricao-audio-whatsapp-ia).

## Conclusão

Mídia no webhook dá dois passos: o evento avisa que chegou um arquivo e diz onde ele está, e o seu código busca o arquivo. No WhatsApp a busca é pelo endpoint da instância, em binário para guardar ou em JSON quando o destino espera base64. No Instagram e no Messenger é pela `url` do CDN da Meta. Baixe na chegada, guarde o `filename` do evento, confira o `sha256` e cheque tamanho e tipo antes de repassar o arquivo para outro canal. Assim a mídia não se perde nem trava o seu fluxo.

### Pronto para automatizar seu WhatsApp?

Crie sua conta gratuita e comece a enviar mensagens pela API em minutos.

[Começar grátis](https://portal.api-wa.me/sign-up)

## Perguntas frequentes

O webhook do WhatsApp manda o arquivo junto com a mensagem?+

Não. O evento traz só a referência da mídia: o id da mensagem, o mime\_type, o sha256, a legenda e, em documentos, o nome original do arquivo. O conteúdo você baixa à parte, pelo GET /{key}/message/{messageId}/media. Assim o webhook fica leve e chega rápido, mesmo quando o cliente manda um vídeo.

Qual a diferença entre format=json e format=binary no download?+

Sem parâmetro, ou com format=json, a resposta é um JSON com messageId, mimetype e base64, sendo que o base64 vem como data URL (data:image/jpeg;base64,...). Com format=binary, a resposta é o próprio arquivo, com Content-Type e Content-Length. Use binary para salvar em disco ou storage e para repassar a outra API. Use json quando o destino já espera base64.

Como baixo mídia recebida pelo Instagram ou pelo Messenger?+

Nesses canais o bloco de mídia chega sem id e traz uma url do CDN da Meta. Você baixa o arquivo direto dessa url, e não pelo endpoint de mídia da instância, que atende mensagens de WhatsApp. Em reels e posts compartilhados a url é o link da publicação, não um arquivo para baixar.

Qual o tamanho máximo de arquivo no WhatsApp, Instagram e Messenger?+

Pela documentação da Meta: no WhatsApp são 5 MB para imagem, 16 MB para vídeo e áudio e 100 MB para documento. No Instagram, 8 MB para imagem e 25 MB para vídeo e áudio. No Messenger, 25 MB para qualquer anexo. Os limites valem para envio pela API, então pesam quando o seu fluxo reenvia por um canal um arquivo recebido em outro.

Por quanto tempo a mídia fica disponível para download?+

Não conte com um prazo fixo. O arquivo depende dos servidores do WhatsApp e da Meta, que descartam mídia antiga, e um download tardio pode voltar 404 com a mensagem de mídia expirada. O mais seguro é baixar assim que o evento chega e guardar o arquivo no seu próprio storage.

## Continue lendo

[### Um webhook para WhatsApp, Instagram e Messenger: o padrão Meta na prática

Receba WhatsApp, Instagram e Messenger em um único webhook no formato da Meta Cloud API, reusando um só parser. O campo provider diz o canal.](https://api-wa.me/blog/webhook-whatsapp-instagram-messenger-padrao-meta)[### Transcrição de áudio no WhatsApp com IA: responder mensagens de voz automaticamente

Como baixar o áudio recebido no WhatsApp pela API, transcrever com IA (Whisper) e responder — o código completo, com o que quebra em produção.](https://api-wa.me/blog/transcricao-audio-whatsapp-ia)[### Bloqueios em massa do WhatsApp: o que aconteceu e quem foi atingido

A onda de bloqueios de contas do WhatsApp em agosto de 2026 atingiu negócios inteiros. O que os casos tinham em comum, por que a Meta agiu em lote e quem passou ileso.](https://api-wa.me/blog/bloqueios-massa-whatsapp-agosto-2026)

[Voltar ao blog](https://api-wa.me/blog)

## Structured data

```json
{
  "@context": "https://schema.org",
  "@type": "WebSite",
  "name": "WAME API",
  "alternateName": "API Oficial e Não Oficial de WhatsApp, Instagram, Messenger e Telegram",
  "url": "https://api-wa.me",
  "inLanguage": "pt-BR",
  "publisher": {
    "@id": "https://api-wa.me/#organization",
    "@type": "Organization",
    "name": "WAME API",
    "url": "https://api-wa.me"
  }
}
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "@id": "https://api-wa.me/#organization",
  "name": "WAME API",
  "alternateName": [
    "WAME",
    "Wame API",
    "wame.api.br",
    "api-wa.me"
  ],
  "url": "https://api-wa.me",
  "logo": {
    "@type": "ImageObject",
    "url": "https://api-wa.me/images/web-app-manifest-512x512.png",
    "width": 512,
    "height": 512
  },
  "disambiguatingDescription": "WAME API é uma empresa brasileira de software, fundada em 2017 e parceira oficial da Meta (Meta Business Partner), que fornece APIs de WhatsApp, Instagram Direct e Messenger. Não tem relação com o wa.me, que é o encurtador de links operado pela WhatsApp LLC.",
  "identifier": {
    "@type": "PropertyValue",
    "propertyID": "INPI-BR",
    "name": "Pedido de registro de marca (INPI, classe NCL 42)",
    "value": "944724159"
  },
  "foundingDate": "2017",
  "slogan": "Parceira Oficial da Meta — WhatsApp, Instagram, Messenger e Telegram numa instância só. Desde 2017.",
  "description": "Plataforma brasileira e Parceira Oficial da Meta (Meta Business Partner) para as APIs oficiais de WhatsApp (Cloud API), Instagram Direct e Messenger — os três numa única instância, com os mesmos endpoints e um único formato de webhook. Também oferece a API não oficial via QR Code e o Telegram, na mesma plataforma. No mercado desde 2017, com mais de 50 mil instâncias criadas, 99,9% de uptime e suporte humano 24/7 em português. SDKs oficiais para Node.js/TypeScript e PHP.",
  "knowsAbout": [
    "WhatsApp Cloud API oficial (Meta)",
    "API oficial de Instagram (Direct)",
    "API oficial de Messenger",
    "API multicanal Meta",
    "Meta Business Partner",
    "WhatsApp API",
    "API não oficial de WhatsApp",
    "automação de WhatsApp",
    "números virtuais",
    "webhooks"
  ],
  "sameAs": [
    "https://github.com/wame-api",
    "https://www.linkedin.com/company/wameapi",
    "https://www.instagram.com/wame.api/",
    "https://www.youtube.com/@wameapi"
  ],
  "contactPoint": {
    "@type": "ContactPoint",
    "contactType": "customer support",
    "url": "https://api-wa.me/contact",
    "availableLanguage": [
      "Portuguese"
    ]
  }
}
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "Mídia no webhook do WhatsApp: como receber, baixar e os limites de tamanho por canal",
  "description": "O webhook traz a referência da mídia, não o arquivo. Como baixar imagem, áudio, vídeo e documento pela API, em base64 ou binário, e os limites de tamanho de WhatsApp, Instagram e Messenger.",
  "image": "https://api-wa.me/blog/midia-webhook-whatsapp-baixar-limites/opengraph-image",
  "datePublished": "2026-09-25",
  "dateModified": "2026-09-25",
  "author": {
    "@type": "Person",
    "name": "Raphael Serafim",
    "url": "https://github.com/raphaelvserafim",
    "sameAs": [
      "https://github.com/raphaelvserafim"
    ]
  },
  "publisher": {
    "@type": "Organization",
    "name": "api-wa.me",
    "logo": {
      "@type": "ImageObject",
      "url": "https://api-wa.me/images/screenshot.png"
    }
  },
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://api-wa.me/blog/midia-webhook-whatsapp-baixar-limites"
  },
  "keywords": "baixar mídia whatsapp api, receber imagem whatsapp api, download arquivo whatsapp api, limite tamanho arquivo whatsapp, base64 whatsapp api, webhook whatsapp api, webhook instagram, transcrever audio whatsapp",
  "inLanguage": "pt-BR"
}
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "Home",
      "item": "https://api-wa.me"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "Blog da API do WhatsApp",
      "item": "https://api-wa.me/blog"
    },
    {
      "@type": "ListItem",
      "position": 3,
      "name": "Mídia no webhook do WhatsApp: como receber, baixar e os limites de tamanho por canal",
      "item": "https://api-wa.me/blog/midia-webhook-whatsapp-baixar-limites"
    }
  ]
}
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "O webhook do WhatsApp manda o arquivo junto com a mensagem?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Não. O evento traz só a referência da mídia: o id da mensagem, o mime_type, o sha256, a legenda e, em documentos, o nome original do arquivo. O conteúdo você baixa à parte, pelo GET /{key}/message/{messageId}/media. Assim o webhook fica leve e chega rápido, mesmo quando o cliente manda um vídeo."
      }
    },
    {
      "@type": "Question",
      "name": "Qual a diferença entre format=json e format=binary no download?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Sem parâmetro, ou com format=json, a resposta é um JSON com messageId, mimetype e base64, sendo que o base64 vem como data URL (data:image/jpeg;base64,...). Com format=binary, a resposta é o próprio arquivo, com Content-Type e Content-Length. Use binary para salvar em disco ou storage e para repassar a outra API. Use json quando o destino já espera base64."
      }
    },
    {
      "@type": "Question",
      "name": "Como baixo mídia recebida pelo Instagram ou pelo Messenger?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Nesses canais o bloco de mídia chega sem id e traz uma url do CDN da Meta. Você baixa o arquivo direto dessa url, e não pelo endpoint de mídia da instância, que atende mensagens de WhatsApp. Em reels e posts compartilhados a url é o link da publicação, não um arquivo para baixar."
      }
    },
    {
      "@type": "Question",
      "name": "Qual o tamanho máximo de arquivo no WhatsApp, Instagram e Messenger?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Pela documentação da Meta: no WhatsApp são 5 MB para imagem, 16 MB para vídeo e áudio e 100 MB para documento. No Instagram, 8 MB para imagem e 25 MB para vídeo e áudio. No Messenger, 25 MB para qualquer anexo. Os limites valem para envio pela API, então pesam quando o seu fluxo reenvia por um canal um arquivo recebido em outro."
      }
    },
    {
      "@type": "Question",
      "name": "Por quanto tempo a mídia fica disponível para download?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Não conte com um prazo fixo. O arquivo depende dos servidores do WhatsApp e da Meta, que descartam mídia antiga, e um download tardio pode voltar 404 com a mensagem de mídia expirada. O mais seguro é baixar assim que o evento chega e guardar o arquivo no seu próprio storage."
      }
    }
  ]
}
```
