# Mídia

> Upload de mídia para envio e download da mídia recebida.

Fonte: https://metahub.matratecnologia.com/docs/midia

## Upload (mídia de saída)

`POST /v1/connections/:connectionId/media` com o arquivo cru no corpo, `Content-Type` = MIME do arquivo, `Content-Length` obrigatório e `X-Filename` opcional (só exibição). O hub confere tipo, tamanho e o conteúdo real do arquivo e sobe para a Meta; o arquivo não fica guardado no hub.

| Família | MIME aceitos | Teto |
|---|---|---|
| imagem | `image/jpeg`, `image/png` | 5 MB |
| sticker | `image/webp` | 500 KB |
| áudio | `audio/aac`, `audio/amr`, `audio/mpeg`, `audio/mp4`, `audio/ogg` | 16 MB |
| vídeo | `video/mp4`, `video/3gpp` | 16 MB |
| documento | `text/plain`, `application/pdf`, Word, Excel e PowerPoint (`.doc`, `.docx`, `.xls`, `.xlsx`, `.ppt`, `.pptx`) | 100 MB |

Resposta `201`:

```json
{ "media": { "id": "...", "mimeType": "image/png", "size": 48213, "sha256": "...", "expiresAt": "2026-11-21T15:00:00.000Z" } }
```

Use o `id` como `mediaId` no envio até `expiresAt` (29 dias).

| Status | `code` | Quando |
|---|---|---|
| 411 | `CONTENT_LENGTH_REQUIRED` | sem `Content-Length` (envio chunked não é aceito) |
| 415 | `MEDIA_TYPE_NOT_ALLOWED` | MIME fora da tabela |
| 413 | `MEDIA_TOO_LARGE` | acima do teto da família, ou corpo vazio |
| 400 | `MEDIA_SIGNATURE_MISMATCH` | o conteúdo não é do tipo declarado |
| 404 / 409 | `CONNECTION_NOT_FOUND` / `CONNECTION_NOT_ACTIVE` | conexão |
| 429 | `MEDIA_UPLOAD_BUSY` | uploads simultâneos demais; `Retry-After: 5` |
| 422 | `META_MEDIA_REJECTED` | a Meta recusou o arquivo, com `metaErrorCode` |
| 502 | `META_UNAVAILABLE` | resposta incerta da Meta; pode repetir |

## Mídia recebida

Mensagem com mídia chega no `whatsapp.message.received` com `message.media.id` (id do hub) e `message.media.status` (em geral `pending`). O hub baixa o arquivo da Meta em segundo plano e emite `whatsapp.media.updated` quando termina. Esse evento pode chegar **antes** do `whatsapp.message.received` da mesma mensagem: correlacione pelo `id` da mídia ou pelo `wamid`.

`GET /v1/media/:mediaId`:

| Status | `code` | Quando |
|---|---|---|
| 200 | | `{ media: { id, direction, mimeType, size, sha256, filename, createdAt, url, urlExpiresAt } }`. `url` é assinada e vale 5 minutos: baixe na hora e guarde no seu storage. Mídia de saída (`direction: "outbound"`) vem com `url: null` |
| 404 | `MEDIA_NOT_FOUND` | inexistente ou de outro app |
| 409 | `MEDIA_NOT_READY` | ainda baixando; tente depois ou espere o `whatsapp.media.updated` |
| 410 | `MEDIA_UNAVAILABLE` | o download falhou ou a mídia venceu na Meta (7 dias), com `errorCode` |

O download é sempre `attachment`, com o MIME validado pelo hub: tipo fora da lista da Meta, ou conteúdo que não bate com o tipo declarado, vem como `application/octet-stream`. `filename` vem do remetente: use só para exibição, nunca como caminho. A mídia recebida fica no hub por 30 dias.
