# Inbox

What you can send and receive on iMessage: media, voice notes, effects, reactions, edit and unsend, group chats and the SMS/RCS fallback

iMessage conversations live in the [unified inbox](/messages/list-inbox-conversations).

Sending is the same [`POST /v1/inbox/conversations/{conversationId}/messages`](/messages/send-inbox-message) call as every other channel, with `accountId` set to the sender's account. iMessage adds a few fields of its own.

## What you can send

| Feature | Supported |
|---|---|
| Text | Yes, under 10,000 characters. Inline markup renders as rich text: `*bold*`, `_italic_`, `__underline__`, `~strikethrough~` |
| Images, videos, files | Yes, up to 10 attachments per message, each a public `https` URL of at most 256 characters |
| Voice notes | Yes with `voiceNote: true` on an audio attachment; dashboard recordings are transcoded to what Apple plays natively |
| Location pin | Yes via `location`; renders as a native map bubble |
| Contact card | Yes with `contactCard: true`; shares the sender's own card, set on the sender first |
| Subject | Yes, `subject` renders as a bold title line above the text |
| Effects | Yes, `effect` plays an Apple screen or bubble animation: `slam`, `loud`, `gentle`, `invisibleInk`, `echo`, `spotlight`, `balloons`, `confetti`, `love`, `lasers`, `fireworks`, `shootingStar`, `celebration` |
| Replies | Yes via `replyTo` |
| Link previews | On by default; `linkPreview: false` sends links as plain text |
| Channel override | `channel` forces `imessage`, `sms`, `rcs` or `whatsapp` for one send; leave it unset so the provider picks per contact |
| Typing indicator and read receipts | Yes, inside an active two-way conversation |

`subject`, `effect`, `contactCard` and `channel` are accepted on the JSON body only and return `400` on other platforms.

## Edit and unsend

An outbound message can be edited within 15 minutes and unsent within 2 minutes of sending, Apple's own limits.

- [`PATCH …/messages/{messageId}`](/messages/edit-inbox-message) with `text` edits it and keeps the edit history on the stored message.
- [`DELETE …/messages/{messageId}`](/messages/delete-inbox-message) unsends it and leaves a tombstone.

Outside the window the calls return `409` with `edit_window_expired` or `unsend_window_expired`.

## Reactions

Apple's six tapbacks (❤️ 👍 👎 😂 ‼️ ❓) render natively. Any other emoji is sent as a custom emoji tapback, which iOS 18 and later display.

Inbound reactions arrive on the `reaction.received` webhook and on the message's `reactions`, keyed per reactor.

When the reaction targeted one attachment of a multi-attachment message, it carries the attachment index. See [Add message reaction](/messages/add-message-reaction).

## What you receive

Inbound messages fire `message.received` and carry, in `metadata`:

- the channel the message arrived on
- the message type (text, audio, attachments, sticker, location)
- the reply thread id
- a detected language code
- the transcript of a voice message
- any rich-text markup as `markdownText`

A shared location or sticker arrives without coordinates. A Maps link in the text is parsed into a location when present.

A FaceTime call attempt shows up in the thread as a call-typed message.

Inbound media is copied to Zernio storage so the URLs outlive the provider's retention.

Delivery follows `message.delivered` and `message.failed`. A send the provider defers to respect sending intervals sits at `queued` until it goes out.

## Group chats

Group threads arrive on their own conversation with `isGroup: true`. Replying uses the normal send call.

- [`GET /v1/imessage/groups/{conversationId}`](/imessage/get-imessage-group) returns the participants.
- [`PATCH`](/imessage/update-imessage-group) renames the group or changes its photo.
- [`POST`](/imessage/add-imessage-group-participant) / [`DELETE …/participants`](/imessage/remove-imessage-group-participant) add and remove people.

Starting a group from a sender is [`POST /v1/imessage/groups`](/imessage/create-imessage-group). It is asynchronous, so the thread appears on the first group webhook.

Group writes are applied by the provider in the background. A `200` means accepted.

## Messaging new contacts

A sender you order through Zernio can start a conversation with someone who never wrote to it. Use [`POST /v1/inbox/conversations`](/messages/create-inbox-conversation) or **New message** in the dashboard.

- The first message is an introduction. Cold outreach is fine, but no links, emails, phone numbers, prices or attachments.
- New conversations are paced and warmed up per sender.
- Until the contact replies, you can follow up at most twice, a day apart.

See [New Contacts](/platforms/imessage/new-contacts) for the full rules.

Contacts who wrote to you within the last day can be replied to without any interval.

Messages to contacts who have not written in the last 24 hours are spaced at least 2 minutes apart per sender. Inside that window you get `429` with `new_contact_limit`.

A send to a contact who has opted out returns `409` with `recipient_opted_out`. See [Opt-in & Audience](/platforms/imessage/opt-in).