Use this file to discover all available pages before exploring further.
im.groups covers iMessage group-only operations: display names, participants, group icons, leaving, and group events.Group methods use the group chat’s chat.guid. If you only have email addresses or phone numbers, create the group first with im.chats.create(...).Direct chats cannot use group APIs. Shared chat features, such as chat creation, read state, typing, and chat backgrounds, are documented under chats.
Except for subscribeEvents(...), which takes an optional { chat } filter, group methods take the group chat.guid as their first argument.Create or fetch a group chat first:
const { chat: group } = await im.chats.create(["alice@example.com", "bob@example.com"]);
Non-empty array; each item must already be a participant
Removing participants usually requires the current account to have permission to manage the group. The server rejects unknown addresses, duplicate addresses, and removals the current account is not allowed to perform.
leave(...) makes the current account leave the group. It cannot rejoin by itself; another participant must invite it again.
Group write methods accept optional { clientMessageId } for idempotent retries from your job system. Most direct calls can omit it. See error handling for details.
subscribeEvents(...) returns TypedEventStream<GroupEvent>. Use the stream to observe changes made by other people, other devices, or another part of your system. Immediately after your code calls a write method, use that method’s Chat result or completion status.
Every group event has type: "group.changed". The outer fields answer which group changed, who triggered it, and when:
{ "type": "group.changed", // Fixed value for group change events "chatGuid": "any;+;group-id", // Group chat that changed "sequence": 123, // Event sequence for ordering and catch-up "isFromMe": false, // Triggered by the current account "occurredAt": "2026-01-01T12:00:00Z", // Event time "actor": { // Participant that triggered the event; may be absent "address": "alice@example.com", "service": "iMessage" }, "change": { // The actual group change "type": "displayNameChanged", "displayName": "Weekend" }}
Switch on event.change.type. When you subscribe to one group, you do not need to check chatGuid again:
for await (const event of im.groups.subscribeEvents({ chat: group.guid })) { switch (event.change.type) { case "displayNameChanged": console.log(event.change.displayName); break; case "participantAdded": case "participantRemoved": case "participantLeft": console.log(event.change.type, event.change.participant.address); break; case "iconChanged": case "iconRemoved": console.log(event.change.type); break; }}
When you subscribe to all visible groups, use event.chatGuid to identify the group:
for await (const event of im.groups.subscribeEvents()) { console.log(event.chatGuid, event.change.type);}
If the stream disconnects, use events to catch up on missed durable events, then continue consuming the live stream.