POST /v1/messages/read with {"messageId": "wamid…"}: the id of a message you RECEIVED (data.message.id of message.received). It goes in the body, not the URL (a URL ends up in access logs, and the id carries the contact's number). The contact sees the blue ticks; Meta also marks the earlier messages of that chat as read. Add "typing": true to also show "typing…": it disappears when you reply or after 25 seconds, whichever comes first.
It is not a send: no msg_…, no quota, it does not count as a message, and no Idempotency-Key (marking twice is harmless). It works the same on Cloud API and Coexistence numbers.
# messageId comes from a message.received event: data.message.id
curl -X POST https://api.waiaconnect.com/v1/messages/read \
-H "Authorization: Bearer wc_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"messageId": "wamid.HBgN…AA==", "typing": true}'
# → { "messageId": "wamid.…", "status": "read", "typing": true, "typingSeconds": 25, "connectionId": "conn_…" }Meta only accepts messages received in the last 30 days → MESSAGE_TOO_OLD. A msg_… id → INVALID_MESSAGE_ID; an id of ANOTHER account → INBOUND_MESSAGE_NOT_FOUND (we never confirm it exists).
Show "typing…" only when you are about to answer (Meta's guidance): a contact who sees it and gets nothing has a worse experience than one who sees nothing.