> ## Documentation Index
> Fetch the complete documentation index at: https://docs.polymorfa.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Ler o histórico de mensagens

> Liste as conversas armazenadas e percorra as mensagens delas em números com armazenamento hospedado de mensagens.

> [!NOTE]
>
> A API de histórico de mensagens está em beta. Na página **Números**, um
> proprietário ou administrador da equipe seleciona **Participar** na linha do
> beta de histórico de mensagens, revisa os termos e seleciona **Aceitar e
> participar**. Até a equipe participar e o beta ser oferecido a ela, toda
> solicitação de histórico retorna `403 permission_denied`.

A API de histórico de mensagens retorna as conversas e mensagens que a
Polymorfa armazenou para um número com armazenamento hospedado de mensagens
ativado. Use-a para preencher uma caixa de entrada com mensagens anteriores,
exibir uma conversa depois que a página recarrega ou conciliar o seu próprio
armazenamento com o que a Polymorfa reteve.

## Antes de começar

* **O armazenamento hospedado de mensagens está ativado para o número.** O
  histórico contém apenas mensagens recebidas ou enviadas depois que o
  armazenamento foi ativado. Para qualquer outro número, as solicitações de
  histórico retornam `404 hms_not_enabled`. Números de teste nunca têm
  histórico armazenado.
* **Sua equipe participa do beta.** Participe pela linha do beta na página
  **Números** do Console. Sair do beta bloqueia novas leituras do histórico e
  não exclui as mensagens armazenadas.
* **Você faz as chamadas do seu servidor com uma chave de organização ou um
  token de projeto.** Tokens de cliente são rejeitados com
  `403 permission_denied`.

| Método | Escopo |
| - | - |
| [List conversations](/api-reference/messaging/conversations/list-chats) `GET /messaging/{session}/chats` | `chats:read` |
| [Get a conversation](/api-reference/messaging/conversations/get-chat) `GET /messaging/{session}/chats/{conversation}` | `chats:read` |
| [List messages](/api-reference/messaging/conversations/list-chat-messages) `GET /messaging/{session}/chats/{conversation}/messages` | `messages:read` |
| [Get a message](/api-reference/messaging/conversations/get-chat-message) `GET /messaging/{session}/chats/{conversation}/messages/{messageId}` | `messages:read` |
| [Download stored message media](/api-reference/messaging/conversations/get-chat-message-media) `GET /messaging/{session}/chats/{conversation}/messages/{messageId}/media` | `messages:read` e `media:read` |

`messages:read` é um escopo novo. As credenciais criadas antes de ele existir,
incluindo as credenciais com acesso total, não o incluem. Crie uma credencial
que liste `messages:read` explicitamente.

## Listar conversas

As conversas são ordenadas pela atividade mais recente, da mais nova para a
mais antiga. Cada item traz a identidade da conversa, o tipo dela e um resumo
da última mensagem armazenada. O resumo não tem o corpo da mensagem; leia as
mensagens para obter o conteúdo.

```bash theme={null}
curl "https://api.polymorfa.com/messaging/support-line/chats?limit=20&kind=direct" \
  -H "Authorization: Bearer $POLYMORFA_PROJECT_TOKEN"
```

```json theme={null}
{
  "success": true,
  "data": [
    {
      "conversation": { "id": "739182640518203", "phoneNumber": "+15550001111" },
      "kind": "direct",
      "lastActivityAt": "2026-09-18T10:05:00.000Z",
      "lastMessage": {
        "id": "739182640518977",
        "whatsapp_ids": { "linked_devices": "3EB0C767D8A1A2B5" },
        "whatsapp_id": "3EB0C767D8A1A2B5",
        "direction": "inbound",
        "type": "text",
        "timestamp": "2026-09-18T10:05:00.000Z"
      }
    }
  ],
  "hasMore": true,
  "nextCursor": "eyJ2IjoxLCJz...",
  "previousCursor": null
}
```

| Parâmetro de consulta | Significado |
| - | - |
| `limit` | Tamanho da página, de 1 a 100. Padrão 50. |
| `cursor` | `nextCursor` da página anterior. |
| `kind` | `direct`, `group`, `channel` ou `broadcast`. |
| `activeSince` | Conversas com atividade nesse horário ISO 8601 ou depois dele. |
| `activeBefore` | Conversas cuja atividade mais recente é anterior a esse horário ISO 8601. |

Uma conversa só aparece enquanto pelo menos uma das mensagens dela estiver
retida. Uma conversa que recebe uma mensagem nova enquanto você percorre as
páginas vai para o topo da lista; ela não se repete nas páginas seguintes.

## Listar as mensagens de uma conversa

Selecione a conversa pelo `id` ou por um número de telefone E.164 (codifique o
`+` na URL como `%2B`). Por padrão, as mensagens vêm da mais nova para a mais
antiga.

```bash theme={null}
curl "https://api.polymorfa.com/messaging/support-line/chats/739182640518203/messages?limit=50&direction=inbound&types=text,image" \
  -H "Authorization: Bearer $POLYMORFA_PROJECT_TOKEN"
```

```json theme={null}
{
  "success": true,
  "data": [
    {
      "id": "739182640518977",
      "whatsapp_ids": { "linked_devices": "3EB0C767D8A1A2B5" },
      "whatsapp_id": "3EB0C767D8A1A2B5",
      "conversation": { "id": "739182640518203", "phoneNumber": "+15550001111" },
      "direction": "inbound",
      "fromMe": false,
      "type": "image",
      "timestamp": "2026-09-18T10:05:00.000Z",
      "pushName": "Ana",
      "caption": "Receipt",
      "mimeType": "image/jpeg",
      "media": [
        {
          "id": "0e6f1c3a-5a55-4f3c-9d4f-0b1f8f2a9c11",
          "mimeType": "image/jpeg",
          "fileLength": 48213,
          "url": "/messaging/media/0e6f1c3a-5a55-4f3c-9d4f-0b1f8f2a9c11"
        }
      ]
    }
  ],
  "hasMore": true,
  "nextCursor": "eyJ2IjoxLCJz...",
  "previousCursor": null
}
```

| Parâmetro de consulta | Significado |
| - | - |
| `limit` | Tamanho da página, de 1 a 100. Padrão 50. |
| `cursor` | `nextCursor` ou `previousCursor` de uma página anterior. |
| `order` | `desc` (mais novas primeiro, padrão) ou `asc` (mais antigas primeiro). |
| `since` | Mensagens enviadas nesse horário ISO 8601 ou depois dele. |
| `until` | Mensagens enviadas antes desse horário ISO 8601. `since` precisa ser anterior. |
| `direction` | `inbound` (dos contatos) ou `outbound` (enviadas pelo número, inclusive pelos outros dispositivos vinculados dele). |
| `types` | Tipos de mensagem separados por vírgula, até 16, por exemplo `text,image`. |

O objeto `whatsapp_ids` guarda as referências do provedor que a Polymorfa
observou para a mensagem. Ele contém `linked_devices`, `official_api` ou os
dois. Use o `id` da Polymorfa para buscar uma mensagem ou enviar uma resposta.
O campo antigo `whatsapp_id` continua disponível temporariamente para as
integrações que ainda leem uma única referência.

Em um grupo, uma mensagem recebida inclui `conversation.sender`, o autor. Os
campos da mensagem são os mesmos de `message.received`: `text`, `caption`,
`mimeType`, `filename`, `ptt`, `latitude`, `longitude`, `displayName`,
`title`, `reaction`, `reactionTo`, `edited`, `unavailable`,
`unavailableReason` e `pollOptions` aparecem quando a mensagem armazenada os
tem. As mensagens enviadas pela API são armazenadas com o tipo e os
identificadores; o corpo delas não faz parte do registro armazenado.

## Paginação

Os cursores são opacos. Devolva-os sem alterações, com o mesmo caminho e os
mesmos filtros. Um cursor usado com outros filtros ou em outra conversa
retorna `400 invalid_parameter` com `param: "cursor"`; comece de novo sem
cursor.

* `nextCursor` continua na `order` atual. Ele é `null` na última página, e
  `hasMore` é `false`.
* `previousCursor` retorna a página anterior à atual. Ele é `null` na primeira
  página. Listas de conversas não têm cursor anterior.

```ts theme={null}
let cursor: string | undefined;
do {
  const url = new URL("https://api.polymorfa.com/messaging/support-line/chats/739182640518203/messages");
  url.searchParams.set("limit", "100");
  if (cursor) url.searchParams.set("cursor", cursor);
  const response = await fetch(url, { headers: { Authorization: `Bearer ${token}` } });
  if (!response.ok) throw new Error(`history request failed: ${response.status}`);
  const page = await response.json();
  for (const message of page.data) store(message);
  cursor = page.nextCursor ?? undefined;
} while (cursor);
```

## Mídia

O histórico nunca retorna chaves de mídia do WhatsApp, caminhos de download ou
URLs de armazenamento. Uma mensagem de imagem, vídeo, áudio, documento ou
figurinha tem um array `media`. Baixe os itens de mídia de Dispositivos
vinculados com [Download linked media](/api-reference/messaging/media/download-linked-media)
usando uma credencial com `media:read`. Baixe a mídia armazenada de uma
mensagem da API oficial com [Download stored message media](/api-reference/messaging/conversations/get-chat-message-media)
usando `messages:read` e `media:read`. Um ID de mídia armazenada não é um ID
de mídia vinculada. O array fica vazio quando a Polymorfa não tem uma cópia
desse arquivo que possa ser baixada.

### Mídia da API oficial

O WhatsApp mantém a mídia de uma mensagem da API oficial por tempo limitado.
Quando o armazenamento hospedado de mensagens retém uma mensagem desse tipo, a
Polymorfa copia a mídia dela para a região de dados do número. A mensagem passa
a ter um objeto `mediaRetrieval`. Isso vale apenas para números conectados pela
API oficial; em um número que usa o Hybrid Link, a mídia da API oficial não é
copiada.

```json theme={null}
{
  "type": "image",
  "media": [
    {
      "id": "5f0c2a1e-9d3b-5c47-a1f2-6b8e4d7c9a10",
      "mimeType": "image/jpeg",
      "fileLength": 48213,
      "url": "/messaging/support-line/chats/739182640518203/messages/739182640518977/media"
    }
  ],
  "mediaRetrieval": { "state": "stored" }
}
```

| `mediaRetrieval.state` | Significado |
| - | - |
| `pending` | A cópia ainda não foi armazenada. A Polymorfa tenta de novo os downloads que falharam, com intervalos cada vez maiores. |
| `stored` | `media` lista a cópia. Baixe-a pela `url` dela. |
| `unavailable` | O WhatsApp não tem arquivo para esta mensagem. |
| `expired` | O arquivo não podia mais ser baixado, ou a retenção da mensagem terminou antes. |
| `too_large` | O arquivo excede o limite de tamanho indicado abaixo. |
| `unsupported_type` | O tipo do arquivo não corresponde ao tipo da mensagem. |
| `failed` | Todas as tentativas de download falharam. |
| `cancelled` | O armazenamento hospedado de mensagens foi desativado, a região de dados dele mudou ou a conexão da API oficial do número foi removida antes de a cópia ser armazenada. |

Todos os estados, exceto `pending`, são finais. Um estado final diferente de
`stored` tem um `reason`, por exemplo `provider_media_not_found` ou
`media_too_large`; nesse caso, `media` fica vazio.

A Polymorfa armazena arquivos de até 32 MiB, e nunca acima do limite do próprio
WhatsApp para o tipo de mídia: 5 MB para imagens, 500 KB para figurinhas e
16 MB para áudio e vídeo. O WhatsApp disponibiliza um arquivo por 7 dias depois
de entregar a mensagem, então uma cópia que não for armazenada nesse prazo
termina como `expired`.

Baixe a cópia com [Download stored message media](/api-reference/messaging/conversations/get-chat-message-media)
usando uma credencial com `messages:read` e `media:read`. O corpo da resposta é
o próprio arquivo, servido como anexo com o tipo de conteúdo armazenado. A
cópia é excluída junto com a mensagem quando o período de retenção dela
termina.

## Retenção e região de dados

O histórico retorna apenas mensagens dentro do período de retenção do
armazenamento hospedado do número, ou sob preservação legal (legal hold).
Mensagens expiradas não são retornadas, e uma mensagem pode sumir entre duas
páginas quando o período de retenção dela termina.

Toda resposta bem-sucedida tem um cabeçalho `Polymorfa-Data-Region` com o nome
da região que armazenou e serviu o histórico. O histórico é lido apenas na
região do número.

## Erros

| Status | Código | Quando |
| - | - | - |
| `400` | `invalid_parameter` | Um filtro é inválido, ou um cursor não corresponde à solicitação. |
| `403` | `missing_scope` | A credencial não tem `chats:read` ou `messages:read`, ou `media:read` para baixar mídia. |
| `403` | `permission_denied` | A solicitação usou um token de cliente, ou a equipe não está inscrita no beta. |
| `404` | `hms_not_enabled` | O armazenamento hospedado de mensagens está desativado para o número. |
| `404` | `resource_not_found` | O número, a conversa ou a mensagem não está disponível para a credencial, ou não existe uma cópia de mídia armazenada. |
| `503` | `service_unavailable` | O histórico da região do número está temporariamente indisponível. Tente novamente mais tarde. |

Consulte [Erros](/api/errors) para ver o formato completo dos erros.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.