Baixar mídia recebida
/v1/instances/{id}/media/{media_id}desde M2token da instância ou adminQuando usar
Baixa a mídia de uma mensagem recebida (media.id no log). Na primeira vez o worker baixa do WhatsApp e o arquivo fica em data/media/. Com ?signed=1 devolve uma URL assinada que vale 1h sem token, para repassar a terceiros. Fora de loopback, ?signed=1 exige public_url (409 conflict). A resposta leva X-Content-Type-Options: nosniff, CSP sandbox e Content-Disposition (inline só para JPEG/PNG/WebP/GIF, áudio e vídeo).
Autenticação
Aceita o token da instância (só a própria instância) ou o token admin. Um token de outra instância recebe 403 forbidden (ou 404 not_found em webhooks de outra instância).
Parâmetros
Caminho
| Nome | Tipo | Descrição |
|---|---|---|
idobrigatório | string | Id da instância (inst_...). |
media_idobrigatório | string | Id da mídia (med_...), de media.id no log. |
Query
| Nome | Tipo | Descrição |
|---|---|---|
signed | "1" | 1 devolve {url, expires_at} em vez do arquivo. |
Exemplo
curl -s "$LITEZAP_URL/v1/instances/$ID/media/$MEDIA_ID" \ -H "Authorization: Bearer $LITEZAP_TOKEN" \ -o arquivoimport { writeFile } from "node:fs/promises";
const res = await fetch("http://localhost:8787/v1/instances/inst_7f3a9c2e5b1d4086/media/med_5b8e1f3c9d2a7046", { headers: { Authorization: `Bearer ${process.env.LITEZAP_TOKEN}` },});await writeFile("arquivo", Buffer.from(await res.arrayBuffer()));import osimport requests
r = requests.get( "http://localhost:8787/v1/instances/inst_7f3a9c2e5b1d4086/media/med_5b8e1f3c9d2a7046", headers={"Authorization": f"Bearer {os.environ['LITEZAP_TOKEN']}"}, timeout=150,)r.raise_for_status()open("arquivo", "wb").write(r.content)package main
import ( "fmt" "io" "net/http" "os")
func main() { req, _ := http.NewRequest("GET", "http://localhost:8787/v1/instances/inst_7f3a9c2e5b1d4086/media/med_5b8e1f3c9d2a7046", nil) req.Header.Set("Authorization", "Bearer "+os.Getenv("LITEZAP_TOKEN")) resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close() f, _ := os.Create("arquivo") defer f.Close() io.Copy(f, resp.Body) fmt.Println(resp.Status)}<?phprequire 'vendor/autoload.php'; // composer require guzzlehttp/guzzle
$client = new GuzzleHttp\Client(['base_uri' => 'http://localhost:8787']);$res = $client->request('GET', '/v1/instances/inst_7f3a9c2e5b1d4086/media/med_5b8e1f3c9d2a7046', [ 'headers' => ['Authorization' => 'Bearer ' . getenv('LITEZAP_TOKEN')], 'sink' => 'arquivo', 'http_errors' => false,]);echo $res->getStatusCode(), ' ', 'salvo em arquivo', PHP_EOL;Nos exemplos, LITEZAP_URL é a URL base (ex.: http://localhost:8787) e o token vem deLITEZAP_TOKEN (instância) ou LITEZAP_ADMIN_TOKEN.
Resposta
200 O arquivo, ou a URL assinada com ?signed=1. Também: application/octet-stream.
Campos de SignedURL
url | string | |
expires_at | string |
{ "url": "https://api.seu-dominio.com/media/inst_7f3a9c2e5b1d4086/med_5b8e1f3c9d2a7046?exp=1792252800&sig=9f86d081884c7d65", "expires_at": "2026-10-17T14:52:10Z"}Erros
| Código | HTTP | Retentável | O que fazer |
|---|---|---|---|
unauthorized | 401 | não | Envie Authorization: Bearer <token> válido. |
forbidden | 403 | não | Use o token certo (admin, ou o da própria instância). |
not_found | 404 | não | Confira o id do recurso (mensagem, chat, contato, mídia ou webhook). |
instance_not_found | 404 | não | Confira o id da instância. |
conflict | 409 | não | O recurso está num estado que não permite a operação; veja a message. |
media_unavailable | 410 | não | A mídia expirou no WhatsApp; peça o arquivo de novo ao contato. |
worker_error | 502 | sim | Tente de novo com backoff; se persistir, veja o log do servidor. |
worker_timeout | 504 | sim | Tente de novo; a instância pode estar sobrecarregada ou reconectando. |
Todo erro usa o envelope {"error":{"code","message","retryable"}}. Tabela completa em Erros.
Equivalente na Z-API: (mídia chega por URL no webhook). Veja Migrar da Z-API.
Outras operações de Mídia: Mídia por URL assinada

