im.messages sends, reads, mutates, and subscribes to messages.
Get a chat.guid before calling message APIs. chat.guid is the server’s chat identifier. It is not an email address or phone number. If you only have a recipient address, create or resolve the chat first with im.chats.create(...).
What You Can Do
Send Text
sendText(...) returns Message. text is trimmed by the server and must not be empty after trimming.
Common Message fields:

Message Effects
Message effects apply to the whole outgoing message: confetti, fireworks, slam, invisible ink, and similar iMessage effects.
Clients that do not support a given effect show the message normally.
Text Formatting
formatting applies bold, italic, underline, strikethrough, or animated text effects to a range of text.
start and length use UTF-16 code units. In plain ASCII text, offsets match what you see on screen. With emoji or other non-BMP characters, one visible character may use two code units.

Send Attachments
Sending an attachment has two steps:- Upload file bytes with
im.attachments.upload(...)to get an attachment GUID. - Pass
uploaded.attachment.guidtosendAttachment(...).
sendAttachment(...) is a server attachment GUID, not a local file path. Upload behavior, file extensions, Live Photos, and downloads are covered in attachments.

Audio Messages
To use Apple’s audio-message bubble UI, setisAudioMessage: true:

Send Mini App Cards
sendCustomizedMiniApp(...) sends a card that, when tapped, opens your iMessage extension and hands it url. Use it to launch your own app with a structured payload; for plain link previews, just put the URL in sendText(...).
You need a published iMessage extension on the App Store before you can call this. appName, teamId, and extensionBundleId identify that extension so Messages.app can route the tap to it on the recipient’s device. appStoreId is optional — when set, recipients without the extension installed see an App Store install prompt.
For most cards we recommend an image preview with an overlaid title:
This call does not accept
replyTo, message effects, or subject. The only option you can pass in the final argument is clientMessageId, used as an idempotency key for job retries.Card Layout
layout mirrors Apple’s MSMessageTemplateLayout — slot names match the Apple field names, so Apple’s documentation applies directly.
The server enforces these rules at send time:
- At least one of
caption,subcaption,trailingCaption,trailingSubcaption, orimagemust be set.summaryalone is not enough — it only appears on fallback surfaces. imageandimageTitlemust be set together. Setting one without the other is rejected.imageSubtitlerequiresimage.
Reply to a Message
To reply to a message, pass the target message GUID asreplyTo:
replyTo works with text, attachment, and multipart sends:
For a multipart target, pass both the message GUID and the zero-based bubble index:

Send Multipart Messages
sendMultipart(...) sends text, mentions, and attachments as one logical message. Recipients see related bubbles instead of separate sends.

sendMultipart(...) call.

Reactions and Stickers
Reactions
setReaction(...) adds or removes a tapback / emoji reaction. The fourth argument is true to add and false to remove.

Stickers
A sticker is an image placed on top of a message. Upload the sticker image first, then callplaceSticker(...).
Sticker placement is not screen pixels. Think of the target message bubble as a small coordinate space: x: 0.5, y: 0.5 is roughly the center. Larger x moves right; smaller x moves left. Larger y moves down; smaller y moves up. Start near 0.5, 0.5 and make small adjustments. Do not pass pixel-like values such as 120 or 90.

partIndex. partIndex is zero-based. When omitted, the first bubble is targeted.
placeSticker(...) supports the same partIndex option.
Edit and Unsend
edit(...) changes a sent message and returns the updated Message.
unsend(...) retracts a sent message and returns void.
After the Apple window expires, the server rejects the request and the SDK throws. See error handling.
Notify Anyway
notifySilenced(...) triggers Apple’s “Notify Anyway” action after a recipient has Focus silence enabled.
void. To check Focus state before sending, use im.addresses.isFocusSilenced(address).
Get and List Messages
Get One Message
When you have a message GUID, callget(...):
NotFoundError.
List Recent Messages
listRecent(...) lists recent messages across chats:
listInChat(...) lists messages in one chat:
nextPageToken as the next request’s pageToken:
Embedded Media
Digital Touch and handwritten-message media are not exposed as regular attachments. UsegetEmbeddedMedia(...) to read that media.
Message Events
subscribeEvents(...) streams live message changes. To scope it to one chat, pass { chat: chat.guid }:
Write method return values tell you that the call you made has completed. Event streams are for changes from other people, other devices, or another part of your system. In production, consume live streams and recovery together; see events.
Next Steps
- Attachments — upload files, get attachment GUIDs, and send attachment messages
- Chats — create chats and get
chat.guid - Events — handle live events and recovery
- Error Handling — handle errors, retries, and idempotent writes