Group chats
Find a group chat, text into it with chat_id, and read what its members send. BlueBot can text into a group that already exists but can’t start a new one.
BlueBot can text into any group chat that already exists in Messages on your Mac, and read what everyone in it sends. It can’t start a new group: Messages offers no reliable way for an app to do that.
Dana is selling 412 Oak St, and she has a group chat in Messages called “Oak St closing” with the buyers and their lender. Her code finds the chat once, then posts updates into it as the closing moves along.
Find the chat
/v1/chats lists the chats your Mac has copied, newest first. is_group=true leaves out the one-to-one chats:
/v1/chatscurl "https://usebluebot.com/api/v1/chats?is_group=true" \
-H "Authorization: Bearer $BLUEBOT_API_KEY"{
"object": "list",
"data": [
{
"id": "chat_1Hq2LxW9cVbN3mKpRtYs0a",
"object": "chat",
"name": "Oak St closing",
"is_group": true,
"participants": [
"+15555550123",
"+15555550187"
],
"service": "imessage",
"last_message_at": "2026-11-13T19:41:00.000Z",
"created_at": "2026-11-02T14:00:00.000Z"
}
],
"has_more": false,
"next_cursor": null
}| Field | What it tells you |
|---|---|
id | The chat’s id (chat_…). This is what chat_id takes on a send. |
name | The group’s name in Messages, or null when nobody named it. |
participants | Everyone in the chat except you. |
service | imessage for an iMessage group, sms for a group of regular texts. |
To find a group somebody is in, add person: GET /v1/chats?is_group=true&person=+15555550187. A chat’s id stays the same for as long as the group exists, so look it up once and keep it.
A group appears in the list once your Mac has copied it. Under the default Which chats to copy setting, that means a group in which you’ve already texted every other member through BlueBot. A new group of people you’ve never texted that way won’t show until you set Which chats to copy to Everything. explains the setting. When the Mac copies a group BlueBot didn’t know, chat.created fires.
Text into it
Send chat_id in place of to:
/v1/messagescurl -X POST "https://usebluebot.com/api/v1/messages" \
-H "Authorization: Bearer $BLUEBOT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: oak-st-closing-appraisal" \
-d '{
"chat_id": "chat_1Hq2LxW9cVbN3mKpRtYs0a",
"text": "Good news: the appraisal came back at the asking price. Closing is still on for the 24th."
}'{
"id": "msg_2Bf8QzD4kJmA6nXwEuTr1c",
"object": "message",
"direction": "out",
"state": "queued",
"to": null,
"chat_id": "chat_1Hq2LxW9cVbN3mKpRtYs0a",
"contact_id": null,
"hold": null
}Everyone in the group gets it, as if you had typed it in Messages. A group text has "to": null and "contact_id": null, since it goes to the chat rather than one person. Files, send_at, expires_at and metadata work as they do on any send.
Send to or chat_id, never both, or the send is 400 invalid_request. A chat_id that isn’t on your account is 404 not_found.
The id of a one-to-one chat works in chat_id too. BlueBot then sends to that person as if you had used to, so their stop list and their conversation apply.
How groups differ
| One-to-one | Group | |
|---|---|---|
Service with auto | The newest chat’s, else iMessage, with one SMS try if iMessage fails | The group’s own service. No SMS fallback. |
| A failed text | failed, or sent again as SMS once with auto | failed with “Messages couldn’t send it to this group.” |
| The stop list | A text to somebody on it is canceled | Doesn’t apply: BlueBot can’t leave one person out of a group |
| New people a day | Counts the first text to somebody | Never counts |
| Pacing, quiet hours, daily ceiling | Apply | Apply |
The stop list covers one-to-one texts. If somebody in a group asks you to stop, take them out of the group on your phone, or stop texting the group. A reply of STOP inside a group doesn’t put anyone on your stop list.
Read what the group sends
Every text a member sends into a copied group comes in as a message with the group’s chat_id. from and contact_id are the member who sent it, and to is null:
{
"id": "msg_3Lp3VsC7hGqE5tZyKbWn2d",
"object": "message",
"direction": "in",
"state": "received",
"to": null,
"from": "+15555550187",
"chat_id": "chat_1Hq2LxW9cVbN3mKpRtYs0a",
"contact_id": "ct_2Bf8QzD4kJmA6nXwEuTr1c",
"text": "Thanks Dana! Do we need to bring anything to closing?",
"service": "imessage",
"received_at": "2026-11-13T20:02:00.000Z"
}To read one group’s history:
/v1/messagescurl "https://usebluebot.com/api/v1/messages?chat_id=chat_1Hq2LxW9cVbN3mKpRtYs0a" \
-H "Authorization: Bearer $BLUEBOT_API_KEY"Starting a group
BlueBot can’t make a new group chat. To text a new group from your code, start it once by hand:
- In Messages on your Mac or iPhone, start the group with everyone in it and send the first text.
- If you haven’t texted them all through BlueBot, set Which chats to copy to Everything, at least until the group shows up.
- Find the group with
GET /v1/chats?is_group=trueand keep itsid.
From then on your code can text into it whenever it needs to.
What else BlueBot can’t do in a group
BlueBot can’t add or remove people, rename the group, leave it, or send a tapback in it. Those all need Apple’s private frameworks. lists what a Mac can and can’t do.