GET /v1/messages/:id with the msg_… returned by POST (a numeric id → 404). One status vocabulary: queued | sending | sent | delivered | read | failed | held. ⚠ Terminal: only read and failed. delivered is NOT terminal (delivered→read is valid) — if you stop polling at delivered you never see the read.
A rejection from WhatsApp does NOT come back as an HTTP error. The POST already answered 202 (accepted, not sent); if Meta refuses it, this is where you find out: the message ends failed (or held) with lastErrorCode, a stable code you can switch on — WINDOW_24H_EXPIRED, RECIPIENT_OPTED_OUT, CONNECTION_TOKEN_REVOKED… The lastError next to it is English help for a human, not the contract. Full catalog in the errors module.
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", … }We store no content: this response carries metadata (status, attempts, holdReason), never the message text.
The most common rejection is WINDOW_24H_EXPIRED: you sent free text to someone who has not written to you in the last 24 hours. An approved template is the way out.