WASync · Developers
Changelog

25 July 2026

Read receipts, and messageId becomes WASync's stable id.

Read receipts — POST /messages/read gives your customers blue ticks

New feature.

If your operators read WhatsApp inside your own CRM, nobody ever opens the chat in WhatsApp — the customer's messages stay on double grey ticks and the conversation feels ignored. POST /messages/read sends the WhatsApp read receipt for you.

Body: { connectionId, phone?, messageId? } — at least one of phone / messageId (the latter is WASync's cuid of an incoming message, not waMessageId). It uses the existing whatsapp.send scope, because marking read transmits a receipt to the customer's device — no re-consent needed.

Idempotent by nature: no idempotencyKey, no rate limit, safe to retry. Response { ok: true, marked }, where marked counts the stored inbound messages newly flagged as read.

messageId is now WASync's stable id — WhatsApp's id moves to waMessageId

Breaking change · Improvement.

POST /messages previously returned WhatsApp's own message id (true_…@c.us_3EB0…) as messageId, while GET /messages and the message.received / message.status webhooks used WASync's id — so status events could never be matched back to a send.

They are now the SAME id everywhere: messageId (POST) = id (GET) = message.id (webhooks), a WASync cuid. WhatsApp's own id is still returned, alongside, as waMessageId (REST), wa_id (webhooks) and wa_message_id (media send) — use it for support tickets, never as a join key (it can be null). GET /messages rows now also carry waMessageId, so you can map both ways.

Action required if you stored the value of messageId to match webhooks: it now changes format — join on the new value, and read waMessageId if you specifically needed the WhatsApp id.

One new edge case: if a send reaches WhatsApp but cannot be persisted, the 200 body is { messageId: null, waMessageId, status, persisted: false } — the message was delivered, so do not retry it.

On this page