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

# GET /v1/messages/unread — Mensagens não lidas

> Recupere todas as mensagens recebidas que ainda não foram lidas para o número conectado.

Recupere as mensagens recebidas que contam como não lidas para o número conectado. O estado de não lida **não** é derivado de um campo `readAt` por mensagem (o `readAt` por mensagem não é mantido para mensagens recebidas). Em vez disso, ele é derivado do `unreadCount` de cada conversa — o mesmo contador exibido no painel — e o `total` da resposta é a **soma do `unreadCount` entre as conversas não lidas**. Cada item inclui essa contagem de não lidas no nível da conversa.

## Endpoint

`GET https://pilotstatus.com.br/v1/messages/unread`

<Note>
  Requer uma chave de API **com escopo de número** (`ps_*`) no cabeçalho `x-api-key`. Chaves com escopo de tenant retornam `403`.
</Note>

## Parâmetros de query

<ParamField query="page" default="1" type="integer">
  Número da página (≥ 1).
</ParamField>

<ParamField query="pageSize" default="30" type="integer">
  Resultados por página (1–100).
</ParamField>

Não há filtro de intervalo de datas neste endpoint; ele retorna todas as mensagens recebidas atualmente não lidas.

## Efeito do modo PII

A resposta depende do **modo PII** configurado para o número (definido no painel, no painel Privacidade & retenção da página API Keys ou nas configurações do número). Este endpoint usa **redigir-e-mostrar** (redact-and-show): ele **não** aplica um filtro rígido por data de retenção — os envelopes das mensagens continuam sendo retornados, mas `content`, `from`, `media` e `fromName`/remetente são anulados e `redacted: true` é definido nas linhas cobertas pela política de PII.

| Modo PII                    | Efeito                                                                                                                                                                                                                                                     |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `STORE_INDEFINITE` (padrão) | Todas as mensagens não lidas são retornadas na íntegra, `redacted: false`.                                                                                                                                                                                 |
| `STORE_X_DAYS`              | Os envelopes continuam sendo retornados, mas as linhas **fora** da janela de retenção são redigidas (`content`/`from`/`media`/remetente anulados, `redacted: true`); as linhas dentro da janela são retornadas na íntegra.                                 |
| `RELAY_ONLY`                | O redigir-e-mostrar se aplica a **todas** as linhas (`redacted: true`) e a resposta adiciona um campo `notice: "PII_RELAY_ONLY"`. Na prática, números `RELAY_ONLY` não armazenam nada, então a lista costuma ficar **vazia** (`messages: []`, `total: 0`). |

## Exemplo

<CodeGroup>
  ```bash cURL theme={null}
  curl "https://pilotstatus.com.br/v1/messages/unread?page=1&pageSize=30" \
    -H "x-api-key: ps_your_key_here"
  ```

  ```json Response (200) theme={null}
  {
    "messages": [
      {
        "id": "cmm04obm46zz0qv4ycjp8x6r2",
        "conversationId": "conv_abc123",
        "conversationUnreadCount": 3,
        "direction": "INBOUND",
        "type": "text",
        "content": "Hi, I need help with my order.",
        "from": "+5511999999999",
        "fromName": "John Doe",
        "redacted": false,
        "readAt": null,
        "createdAt": "2026-06-27T10:15:00.000Z"
      },
      {
        "id": "cmm04xyzabcde1234567890ab",
        "conversationId": "conv_abc123",
        "conversationUnreadCount": 3,
        "direction": "INBOUND",
        "type": "image",
        "content": null,
        "media": {
          "provider": "META",
          "id": "845849791681505",
          "url": "https://media.pilotstatus.com.br/abc123.jpg",
          "mimeType": "image/jpeg",
          "fileName": null
        },
        "from": "+5511999999999",
        "fromName": "John Doe",
        "redacted": false,
        "readAt": null,
        "createdAt": "2026-06-27T10:16:00.000Z"
      }
    ],
    "total": 12,
    "page": 1,
    "pageSize": 30,
    "totalPages": 1
  }
  ```

  ```json RELAY_ONLY (200) theme={null}
  {
    "messages": [],
    "total": 0,
    "page": 1,
    "pageSize": 30,
    "totalPages": 0,
    "notice": "PII_RELAY_ONLY"
  }
  ```
</CodeGroup>

## Campos do objeto de mensagem

<ResponseField name="id" type="string" required>
  ID interno da mensagem no Pilot Status.
</ResponseField>

<ResponseField name="conversationId" type="string" required>
  ID da conversa pai.
</ResponseField>

<ResponseField name="conversationUnreadCount" type="integer" required>
  Contagem total de mensagens não lidas dessa conversa.
</ResponseField>

<ResponseField name="direction" type="string" required>
  Sempre `"INBOUND"` para este endpoint.
</ResponseField>

<ResponseField name="type" type="string" required>
  `text`, `image`, `audio`, `video`, `document`, `location`, `contacts`, `sticker` ou `reaction`.
</ResponseField>

<ResponseField name="content" type="string | null">
  Texto da mensagem ou legenda, quando disponível.
</ResponseField>

<ResponseField name="from" type="string" required>
  Remetente no formato E.164.
</ResponseField>

<ResponseField name="fromName" type="string | null">
  Nome de exibição do remetente (resolvido a partir da conversa), quando disponível.
</ResponseField>

<ResponseField name="media" type="object | null">
  Descritor de mídia `{ provider, id, url, mimeType, fileName }` quando a mensagem carrega mídia; `null` para texto.

  * `media.provider` — o provedor que entregou a mídia — `"META"` para números da Meta Cloud API, ou uma tag interna de provedor para números não oficiais.
  * `media.id` — id de mídia da **Meta**. Definido em números `META` — passe-o para `GET /v1/media/{mediaId}` para baixar os bytes; `null` para números não oficiais.
  * `media.url` — URL de download direto quando disponível. Mídia recebida da **META** é espelhada no S3 (então mensagens META geralmente carregam tanto `id` **quanto** `url`); o provedor não oficial fornece seu próprio link. Melhor esforço — pode ser `null`.
  * `media.mimeType` — Tipo MIME da mídia quando conhecido (pode ser `null`).
  * `media.fileName` — Nome do arquivo da mídia quando conhecido (pode ser `null`).
</ResponseField>

<ResponseField name="redacted" type="boolean">
  `true` quando `content`, `media` e os campos do remetente foram anulados pela política de PII do número (veja [Efeito do modo PII](#efeito-do-modo-pii)); `false` (ou ausente) quando a linha é retornada na íntegra.
</ResponseField>

<ResponseField name="readAt" type="null" required>
  Sempre `null` — o `readAt` por mensagem não é mantido para mensagens recebidas; o estado de não lida é rastreado no nível da conversa via `conversationUnreadCount`.
</ResponseField>

<ResponseField name="createdAt" type="string" required>
  ISO 8601 — quando a mensagem foi recebida.
</ResponseField>

## Erros comuns

* `400 NUMBER_NOT_FOUND` — a chave de API não está vinculada a um número de WhatsApp.
* `401` — cabeçalho `x-api-key` ausente ou inválido.
* `403` — chave com escopo de tenant usada (é necessária uma chave com escopo de número).
