9. Mídia (Upload/Download)#
POST/v1/instances/{instanceId}/média#
Faz upload de arquivo para o S3. Retorna um media_id (UUID) que pode ser usado nos endpoints de mensagem via o campo media_id. Este endpoint e opcional para fluxos que querem preparar/reutilizar mídias; para envio simples, os endpoints messages/image, messages/video, messages/audio, messages/document e messages/sticker também aceitam media_url ou multipart/form-data direto.
Auth: Todos autenticados
Limites:
| Limite | Valor |
|---|---|
| Tamanho máximo por arquivo | 64 MB |
| Content-Type aceito | multipart/form-data OU application/json |
| MIME types aceitos | image/*, video/*, audio/*, application/pdf (qualquer outro retorna 400 unsupported media MIME type) |
Opcao 1: Multipart upload (recomendado para upload direto)#
Content-Type: multipart/form-data
Form field: file (arquivo binario, max 64 MB)
Exemplo:
curl -X POST https://api.catcher.one/v1/instances/$INSTANCE/media \
-H "X-API-Key: $TOKEN" \
-F "file=@/caminho/para/documento.pdf"
Opcao 2: Upload via URL (o servidor baixa do link)#
Content-Type: application/json
{
"media_url": "https://exemplo.com/imagem.png",
"file_name": "imagem.png"
}
Util quando o arquivo já está em um bucket público (R2, S3 com signed URL, etc). O servidor baixa respeitando o timeout HTTP global (HTTP_TIMEOUT, padrão 30s), aplica o mesmo limite de 64 MB, e rejeita MIME type fora da allowlist. URLs em redes privadas / IPs internos / Meta CDN são rejeitadas (SSRF guard + proxy discipline).
Resposta 201:
{
"media_id": "68854a58-c8c9-4021-9c6f-765dc5cdff34",
"mime_type": "image/png",
"file_name": "imagem.png",
"file_size": 45678
}
media_ide um UUID v4 — use comomedia_idno body de qualquer endpointPOST /v1/instances/{instanceId}/messages/{image|video|audio|document|sticker}dentro dos 7 dias de retencao padrão, ou envie a mídia direto nesses endpoints viamedia_url/file.
Erros:
| Status | error_code |
Descricao |
|---|---|---|
| 400 | BAD_REQUEST |
file required (multipart sem o campo file), failed to read file, file too large (max 64MB), unsupported media MIME type, invalid JSON, media_url or file upload required, failed to parse multipart form |
| 401 | UNAUTHORIZED |
Sem Authorization: Bearer nem X-API-Key, ou credencial inválida |
| 404 | NOT_FOUND |
instance not found (instância não pertence a sua empresa) |
| 500 | INTERNAL_SERVER_ERROR |
upload failed (S3 indisponível), failed to save media record (DB indisponível) |
| 503 | SERVICE_UNAVAILABLE |
media storage not configured (S3 não wired no backend — não deve ocorrer em staging/prod) |
GET/v1/instances/{instanceId}/média/{mediaId}#
Faz download de um arquivo de mídia. Funciona tanto para mídia enviada (upload via POST) quanto para mídia recebida (baixada automaticamente de mensagens inbound do WhatsApp).
Auth: Todos autenticados
Parametros de URL:
| Parametro | Descricao |
|---|---|
instanceId |
ID da instância |
mediaId |
UUID da mídia (retornado no upload, no campo media_id do evento message.received, ou no campo media_id do objeto de mensagem) |
Resposta 200: Arquivo binario com headers:
Content-Type: MIME type do arquivo (ex:image/png,audio/ogg; codecs=opus)Content-Disposition:inline; filename="imagem.png"Content-Length: Tamanho em bytes
Erros:
| Status | Descricao |
|---|---|
| 404 | Mídia não encontrada |
| 503 | Armazenamento S3 não configurado |
Exemplo de uso (download de audio recebido):
# 1. Receba um evento message.received via webhook/SSE com media_id
# 2. Baixe o arquivo:
curl -o audio.ogg \
-H "X-API-Key: $TOKEN" \
"https://api.catcher.one/v1/instances/$INSTANCE/media/b2c3d4e5-f6a7-8901-bcde-f12345678901"
Nota: Toda mídia recebida no WhatsApp (imagens, videos, audios, documentos, stickers) e baixada automaticamente do WhatsApp e armazenada no S3. O
media_ide incluído no eventomessage.receivede no objeto de mensagem retornado pelos endpoints de chat/mensagens.
GET/v1/instances/{instanceId}/média/{mediaId}/info#
Retorna apenas metadata da mídia (MIME, tamanho, filename, timestamps) como JSON, sem baixar o binario. Use este endpoint para espelhar informações da mídia no seu banco ou decidir se vale a pena baixar o arquivo antes de puxar os bytes.
Auth: Todos autenticados
Parametros de URL: mesmos do endpoint de download (instanceId, mediaId).
Resposta 200:
{
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"mime_type": "image/jpeg",
"file_name": "foto.jpg",
"file_size": 102400,
"download_url": "/v1/instances/84c2e480-.../media/b2c3d4e5-...",
"info_url": "/v1/instances/84c2e480-.../media/b2c3d4e5-.../info",
"created_at": "2026-03-28T14:30:00Z"
}
Quando a mídia e temporaria (upload com TTL), o campo expires_at acompanha. O mesmo shape aparece inline no campo media da resposta de GET /v1/instances/{instanceId}/message/{messageId} — consumidores podem usar as mesmas chaves em ambos os contextos.
Erros:
| Status | Descricao |
|---|---|
| 404 | Mídia não encontrada para está instância |
GET/v1/instances/{instanceId}/média#
Lista paginada de mídias da instância. Cada item inclui remote_jid da conversa associada (quando a mídia está vinculada a uma mensagem).
Auth: Todos autenticados
Query params:
| Parametro | Tipo | Descricao |
|---|---|---|
page |
int | Página (default: 1) |
limit |
int | Itens por página (default: 50, max: 100) |
mime_type |
string | Filtro por prefixo MIME (ex: image/, video/) |
remote_jid |
string | Filtra mídias de uma conversa especifica (ex: 5511999887766@s.whatsapp.net) |
Resposta 200:
{
"data": [
{
"id": "uuid-media",
"external_id": "uuid-media",
"instance_id": "uuid-instance",
"s3_key": "company/instance/file.png",
"mime_type": "image/png",
"file_name": "foto.png",
"file_size": 45678,
"remote_jid": "5511999887766@s.whatsapp.net",
"created_at": "2026-03-28T14:30:00Z"
}
],
"total": 120,
"page": 1,
"limit": 50
}
Nota:
remote_jidpode estar ausente para mídias que não estão associadas a nenhuma mensagem (ex: uploads manuais ainda não enviados).
Erros:
| Status | Descricao |
|---|---|
| 401 | Sem autenticação válida |
| 404 | Instância não pertence a sua empresa |
| 500 | Erro de acesso ao banco do tenant |
GET/v1/instances/{instanceId}/média/conversations#
Lista conversas que possuem mídias, com contadores e metadados agregados. Util para agrupar a galeria de mídia por conversa.
Auth: Todos autenticados
Query params:
| Parametro | Tipo | Descricao |
|---|---|---|
mime_type |
string | Filtro por prefixo MIME (ex: image/) |
Resposta 200:
{
"data": [
{
"remote_jid": "5511999887766@s.whatsapp.net",
"media_count": 42,
"total_size": 156789012,
"last_media_at": "2026-03-28T14:30:00Z",
"thumbnail_id": "uuid-da-midia-mais-recente"
}
]
}
| Campo | Descricao |
|---|---|
remote_jid |
JID da conversa |
media_count |
Quantidade de mídias na conversa |
total_size |
Tamanho total em bytes |
last_media_at |
Data da mídia mais recente |
thumbnail_id |
UUID da mídia mais recente (pode ser usado para thumbnail via GET .../media/{thumbnail_id}) |
Erros:
| Status | Descricao |
|---|---|
| 401 | Sem autenticação válida |
| 404 | Instância não pertence a sua empresa |
| 500 | Erro de acesso ao banco do tenant |