You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
`sendMiniApp(...)` sends a tappable iMessage card that opens a URL. Use it when you want a custom preview card instead of an automatic link preview.
189
+
`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(...)`.
190
+
191
+
You need a published iMessage extension on the App Store before you can call this. `appName`, `appStoreId`, `teamId`, and `extensionBundleId` identify that extension so Messages.app can route the tap to it on the recipient's device.
192
+
193
+
For most cards we recommend an image preview with an overlaid title:
190
194
191
195
```ts
192
-
const sent = await im.messages.sendMiniApp(chat.guid, {
193
-
url: "https://photon.codes",
194
-
preview: {
195
-
title: "Photon",
196
-
subtitle: "photon.codes",
197
-
body: "Build messaging agents with advanced iMessage support.",
196
+
const sent = await im.messages.sendCustomizedMiniApp(chat.guid, {
<img src="/images/advanced-kits/imessage/messages/mini-app-card.avif" alt="Mini app card preview showing a custom web page card" />
206
-
</Frame>
207
-
208
-
The SDK only asks for the destination URL and the preview content shown on the card. The server handles the iMessage app-card details internally.
211
+
| Field | Meaning |
212
+
|---|---|
213
+
| `appName` | Display name of your app. Recipients without your extension installed see this on an App Store install prompt. |
214
+
| `appStoreId` | Numeric App Store id, e.g. `1234567890` from `apps.apple.com/app/id1234567890`. Positive integer. |
215
+
| `teamId` | 10-character uppercase alphanumeric Apple Team ID. Find it in App Store Connect → Membership. |
216
+
| `extensionBundleId` | Bundle identifier of the iMessage extension target inside your app. |
217
+
| `url` | Absolute URL delivered to your extension when the recipient taps the card. |
218
+
| `layout` | What the card looks like in the conversation, covered in [Card Layout](#card-layout) below. |
209
219
210
-
Only `url` and `preview.title` are required. Most cards should also set `preview.subtitle`, `preview.body`, and `preview.imageJpeg` when that content is available. To include an image, pass JPEG bytes as `preview.imageJpeg`:
220
+
<Note>
221
+
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.
222
+
</Note>
211
223
212
-
```ts
213
-
await im.messages.sendMiniApp(chat.guid, {
214
-
url: "https://photon.codes",
215
-
preview: {
216
-
title: "Photon",
217
-
subtitle: "photon.codes",
218
-
imageJpeg: await readFile("preview.jpg"),
219
-
},
220
-
});
221
-
```
224
+
### Card Layout
222
225
223
-
| Field | Required | Meaning |
224
-
|---|---|---|
225
-
| `url` | Yes | URL opened when the recipient taps the card |
226
-
| `preview.title` | Yes | Primary text shown on the card |
227
-
| `preview.subtitle` | No | Secondary text |
228
-
| `preview.body` | No | Supporting text |
229
-
| `preview.imageJpeg` | No | JPEG preview image bytes |
230
-
| `preview.caption` | No | Additional small label when the card layout has room |
231
-
| `preview.footer` | No | Additional footer label when the card layout has room |
232
-
| `preview.detail` | No | Additional detail label when the card layout has room |
233
-
| `preview.summary` | No | Fallback summary for surfaces that cannot show the full card |
226
+
`layout` mirrors Apple's `MSMessageTemplateLayout` — slot names match the Apple field names, so Apple's documentation applies directly.
234
227
235
-
| Option | Meaning |
228
+
| Slot | Where it renders |
236
229
|---|---|
237
-
| `clientMessageId` | Optional idempotency key for job retries; pass it as `options.clientMessageId` in the final argument |
230
+
| `caption` | Top-left, bold. The most prominent text slot. |
231
+
| `subcaption` | Below `caption`, on the left. |
232
+
| `trailingCaption` | Top-right. |
233
+
| `trailingSubcaption` | Below `trailingCaption`, on the right. |
234
+
| `image` | JPEG preview image filling the card. |
235
+
| `imageTitle` | Overlay text above the image. |
236
+
| `imageSubtitle` | Overlay text below `imageTitle`. |
237
+
| `summary` | Fallback text for notifications, lock screens, and other surfaces that cannot render the full card. |
238
+
239
+
The server enforces these rules at send time:
240
+
241
+
- At least one of `caption`, `subcaption`, `trailingCaption`, `trailingSubcaption`, or `image` must be set. `summary` alone is not enough — it only appears on fallback surfaces.
242
+
- `image` and `imageTitle` must be set together. Setting one without the other is rejected.
243
+
- `imageSubtitle` requires `image`.
238
244
239
245
<Warning>
240
-
Pass JPEG bytes to `preview.imageJpeg`. If your source image is PNG, WebP, HEIC, or another format, convert it to JPEG before calling `sendMiniApp(...)`.
246
+
`layout.image` must be JPEG bytes. The server checks the JPEG SOI marker (`FF D8`) and rejects any other format. Convert PNG, WebP, HEIC, or anything else to JPEG before calling.
241
247
</Warning>
242
248
243
-
<Note>
244
-
`sendMiniApp(...)` is its own send operation. It does not upload files first, does not take an attachment GUID, and does not use `replyTo` or message effects.
245
-
</Note>
246
-
247
249
## Reply to a Message
248
250
249
251
To reply to a message, pass the target message GUID as `replyTo`:
0 commit comments