im.chats creates and manages iMessage conversations. A chat can be a direct conversation or a group conversation.
Most chat methods identify the conversation by chat.guid. The exceptions are create(...), which takes email addresses or phone numbers and returns chat.guid, and count(...), which does not take a chat argument.
For group names, participants, group icons, and leaving a group, use groups.
What You Can Do
| Need | Use this when |
|---|---|
| Create a chat | You have one or more email addresses or phone numbers |
| Get a chat | You have chat.guid and need chat details |
| Count chats | You need the number of currently visible chats |
| Mark read | A user opened the conversation and you want to clear unread state |
| Set typing | You want to show or hide the typing indicator |
| Share a contact card | You want to send the current account’s contact card |
| Set a background | You want to apply an image as the chat background |
| Subscribe to events | You need live changes for read state, archive state, or backgrounds |
Chat GUIDs
A chat GUID is the server identifier for a conversation:| Chat type | GUID shape | Example |
|---|---|---|
| Direct chat | any;-;{recipient} | any;-;[email protected] |
| Group chat | any;+;{group-id} | any;+;group-id |
chat.guid returned by im.chats.create(...), im.chats.get(...), message results, or event payloads.
Create a Chat
One address creates a direct chat. Two or more addresses create a group chat:CreateChatResult:
| Input | Rule |
|---|---|
addresses | At least one full email address or E.164 phone number |
options.message | Optional opening text; sent as part of the same call |
options.effect | Optional effect for the opening message; values are listed under message effects |
options.clientMessageId | Optional idempotency key for retrying the same logical create operation |
effect only applies when options.message is present. It is not a chat property. For more complex sends, such as formatting or replies, create the chat first and then use the messages API.
clientMessageId is only needed when your job system might retry the same write after a crash or timeout. Most direct calls can omit it. See error handling for details.Get a Chat
Chat:
get(...) throws NotFoundError when the chat does not exist or cannot be resolved.
Count Chats
By default, archived chats are excluded:includeArchived: true:
number.
Read and Typing State
Mark Read
void. Calling it again when the chat has no unread messages is safe.
Typing Indicator
Show typing:void. Typing is temporary UI state. It is not written to the durable event log and cannot be caught up after a disconnect.
Contact Card
void. The contact card comes from the Mac running the service. The SDK cannot choose which fields are included.
Chat Backgrounds
Chat backgrounds use raw image bytes. They are not attachment GUIDs, and you do not upload them throughim.attachments first.
Set a Background
void. data must not be empty. The server detects the image type from the bytes. JPEG, PNG, HEIC, and HEIF are supported.
After setBackground(...) succeeds, the background usually syncs to other participants’ devices within 30s. The image is uploaded to iCloud and then distributed to the conversation. This is not a hard SLA: network state, iCloud state, and the Messages client state all affect when the background appears.
| Stage | What happens |
|---|---|
Before setBackground(...) returns | The server waits until the background asset is uploaded and ready for distribution |
After setBackground(...) returns | The chat background change has been submitted, and iCloud distributes the asset |
| On other devices | The background appears after Messages receives the iCloud-distributed asset |
| Situation | Result |
|---|---|
| The recipient’s network, iCloud, or Messages state is unhealthy | The background may appear late, often after reopening Messages |
| A group member has never spoken, interacted, or is treated by Apple as unknown / untrusted | Apple may not show the background UI to that member |
The last case is a Messages display rule, not an SDK option. If one group member never sees the background, it is usually more effective for that member to send a message, mark the sender as known, or reopen Messages than to call
setBackground(...) repeatedly.Check Background State
boolean.
Remove a Background
void. Removing a background is safe to repeat, even when no custom background is set.
Chat Events
subscribeEvents(...) returns TypedEventStream<ChatEvent>. 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 return value or completion status.
Scope
Only one chat:Event Shape
Every chat event has the same outer fields:Event Types
event.type | Meaning |
|---|---|
chat.backgroundChanged | A custom background was set or replaced |
chat.backgroundRemoved | The custom background was removed |
chat.markedRead | The chat was marked read |
chat.archived | The chat was archived |
chat.unarchived | The chat was unarchived |
Handle Events
event.chatGuid to identify the chat:
Next Steps
- Messages — send, read, edit, and unsend messages with
chat.guid - Groups — manage group names, participants, group icons, and leaving
- Events — catch up on durable events after a disconnect
- Error Handling — handle
NotFoundError,ValidationError, and idempotent retries