# Consultare lo stato di un messaggio

`GET /v1/messages/:id`

GET /v1/messages/:id con il `msg_…` restituito dal POST (un id numerico → 404). Un unico vocabolario di stato: `queued | sending | sent | delivered | read | failed | held`. ⚠ Finali: **`read`, `failed` e `held`** (un messaggio trattenuto non lo rimandiamo mai: se serve, rimandalo tu a partire da `heldUntil`). `delivered` NON è finale (`delivered→read` è valido) — se interrompi il polling su `delivered` non vedi la lettura.

**Un rifiuto di WhatsApp NON torna come errore HTTP.** Il POST ha già risposto 202 (accettato, non inviato); se Meta lo rifiuta, lo scopri qui: il messaggio resta `failed` (o `held`) con **`lastErrorCode`**, un codice stabile su cui puoi fare `switch` — `WINDOW_24H_EXPIRED`, `RECIPIENT_OPTED_OUT`, `CONNECTION_TOKEN_REVOKED`… Il `lastError` che arriva accanto è un aiuto in inglese per un umano, non il contratto. Il catalogo completo è nel modulo degli errori.

**E non serve chiedere: te lo segnala il webhook.** Se Meta rifiuta il nostro invio (modello inesistente, parametro non valido, numero disattivato…), ti arriva un `message.status` con `status: "failed"`, `stage: "send"`, lo stesso `failureCode` che vedi qui e `messageId` = il tuo `msg_…`. Una sola volta per messaggio. Le conferme di CONSEGNA di ciò che hai mandato tramite l'API portano **`connectMessageId`** = il tuo `msg_…` (lì il `messageId` è il `wamid` di Meta); se Meta lo rifiuta in consegna, `stage: "delivery"` + `failureCode`, e lo stesso codice resta in `lastErrorCode`.

## Esempi

### 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
```

## Note

- Non conserviamo contenuti: questa risposta contiene metadati (stato, tentativi, holdReason), mai il testo del messaggio.
- Il rifiuto più comune è `WINDOW_24H_EXPIRED`: hai mandato testo libero a qualcuno che non ti ha scritto nelle ultime 24 ore. Si risolve con un modello approvato.
