# Consultar o estado de uma mensagem

`GET /v1/messages/:id`

GET /v1/messages/:id com o `msg_…` que o POST devolveu (um id numérico → 404). Um único vocabulário de estado: `queued | sending | sent | delivered | read | failed | held`. ⚠ Terminais: **`read`, `failed` e `held`** (uma mensagem retida nunca é reenviada por nós: se for preciso, reenvie você a partir de `heldUntil`). `delivered` NÃO é terminal (`delivered→read` é válido) — se você parar o polling em `delivered`, não vê a leitura.

**Uma recusa do WhatsApp NÃO volta como erro HTTP.** O POST já respondeu 202 (aceito, não enviado); se a Meta recusar, você fica sabendo aqui: a mensagem fica `failed` (ou `held`) com **`lastErrorCode`**, um código estável sobre o qual você pode fazer `switch` — `WINDOW_24H_EXPIRED`, `RECIPIENT_OPTED_OUT`, `CONNECTION_TOKEN_REVOKED`… O `lastError` que vem ao lado é ajuda em inglês para um humano, não o contrato. O catálogo completo está no módulo de erros.

**E não é preciso perguntar: o webhook avisa.** Se a Meta recusar o nosso envio (template inexistente, parâmetro inválido, número desativado…), chega um `message.status` com `status: "failed"`, `stage: "send"`, o mesmo `failureCode` que você vê aqui e `messageId` = o seu `msg_…`. Uma única vez por mensagem. Os recibos de ENTREGA do que você mandou pela API trazem **`connectMessageId`** = o seu `msg_…` (o `messageId` ali é o `wamid` da Meta); se a Meta recusar na entrega, `stage: "delivery"` + `failureCode`, e o mesmo código fica em `lastErrorCode`.

## Exemplos

### cURL

```bash
curl https://api.waiaconnect.com/v1/messages/msg_5d325780fe504d0f87eb45009d28ae4f \
  -H "Authorization: Bearer wc_live_YOUR_API_KEY"
# → { "id": "msg_…", "status": "delivered", "attempts": 1, "createdAt": "…Z", … }
```

### Node.js

```javascript
const res = await fetch("https://api.waiaconnect.com/v1/messages/msg_5d325780fe504d0f87eb45009d28ae4f", {
  headers: { "Authorization": "Bearer wc_live_YOUR_API_KEY" }
});
const msg = await res.json();
console.log(msg.status); // queued|sending|sent|delivered|read|failed|held (terminal: read|failed)
```

### PHP

```php
<?php
$ch = curl_init("https://api.waiaconnect.com/v1/messages/msg_5d325780fe504d0f87eb45009d28ae4f");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ["Authorization: Bearer wc_live_YOUR_API_KEY"],
]);
$msg = json_decode(curl_exec($ch), true);
echo $msg["status"]; // read|failed are terminal; delivered can still become read
```

### Python

```python
import requests
res = requests.get("https://api.waiaconnect.com/v1/messages/msg_5d325780fe504d0f87eb45009d28ae4f",
  headers={"Authorization": "Bearer wc_live_YOUR_API_KEY"})
msg = res.json()
print(msg["status"])  # read|failed are terminal; delivered can still become read
```

## Notas

- Não guardamos conteúdo: esta resposta traz metadados (estado, tentativas, holdReason), nunca o texto da mensagem.
- A recusa mais comum é `WINDOW_24H_EXPIRED`: você mandou texto livre para alguém que não te escreveu nas últimas 24 horas. Resolve-se com um template aprovado.
