September 3, 2026
Added
WhatsApp lines (beta)
WhatsApp is now a channel you can connect to a Dial iMessage number, documented at WhatsApp lines. It’s enabled per account while in beta — talk to us to request access, and until it’s granted the WhatsApp provisioning endpoints answer 404 rather than 403, because to an account without access the capability doesn’t exist.
Buy a line with it (whatsapp: true on POST /api/v1/numbers, valid only alongside capabilities: ["sms","call","imessage"]) or add it to a line you already hold (POST /api/v1/numbers/{id}/whatsapp). A number reports the channel two ways: capabilities gains whatsapp once it works, and a whatsapp object carries its own status, error and retryAvailableAt — a track independent of setupStatus, since caller-ID can be ready while WhatsApp has failed.
Because a WhatsApp line carries two rails on one number, channel (imessage | whatsapp) is now accepted on POST /api/v1/messages and POST /api/v1/typing. Omitting it keeps each number’s existing behaviour, so nothing you already send changes.
WhatsApp sends are text-only (inbound attachments are unaffected), start at deliveryState: "unconfirmed" and firm up as receipts arrive, report reads unlike SMS, and go out one at a time per line — a second concurrent send is refused rather than queued.
Group conversations
A group is a conversation that isn’t a phone number, so Dial gives it an ID of its own — see Group conversations.
GET /api/v1/groups lists the groups your lines are in. Send into one with groupId on POST /api/v1/messages (exclusive with to; the sending line comes from the group), and read one back with the new GET /api/v1/messages?groupId=… filter. Inbound group messages arrive on message.received carrying groupId, so filters: { "groupId": "…" } waits for one group’s traffic.
to is null on every group message, in both directions: the destination is the group, and a group is not a phone number. Which of your numbers the conversation is on is phoneNumberId, which is set on every message Dial has ever recorded. If your integration reads to as “my number”, that’s the line to change.
A group’s name may be null — Dial stores no copy of a subject participants rename at will, so it’s read live from the line, and a line that can’t answer in time yields a null name rather than failing the listing.
Changed
Message now documents groupId, a nullable to, and whatsapp on channel — plus deliveryState, readState, readAt and deliveryError, which the API has returned for a while and the reference had never listed.
The Send a message reference no longer claims the channel can’t be chosen per request. That was true until one line could carry both iMessage and WhatsApp, which is the case channel exists for.
The MCP tool matrix gains list_groups — and start_typing / stop_typing, which both servers have offered since typing shipped and the table had never listed.
Not yet
Some of this is published ahead of the CLI, SDK and MCP releases that expose it; the REST contract above is live now, and those surfaces follow shortly.
- Typing indicators inside a group aren’t supported —
channel: "whatsapp"typing works one-to-one only. - iMessage groups aren’t supported. The group ID is channel-neutral, so they’ll slot into this same shape.
- There’s no join event. A group your line was just added to shows up as a new entry from
GET /api/v1/groups; list groups when you need to know what’s there.