# Messages ## Send a message to an existing chat `chats.messages.send(strchat_id, MessageSendParams**kwargs) -> MessageSendResponse` **post** `/v3/chats/{chatId}/messages` Send a message to an existing chat. Use this endpoint when you already have a chat ID and want to send additional messages to it. ## Message Effects You can add iMessage effects to make your messages more expressive. Effects are optional and can be either screen effects (full-screen animations) or bubble effects (message bubble animations). **Screen Effects:** `confetti`, `fireworks`, `lasers`, `sparkles`, `celebration`, `hearts`, `love`, `balloons`, `happy_birthday`, `echo`, `spotlight` **Bubble Effects:** `slam`, `loud`, `gentle`, `invisible` Only one effect type can be applied per message. ## Inline Text Decorations (iMessage only) Use the `text_decorations` array on a text part to apply styling and animations to character ranges. Each decoration specifies a `range: [start, end)` and exactly one of `style` or `animation`. **Styles:** `bold`, `italic`, `strikethrough`, `underline` **Animations:** `big`, `small`, `shake`, `nod`, `explode`, `ripple`, `bloom`, `jitter` ```json { "type": "text", "value": "Hello world", "text_decorations": [ { "range": [0, 5], "style": "bold" }, { "range": [6, 11], "animation": "shake" } ] } ``` **Note:** Style ranges (bold, italic, etc.) may overlap, but animation ranges must not overlap with other animations or styles. Text decorations only render for iMessage recipients. For SMS/RCS, text decorations are not applied. ### Parameters - `chat_id: str` - `message: MessageContentParam` Message content container. Groups all message-related fields together, separating the "what" (message content) from the "where" (routing fields like from/to). - `parts: List[Part]` Array of message parts. Each part can be text, media, or link. Parts are displayed in order. Text and media can be mixed freely, but a `link` part must be the only part in the message. **Rich Link Previews:** - Use a `link` part to send a URL with a rich preview card - A `link` part must be the **only** part in the message - To send a URL as plain text (no preview), use a `text` part instead **Supported Media:** - Images: .jpg, .jpeg, .png, .gif, .heic, .heif, .tif, .tiff, .bmp - Videos: .mp4, .mov, .m4v, .mpeg, .mpg, .3gp - Audio: .m4a, .mp3, .aac, .caf, .wav, .aiff, .amr - Documents: .pdf, .txt, .rtf, .csv, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .pages, .numbers, .key, .epub, .zip, .html, .htm - Contact & Calendar: .vcf, .ics **Audio:** - Audio files (.m4a, .mp3, .aac, .caf, .wav, .aiff, .amr) are fully supported as media parts - To send audio as an **iMessage voice memo bubble** (inline playback UI), use the dedicated `/v3/chats/{chatId}/voicememo` endpoint instead **Validation Rules:** - A `link` part must be the **only** part in the message. It cannot be combined with text or media parts. - Consecutive text parts are not allowed. Text parts must be separated by media parts. For example, [text, text] is invalid, but [text, media, text] is valid. - Maximum of **100 parts** total. - Media parts using a public `url` (downloaded by the server on send) are capped at **40**. Parts using `attachment_id` or presigned URLs are exempt from this sub-limit. For bulk media sends exceeding 40 files, pre-upload via `POST /v3/attachments` and reference by `attachment_id` or `download_url`. - `class TextPart: …` - `type: Literal["text"]` Indicates this is a text message part - `"text"` - `value: str` The text content of the message. This value is sent as-is with no parsing or transformation — Markdown syntax will be delivered as plain text. Use `text_decorations` to apply inline formatting and animations (iMessage only). - `text_decorations: Optional[List[TextDecoration]]` Optional array of text decorations applied to character ranges in the `value` field (iMessage only). Each decoration specifies a character range `[start, end)` and exactly one of `style` or `animation`. **Styles:** `bold`, `italic`, `strikethrough`, `underline` **Animations:** `big`, `small`, `shake`, `nod`, `explode`, `ripple`, `bloom`, `jitter` Style ranges may overlap (e.g. bold + italic on the same text), but animation ranges must not overlap with other animations or styles. *Characters are measured as UTF-16 code units. Most characters count as 1; some emoji count as 2.* **Note:** Text decorations only render for iMessage recipients. For SMS/RCS, text decorations are not applied. - `range: List[int]` Character range `[start, end)` in the `value` string where the decoration applies. `start` is inclusive, `end` is exclusive. *Characters are measured as UTF-16 code units. Most characters count as 1; some emoji count as 2.* - `animation: Optional[Literal["big", "small", "shake", 5 more]]` Animated text effect to apply. Mutually exclusive with `style`. - `"big"` - `"small"` - `"shake"` - `"nod"` - `"explode"` - `"ripple"` - `"bloom"` - `"jitter"` - `style: Optional[Literal["bold", "italic", "strikethrough", "underline"]]` Text style to apply. Mutually exclusive with `animation`. - `"bold"` - `"italic"` - `"strikethrough"` - `"underline"` - `class MediaPart: …` - `type: Literal["media"]` Indicates this is a media attachment part - `"media"` - `attachment_id: Optional[str]` Reference to a file pre-uploaded via `POST /v3/attachments` (optional). The file is already stored, so sends using this ID skip the download step — useful when sending the same file to many recipients. Either `url` or `attachment_id` must be provided, but not both. - `url: Optional[str]` Any publicly accessible HTTPS URL to the media file. The server downloads and sends the file automatically — no pre-upload step required. **Size limit:** 10MB maximum for URL-based downloads. For larger files (up to 100MB), use the pre-upload flow: `POST /v3/attachments` to get a presigned URL, upload directly, then reference by `attachment_id`. **Requirements:** - URL must use HTTPS - File content must be a supported format (the server validates the actual file content) **Supported formats:** - Images: .jpg, .jpeg, .png, .gif, .heic, .heif, .tif, .tiff, .bmp - Videos: .mp4, .mov, .m4v, .mpeg, .mpg, .3gp - Audio: .m4a, .mp3, .aac, .caf, .wav, .aiff, .amr - Documents: .pdf, .txt, .rtf, .csv, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .pages, .numbers, .key, .epub, .zip, .html, .htm - Contact & Calendar: .vcf, .ics **Tip:** Audio sent here appears as a regular file attachment. To send audio as an iMessage voice memo bubble (with inline playback), use `/v3/chats/{chatId}/voicememo`. For repeated sends of the same file, use `attachment_id` to avoid redundant downloads. Either `url` or `attachment_id` must be provided, but not both. - `class LinkPart: …` - `type: Literal["link"]` Indicates this is a rich link preview part - `"link"` - `value: str` URL to send with a rich link preview. The recipient will see an inline card with the page's title, description, and preview image (when available). A `link` part must be the **only** part in the message. To send a URL as plain text (no preview card), use a `text` part instead. - `effect: Optional[MessageEffect]` iMessage effect to apply to this message (screen or bubble effect) - `name: Optional[str]` Name of the effect. Common values: - Screen effects: confetti, fireworks, lasers, sparkles, celebration, hearts, love, balloons, happy_birthday, echo, spotlight - Bubble effects: slam, loud, gentle, invisible - `type: Optional[Literal["screen", "bubble"]]` Type of effect - `"screen"` - `"bubble"` - `idempotency_key: Optional[str]` Optional idempotency key for this message. Use this to prevent duplicate sends of the same message. - `preferred_service: Optional[ServiceType]` Messaging service type - `"iMessage"` - `"SMS"` - `"RCS"` - `reply_to: Optional[ReplyTo]` Reply to another message to create a threaded conversation - `message_id: str` The ID of the message to reply to - `part_index: Optional[int]` The specific message part to reply to (0-based index). Defaults to 0 (first part) if not provided. Use this when replying to a specific part of a multipart message. ### Returns - `class MessageSendResponse: …` Response for sending a message to a chat - `chat_id: str` Unique identifier of the chat this message was sent to - `message: SentMessage` A message that was sent (used in CreateChat and SendMessage responses) - `id: str` Message identifier (UUID) - `created_at: datetime` When the message was created - `delivery_status: Literal["pending", "queued", "sent", 2 more]` Current delivery status of a message - `"pending"` - `"queued"` - `"sent"` - `"delivered"` - `"failed"` - `is_read: bool` Whether the message has been read - `parts: List[Part]` Message parts in order (text, media, and link) - `class TextPartResponse: …` A text message part - `reactions: Optional[List[Reaction]]` Reactions on this message part - `handle: ChatHandle` - `id: str` Unique identifier for this handle - `handle: str` Phone number (E.164) or email address of the participant - `joined_at: datetime` When this participant joined the chat - `service: ServiceType` Messaging service type - `"iMessage"` - `"SMS"` - `"RCS"` - `is_me: Optional[bool]` Whether this handle belongs to the sender (your phone number) - `left_at: Optional[datetime]` When they left (if applicable) - `status: Optional[Literal["active", "left", "removed"]]` Participant status - `"active"` - `"left"` - `"removed"` - `is_me: bool` Whether this reaction is from the current user - `type: ReactionType` Type of reaction. Standard iMessage tapbacks are love, like, dislike, laugh, emphasize, question. Custom emoji reactions have type "custom" with the actual emoji in the custom_emoji field. Sticker reactions have type "sticker" with sticker attachment details in the sticker field. - `"love"` - `"like"` - `"dislike"` - `"laugh"` - `"emphasize"` - `"question"` - `"custom"` - `"sticker"` - `custom_emoji: Optional[str]` Custom emoji if type is "custom", null otherwise - `sticker: Optional[Sticker]` Sticker attachment details when reaction_type is "sticker". Null for non-sticker reactions. - `file_name: Optional[str]` Filename of the sticker - `height: Optional[int]` Sticker image height in pixels - `mime_type: Optional[str]` MIME type of the sticker image - `url: Optional[str]` Presigned URL for downloading the sticker image (expires in 1 hour). - `width: Optional[int]` Sticker image width in pixels - `type: Literal["text"]` Indicates this is a text message part - `"text"` - `value: str` The text content - `text_decorations: Optional[List[TextDecoration]]` Text decorations applied to character ranges in the value - `range: List[int]` Character range `[start, end)` in the `value` string where the decoration applies. `start` is inclusive, `end` is exclusive. *Characters are measured as UTF-16 code units. Most characters count as 1; some emoji count as 2.* - `animation: Optional[Literal["big", "small", "shake", 5 more]]` Animated text effect to apply. Mutually exclusive with `style`. - `"big"` - `"small"` - `"shake"` - `"nod"` - `"explode"` - `"ripple"` - `"bloom"` - `"jitter"` - `style: Optional[Literal["bold", "italic", "strikethrough", "underline"]]` Text style to apply. Mutually exclusive with `animation`. - `"bold"` - `"italic"` - `"strikethrough"` - `"underline"` - `class MediaPartResponse: …` A media attachment part - `id: str` Unique attachment identifier - `filename: str` Original filename - `mime_type: str` MIME type of the file - `reactions: Optional[List[Reaction]]` Reactions on this message part - `handle: ChatHandle` - `is_me: bool` Whether this reaction is from the current user - `type: ReactionType` Type of reaction. Standard iMessage tapbacks are love, like, dislike, laugh, emphasize, question. Custom emoji reactions have type "custom" with the actual emoji in the custom_emoji field. Sticker reactions have type "sticker" with sticker attachment details in the sticker field. - `custom_emoji: Optional[str]` Custom emoji if type is "custom", null otherwise - `sticker: Optional[Sticker]` Sticker attachment details when reaction_type is "sticker". Null for non-sticker reactions. - `size_bytes: int` File size in bytes - `type: Literal["media"]` Indicates this is a media attachment part - `"media"` - `url: str` Presigned URL for downloading the attachment (expires in 1 hour). - `class LinkPartResponse: …` A rich link preview part - `reactions: Optional[List[Reaction]]` Reactions on this message part - `handle: ChatHandle` - `is_me: bool` Whether this reaction is from the current user - `type: ReactionType` Type of reaction. Standard iMessage tapbacks are love, like, dislike, laugh, emphasize, question. Custom emoji reactions have type "custom" with the actual emoji in the custom_emoji field. Sticker reactions have type "sticker" with sticker attachment details in the sticker field. - `custom_emoji: Optional[str]` Custom emoji if type is "custom", null otherwise - `sticker: Optional[Sticker]` Sticker attachment details when reaction_type is "sticker". Null for non-sticker reactions. - `type: Literal["link"]` Indicates this is a rich link preview part - `"link"` - `value: str` The URL - `sent_at: Optional[datetime]` When the message was actually sent (null if still queued) - `delivered_at: Optional[datetime]` When the message was delivered - `effect: Optional[MessageEffect]` iMessage effect applied to a message (screen or bubble effect) - `name: Optional[str]` Name of the effect. Common values: - Screen effects: confetti, fireworks, lasers, sparkles, celebration, hearts, love, balloons, happy_birthday, echo, spotlight - Bubble effects: slam, loud, gentle, invisible - `type: Optional[Literal["screen", "bubble"]]` Type of effect - `"screen"` - `"bubble"` - `from_handle: Optional[ChatHandle]` The sender of this message as a full handle object - `preferred_service: Optional[ServiceType]` Messaging service type - `reply_to: Optional[ReplyTo]` Indicates this message is a threaded reply to another message - `message_id: str` The ID of the message to reply to - `part_index: Optional[int]` The specific message part to reply to (0-based index). Defaults to 0 (first part) if not provided. Use this when replying to a specific part of a multipart message. - `service: Optional[ServiceType]` Messaging service type ### Example ```python import os from linq import LinqAPIV3 client = LinqAPIV3( api_key=os.environ.get("LINQ_API_V3_API_KEY"), # This is the default and can be omitted ) response = client.chats.messages.send( chat_id="550e8400-e29b-41d4-a716-446655440000", message={ "parts": [{ "type": "text", "value": "Hello, world!", }] }, ) print(response.chat_id) ``` #### Response ```json { "chat_id": "550e8400-e29b-41d4-a716-446655440000", "message": { "id": "69a37c7d-af4f-4b5e-af42-e28e98ce873a", "created_at": "2025-10-23T13:07:55.019-05:00", "delivery_status": "pending", "is_read": false, "parts": [ { "reactions": [ { "handle": { "id": "69a37c7d-af4f-4b5e-af42-e28e98ce873a", "handle": "+15551234567", "joined_at": "2025-05-21T15:30:00.000-05:00", "service": "iMessage", "is_me": false, "left_at": "2019-12-27T18:11:19.117Z", "status": "active" }, "is_me": false, "type": "love", "custom_emoji": null, "sticker": { "file_name": "sticker.png", "height": 420, "mime_type": "image/png", "url": "https://cdn.linqapp.com/attachments/a1b2c3d4/sticker.png?signature=...", "width": 420 } } ], "type": "text", "value": "Hello!", "text_decorations": [ { "range": [ 0, 5 ], "animation": "shake", "style": "bold" } ] } ], "sent_at": null, "delivered_at": null, "effect": { "name": "confetti", "type": "screen" }, "from_handle": { "id": "550e8400-e29b-41d4-a716-446655440000", "handle": "+15551234567", "joined_at": "2025-05-21T15:30:00.000-05:00", "service": "iMessage", "is_me": false, "left_at": "2019-12-27T18:11:19.117Z", "status": "active" }, "preferred_service": "iMessage", "reply_to": { "message_id": "550e8400-e29b-41d4-a716-446655440000", "part_index": 0 }, "service": "iMessage" } } ``` ## Get messages from a chat `chats.messages.list(strchat_id, MessageListParams**kwargs) -> SyncListMessagesPagination[Message]` **get** `/v3/chats/{chatId}/messages` Retrieve messages from a specific chat with pagination support. ### Parameters - `chat_id: str` - `cursor: Optional[str]` Pagination cursor from previous next_cursor response - `limit: Optional[int]` Maximum number of messages to return ### Returns - `class Message: …` - `id: str` Unique identifier for the message - `chat_id: str` ID of the chat this message belongs to - `created_at: datetime` When the message was created - `is_delivered: bool` Whether the message has been delivered - `is_from_me: bool` Whether this message was sent by the authenticated user - `is_read: bool` Whether the message has been read - `updated_at: datetime` When the message was last updated - `delivered_at: Optional[datetime]` When the message was delivered - `effect: Optional[MessageEffect]` iMessage effect applied to a message (screen or bubble effect) - `name: Optional[str]` Name of the effect. Common values: - Screen effects: confetti, fireworks, lasers, sparkles, celebration, hearts, love, balloons, happy_birthday, echo, spotlight - Bubble effects: slam, loud, gentle, invisible - `type: Optional[Literal["screen", "bubble"]]` Type of effect - `"screen"` - `"bubble"` - `from_: Optional[str]` DEPRECATED: Use from_handle instead. Phone number of the message sender. - `from_handle: Optional[ChatHandle]` The sender of this message as a full handle object - `id: str` Unique identifier for this handle - `handle: str` Phone number (E.164) or email address of the participant - `joined_at: datetime` When this participant joined the chat - `service: ServiceType` Messaging service type - `"iMessage"` - `"SMS"` - `"RCS"` - `is_me: Optional[bool]` Whether this handle belongs to the sender (your phone number) - `left_at: Optional[datetime]` When they left (if applicable) - `status: Optional[Literal["active", "left", "removed"]]` Participant status - `"active"` - `"left"` - `"removed"` - `parts: Optional[List[Part]]` Message parts in order (text, media, and link) - `class TextPartResponse: …` A text message part - `reactions: Optional[List[Reaction]]` Reactions on this message part - `handle: ChatHandle` - `is_me: bool` Whether this reaction is from the current user - `type: ReactionType` Type of reaction. Standard iMessage tapbacks are love, like, dislike, laugh, emphasize, question. Custom emoji reactions have type "custom" with the actual emoji in the custom_emoji field. Sticker reactions have type "sticker" with sticker attachment details in the sticker field. - `"love"` - `"like"` - `"dislike"` - `"laugh"` - `"emphasize"` - `"question"` - `"custom"` - `"sticker"` - `custom_emoji: Optional[str]` Custom emoji if type is "custom", null otherwise - `sticker: Optional[Sticker]` Sticker attachment details when reaction_type is "sticker". Null for non-sticker reactions. - `file_name: Optional[str]` Filename of the sticker - `height: Optional[int]` Sticker image height in pixels - `mime_type: Optional[str]` MIME type of the sticker image - `url: Optional[str]` Presigned URL for downloading the sticker image (expires in 1 hour). - `width: Optional[int]` Sticker image width in pixels - `type: Literal["text"]` Indicates this is a text message part - `"text"` - `value: str` The text content - `text_decorations: Optional[List[TextDecoration]]` Text decorations applied to character ranges in the value - `range: List[int]` Character range `[start, end)` in the `value` string where the decoration applies. `start` is inclusive, `end` is exclusive. *Characters are measured as UTF-16 code units. Most characters count as 1; some emoji count as 2.* - `animation: Optional[Literal["big", "small", "shake", 5 more]]` Animated text effect to apply. Mutually exclusive with `style`. - `"big"` - `"small"` - `"shake"` - `"nod"` - `"explode"` - `"ripple"` - `"bloom"` - `"jitter"` - `style: Optional[Literal["bold", "italic", "strikethrough", "underline"]]` Text style to apply. Mutually exclusive with `animation`. - `"bold"` - `"italic"` - `"strikethrough"` - `"underline"` - `class MediaPartResponse: …` A media attachment part - `id: str` Unique attachment identifier - `filename: str` Original filename - `mime_type: str` MIME type of the file - `reactions: Optional[List[Reaction]]` Reactions on this message part - `handle: ChatHandle` - `is_me: bool` Whether this reaction is from the current user - `type: ReactionType` Type of reaction. Standard iMessage tapbacks are love, like, dislike, laugh, emphasize, question. Custom emoji reactions have type "custom" with the actual emoji in the custom_emoji field. Sticker reactions have type "sticker" with sticker attachment details in the sticker field. - `custom_emoji: Optional[str]` Custom emoji if type is "custom", null otherwise - `sticker: Optional[Sticker]` Sticker attachment details when reaction_type is "sticker". Null for non-sticker reactions. - `size_bytes: int` File size in bytes - `type: Literal["media"]` Indicates this is a media attachment part - `"media"` - `url: str` Presigned URL for downloading the attachment (expires in 1 hour). - `class LinkPartResponse: …` A rich link preview part - `reactions: Optional[List[Reaction]]` Reactions on this message part - `handle: ChatHandle` - `is_me: bool` Whether this reaction is from the current user - `type: ReactionType` Type of reaction. Standard iMessage tapbacks are love, like, dislike, laugh, emphasize, question. Custom emoji reactions have type "custom" with the actual emoji in the custom_emoji field. Sticker reactions have type "sticker" with sticker attachment details in the sticker field. - `custom_emoji: Optional[str]` Custom emoji if type is "custom", null otherwise - `sticker: Optional[Sticker]` Sticker attachment details when reaction_type is "sticker". Null for non-sticker reactions. - `type: Literal["link"]` Indicates this is a rich link preview part - `"link"` - `value: str` The URL - `preferred_service: Optional[ServiceType]` Messaging service type - `read_at: Optional[datetime]` When the message was read - `reply_to: Optional[ReplyTo]` Indicates this message is a threaded reply to another message - `message_id: str` The ID of the message to reply to - `part_index: Optional[int]` The specific message part to reply to (0-based index). Defaults to 0 (first part) if not provided. Use this when replying to a specific part of a multipart message. - `sent_at: Optional[datetime]` When the message was sent - `service: Optional[ServiceType]` Messaging service type ### Example ```python import os from linq import LinqAPIV3 client = LinqAPIV3( api_key=os.environ.get("LINQ_API_V3_API_KEY"), # This is the default and can be omitted ) page = client.chats.messages.list( chat_id="550e8400-e29b-41d4-a716-446655440000", ) page = page.messages[0] print(page.id) ``` #### Response ```json { "messages": [ { "id": "69a37c7d-af4f-4b5e-af42-e28e98ce873a", "chat_id": "94c6bf33-31d9-40e3-a0e9-f94250ecedb9", "created_at": "2024-01-15T10:30:00Z", "is_delivered": true, "is_from_me": true, "is_read": false, "updated_at": "2024-01-15T10:30:00Z", "delivered_at": "2024-01-15T10:30:10Z", "effect": { "name": "confetti", "type": "screen" }, "from": "+12052535597", "from_handle": { "id": "550e8400-e29b-41d4-a716-446655440000", "handle": "+15551234567", "joined_at": "2025-05-21T15:30:00.000-05:00", "service": "iMessage", "is_me": false, "left_at": "2019-12-27T18:11:19.117Z", "status": "active" }, "parts": [ { "reactions": [ { "handle": { "id": "69a37c7d-af4f-4b5e-af42-e28e98ce873a", "handle": "+15551234567", "joined_at": "2025-05-21T15:30:00.000-05:00", "service": "iMessage", "is_me": false, "left_at": "2019-12-27T18:11:19.117Z", "status": "active" }, "is_me": false, "type": "love", "custom_emoji": null, "sticker": { "file_name": "sticker.png", "height": 420, "mime_type": "image/png", "url": "https://cdn.linqapp.com/attachments/a1b2c3d4/sticker.png?signature=...", "width": 420 } } ], "type": "text", "value": "Hello!", "text_decorations": [ { "range": [ 0, 5 ], "animation": "shake", "style": "bold" } ] } ], "preferred_service": "iMessage", "read_at": "2024-01-15T10:35:00Z", "reply_to": { "message_id": "550e8400-e29b-41d4-a716-446655440000", "part_index": 0 }, "sent_at": "2024-01-15T10:30:05Z", "service": "iMessage" } ], "next_cursor": "next_cursor" } ``` ## Domain Types ### Sent Message - `class SentMessage: …` A message that was sent (used in CreateChat and SendMessage responses) - `id: str` Message identifier (UUID) - `created_at: datetime` When the message was created - `delivery_status: Literal["pending", "queued", "sent", 2 more]` Current delivery status of a message - `"pending"` - `"queued"` - `"sent"` - `"delivered"` - `"failed"` - `is_read: bool` Whether the message has been read - `parts: List[Part]` Message parts in order (text, media, and link) - `class TextPartResponse: …` A text message part - `reactions: Optional[List[Reaction]]` Reactions on this message part - `handle: ChatHandle` - `id: str` Unique identifier for this handle - `handle: str` Phone number (E.164) or email address of the participant - `joined_at: datetime` When this participant joined the chat - `service: ServiceType` Messaging service type - `"iMessage"` - `"SMS"` - `"RCS"` - `is_me: Optional[bool]` Whether this handle belongs to the sender (your phone number) - `left_at: Optional[datetime]` When they left (if applicable) - `status: Optional[Literal["active", "left", "removed"]]` Participant status - `"active"` - `"left"` - `"removed"` - `is_me: bool` Whether this reaction is from the current user - `type: ReactionType` Type of reaction. Standard iMessage tapbacks are love, like, dislike, laugh, emphasize, question. Custom emoji reactions have type "custom" with the actual emoji in the custom_emoji field. Sticker reactions have type "sticker" with sticker attachment details in the sticker field. - `"love"` - `"like"` - `"dislike"` - `"laugh"` - `"emphasize"` - `"question"` - `"custom"` - `"sticker"` - `custom_emoji: Optional[str]` Custom emoji if type is "custom", null otherwise - `sticker: Optional[Sticker]` Sticker attachment details when reaction_type is "sticker". Null for non-sticker reactions. - `file_name: Optional[str]` Filename of the sticker - `height: Optional[int]` Sticker image height in pixels - `mime_type: Optional[str]` MIME type of the sticker image - `url: Optional[str]` Presigned URL for downloading the sticker image (expires in 1 hour). - `width: Optional[int]` Sticker image width in pixels - `type: Literal["text"]` Indicates this is a text message part - `"text"` - `value: str` The text content - `text_decorations: Optional[List[TextDecoration]]` Text decorations applied to character ranges in the value - `range: List[int]` Character range `[start, end)` in the `value` string where the decoration applies. `start` is inclusive, `end` is exclusive. *Characters are measured as UTF-16 code units. Most characters count as 1; some emoji count as 2.* - `animation: Optional[Literal["big", "small", "shake", 5 more]]` Animated text effect to apply. Mutually exclusive with `style`. - `"big"` - `"small"` - `"shake"` - `"nod"` - `"explode"` - `"ripple"` - `"bloom"` - `"jitter"` - `style: Optional[Literal["bold", "italic", "strikethrough", "underline"]]` Text style to apply. Mutually exclusive with `animation`. - `"bold"` - `"italic"` - `"strikethrough"` - `"underline"` - `class MediaPartResponse: …` A media attachment part - `id: str` Unique attachment identifier - `filename: str` Original filename - `mime_type: str` MIME type of the file - `reactions: Optional[List[Reaction]]` Reactions on this message part - `handle: ChatHandle` - `is_me: bool` Whether this reaction is from the current user - `type: ReactionType` Type of reaction. Standard iMessage tapbacks are love, like, dislike, laugh, emphasize, question. Custom emoji reactions have type "custom" with the actual emoji in the custom_emoji field. Sticker reactions have type "sticker" with sticker attachment details in the sticker field. - `custom_emoji: Optional[str]` Custom emoji if type is "custom", null otherwise - `sticker: Optional[Sticker]` Sticker attachment details when reaction_type is "sticker". Null for non-sticker reactions. - `size_bytes: int` File size in bytes - `type: Literal["media"]` Indicates this is a media attachment part - `"media"` - `url: str` Presigned URL for downloading the attachment (expires in 1 hour). - `class LinkPartResponse: …` A rich link preview part - `reactions: Optional[List[Reaction]]` Reactions on this message part - `handle: ChatHandle` - `is_me: bool` Whether this reaction is from the current user - `type: ReactionType` Type of reaction. Standard iMessage tapbacks are love, like, dislike, laugh, emphasize, question. Custom emoji reactions have type "custom" with the actual emoji in the custom_emoji field. Sticker reactions have type "sticker" with sticker attachment details in the sticker field. - `custom_emoji: Optional[str]` Custom emoji if type is "custom", null otherwise - `sticker: Optional[Sticker]` Sticker attachment details when reaction_type is "sticker". Null for non-sticker reactions. - `type: Literal["link"]` Indicates this is a rich link preview part - `"link"` - `value: str` The URL - `sent_at: Optional[datetime]` When the message was actually sent (null if still queued) - `delivered_at: Optional[datetime]` When the message was delivered - `effect: Optional[MessageEffect]` iMessage effect applied to a message (screen or bubble effect) - `name: Optional[str]` Name of the effect. Common values: - Screen effects: confetti, fireworks, lasers, sparkles, celebration, hearts, love, balloons, happy_birthday, echo, spotlight - Bubble effects: slam, loud, gentle, invisible - `type: Optional[Literal["screen", "bubble"]]` Type of effect - `"screen"` - `"bubble"` - `from_handle: Optional[ChatHandle]` The sender of this message as a full handle object - `preferred_service: Optional[ServiceType]` Messaging service type - `reply_to: Optional[ReplyTo]` Indicates this message is a threaded reply to another message - `message_id: str` The ID of the message to reply to - `part_index: Optional[int]` The specific message part to reply to (0-based index). Defaults to 0 (first part) if not provided. Use this when replying to a specific part of a multipart message. - `service: Optional[ServiceType]` Messaging service type ### Message Send Response - `class MessageSendResponse: …` Response for sending a message to a chat - `chat_id: str` Unique identifier of the chat this message was sent to - `message: SentMessage` A message that was sent (used in CreateChat and SendMessage responses) - `id: str` Message identifier (UUID) - `created_at: datetime` When the message was created - `delivery_status: Literal["pending", "queued", "sent", 2 more]` Current delivery status of a message - `"pending"` - `"queued"` - `"sent"` - `"delivered"` - `"failed"` - `is_read: bool` Whether the message has been read - `parts: List[Part]` Message parts in order (text, media, and link) - `class TextPartResponse: …` A text message part - `reactions: Optional[List[Reaction]]` Reactions on this message part - `handle: ChatHandle` - `id: str` Unique identifier for this handle - `handle: str` Phone number (E.164) or email address of the participant - `joined_at: datetime` When this participant joined the chat - `service: ServiceType` Messaging service type - `"iMessage"` - `"SMS"` - `"RCS"` - `is_me: Optional[bool]` Whether this handle belongs to the sender (your phone number) - `left_at: Optional[datetime]` When they left (if applicable) - `status: Optional[Literal["active", "left", "removed"]]` Participant status - `"active"` - `"left"` - `"removed"` - `is_me: bool` Whether this reaction is from the current user - `type: ReactionType` Type of reaction. Standard iMessage tapbacks are love, like, dislike, laugh, emphasize, question. Custom emoji reactions have type "custom" with the actual emoji in the custom_emoji field. Sticker reactions have type "sticker" with sticker attachment details in the sticker field. - `"love"` - `"like"` - `"dislike"` - `"laugh"` - `"emphasize"` - `"question"` - `"custom"` - `"sticker"` - `custom_emoji: Optional[str]` Custom emoji if type is "custom", null otherwise - `sticker: Optional[Sticker]` Sticker attachment details when reaction_type is "sticker". Null for non-sticker reactions. - `file_name: Optional[str]` Filename of the sticker - `height: Optional[int]` Sticker image height in pixels - `mime_type: Optional[str]` MIME type of the sticker image - `url: Optional[str]` Presigned URL for downloading the sticker image (expires in 1 hour). - `width: Optional[int]` Sticker image width in pixels - `type: Literal["text"]` Indicates this is a text message part - `"text"` - `value: str` The text content - `text_decorations: Optional[List[TextDecoration]]` Text decorations applied to character ranges in the value - `range: List[int]` Character range `[start, end)` in the `value` string where the decoration applies. `start` is inclusive, `end` is exclusive. *Characters are measured as UTF-16 code units. Most characters count as 1; some emoji count as 2.* - `animation: Optional[Literal["big", "small", "shake", 5 more]]` Animated text effect to apply. Mutually exclusive with `style`. - `"big"` - `"small"` - `"shake"` - `"nod"` - `"explode"` - `"ripple"` - `"bloom"` - `"jitter"` - `style: Optional[Literal["bold", "italic", "strikethrough", "underline"]]` Text style to apply. Mutually exclusive with `animation`. - `"bold"` - `"italic"` - `"strikethrough"` - `"underline"` - `class MediaPartResponse: …` A media attachment part - `id: str` Unique attachment identifier - `filename: str` Original filename - `mime_type: str` MIME type of the file - `reactions: Optional[List[Reaction]]` Reactions on this message part - `handle: ChatHandle` - `is_me: bool` Whether this reaction is from the current user - `type: ReactionType` Type of reaction. Standard iMessage tapbacks are love, like, dislike, laugh, emphasize, question. Custom emoji reactions have type "custom" with the actual emoji in the custom_emoji field. Sticker reactions have type "sticker" with sticker attachment details in the sticker field. - `custom_emoji: Optional[str]` Custom emoji if type is "custom", null otherwise - `sticker: Optional[Sticker]` Sticker attachment details when reaction_type is "sticker". Null for non-sticker reactions. - `size_bytes: int` File size in bytes - `type: Literal["media"]` Indicates this is a media attachment part - `"media"` - `url: str` Presigned URL for downloading the attachment (expires in 1 hour). - `class LinkPartResponse: …` A rich link preview part - `reactions: Optional[List[Reaction]]` Reactions on this message part - `handle: ChatHandle` - `is_me: bool` Whether this reaction is from the current user - `type: ReactionType` Type of reaction. Standard iMessage tapbacks are love, like, dislike, laugh, emphasize, question. Custom emoji reactions have type "custom" with the actual emoji in the custom_emoji field. Sticker reactions have type "sticker" with sticker attachment details in the sticker field. - `custom_emoji: Optional[str]` Custom emoji if type is "custom", null otherwise - `sticker: Optional[Sticker]` Sticker attachment details when reaction_type is "sticker". Null for non-sticker reactions. - `type: Literal["link"]` Indicates this is a rich link preview part - `"link"` - `value: str` The URL - `sent_at: Optional[datetime]` When the message was actually sent (null if still queued) - `delivered_at: Optional[datetime]` When the message was delivered - `effect: Optional[MessageEffect]` iMessage effect applied to a message (screen or bubble effect) - `name: Optional[str]` Name of the effect. Common values: - Screen effects: confetti, fireworks, lasers, sparkles, celebration, hearts, love, balloons, happy_birthday, echo, spotlight - Bubble effects: slam, loud, gentle, invisible - `type: Optional[Literal["screen", "bubble"]]` Type of effect - `"screen"` - `"bubble"` - `from_handle: Optional[ChatHandle]` The sender of this message as a full handle object - `preferred_service: Optional[ServiceType]` Messaging service type - `reply_to: Optional[ReplyTo]` Indicates this message is a threaded reply to another message - `message_id: str` The ID of the message to reply to - `part_index: Optional[int]` The specific message part to reply to (0-based index). Defaults to 0 (first part) if not provided. Use this when replying to a specific part of a multipart message. - `service: Optional[ServiceType]` Messaging service type