Foto do grupo
Retorna a foto de um grupo do WhatsApp: redireciona (302) para uma URL pré-assinada quando a foto está no seu BYO Storage; caso contrário, responde 200 com o objeto picture (estado e motivo). O formato da resposta é o mesmo do endpoint de foto de perfil de contato, mas o que acontece quando a URL pré-assinada não pode ser gerada é diferente nos dois: veja Comportamento por picture.kind.
Endpoint
GET /v1/groups/{group_id}/pictureEscopo obrigatório: groups:read. Para números extras: GET /v1/numbers/{ref}/groups/{group_id}/picture, onde {ref} é o number_id do envelope do evento do grupo (num_…, não muda) ou o alias atual do número. group_id é o id público (grp_{hex32}).
Comportamento por picture.kind
O picture retornado tem apenas dois estados possíveis:
available (foto no seu BYO Storage) ou unavailable (qualquer outra
situação, com a causa em reason):
picture.kind | Resposta HTTP |
|---|---|
available | 302 Found: URL pré-assinada do BYO Storage (R2/S3/Supabase), nunca a chave do objeto no bucket |
unavailable | 200 OK: corpo JSON { "kind": "unavailable", "reason": ..., "setup_hint"?: ... } (ver campo reason abaixo) |
O valor picture.kind = "pending" só aparece em payloads de webhook: este
endpoint de leitura nunca o retorna.
Se a foto já está no seu BYO Storage mas a URL pré-assinada não pôde ser gerada
nesta requisição, o endpoint responde 200 OK com unavailable e a causa em
reason. Ele nunca retorna 404 para foto indisponível.
O Turbo Notify reavalia a foto marcada como unavailable na próxima mensagem de um membro do grupo (ou enviada pelo próprio celular) depois que você habilita o BYO Storage, respeitada a janela de 6 horas se já houve consulta. Mensagens enviadas só pela API não disparam a busca (veja Quando as fotos aparecem e a foto fica disponível depois).
Exemplo: foto disponível
curl -I "https://api.turbonotify.com/v1/groups/grp_.../picture" \ -H "Authorization: Bearer SUA_CHAVE"
HTTP/1.1 302 FoundLocation: https://<bucket>.r2.cloudflarestorage.com/groups/.../picture.jpg?...Cache-Control: no-store, no-cache, must-revalidatePragma: no-cacheA URL pré-assinada tem validade curta: 15 minutos por padrão (configurável entre 1 minuto e 1 hora na sua integração de armazenamento).
Exemplo: foto indisponível (sem armazenamento)
{
"kind": "unavailable",
"reason": "no_storage",
"setup_hint": {
"setup_url": "https://dashboard.turbonotify.com/storage",
"docs_url": "https://docs.turbonotify.com/general/byo-storage-setup/",
"message": "Configure object storage (S3, Cloudflare R2, or Supabase Storage, free tiers available) to receive media. Visit your dashboard or read the docs."
}
} O campo reason indica a causa: no_storage (sem armazenamento configurado), storage_circuit_open (o seu armazenamento vinha falhando e o envio foi suspenso temporariamente), upload_failed (o envio da foto para o seu bucket falhou desta vez) ou peer_has_none (o grupo não tem foto). O setup_hint só é preenchido para no_storage e storage_circuit_open. Para upload_failed e peer_has_none ele vem como null. É o mesmo formato usado pela mídia e pela foto de contato.
Campo picture em GET /v1/numbers/{ref}/groups/{group_id}
O campo picture no payload completo do grupo mostra o mesmo estado: traz a URL pré-assinada quando a foto está disponível e o reason e o setup_hint corretos quando ela está unavailable.
Cache
- A resposta vem com
Cache-Control: no-store, no-cache, must-revalidateePragma: no-cache: ela não deve ser guardada em cache, inclusive o redirecionamento302. Refaça a chamada sempre que precisar do estado atual. A URL pré-assinada indicada emLocationcontinua válida pelo próprio prazo dela, e é essa URL que você deve reutilizar se quiser evitar um novo download. - A URL pré-assinada tem validade curta: 15 minutos por padrão (configurável entre 1 minuto e 1 hora). Não reutilize a URL além desse prazo; refaça a chamada para obter uma nova.