## Send a message to an existing chat

`client.Chats.Messages.Send(ctx, chatID, body) (*ChatMessageSendResponse, error)`

**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

- `chatID string`

- `body ChatMessageSendParams`

  - `Message param.Field[MessageContent]`

    Message content container. Groups all message-related fields together,
    separating the "what" (message content) from the "where" (routing fields like from/to).

### Returns

- `type ChatMessageSendResponse struct{…}`

  Response for sending a message to a chat

  - `ChatID string`

    Unique identifier of the chat this message was sent to

  - `Message SentMessage`

    A message that was sent (used in CreateChat and SendMessage responses)

    - `ID string`

      Message identifier (UUID)

    - `CreatedAt Time`

      When the message was created

    - `DeliveryStatus SentMessageDeliveryStatus`

      Current delivery status of a message

      - `const SentMessageDeliveryStatusPending SentMessageDeliveryStatus = "pending"`

      - `const SentMessageDeliveryStatusQueued SentMessageDeliveryStatus = "queued"`

      - `const SentMessageDeliveryStatusSent SentMessageDeliveryStatus = "sent"`

      - `const SentMessageDeliveryStatusDelivered SentMessageDeliveryStatus = "delivered"`

      - `const SentMessageDeliveryStatusFailed SentMessageDeliveryStatus = "failed"`

    - `IsRead bool`

      Whether the message has been read

    - `Parts []SentMessagePartUnion`

      Message parts in order (text, media, and link)

      - `type TextPartResponse struct{…}`

        A text message part

        - `Reactions []Reaction`

          Reactions on this message part

          - `Handle ChatHandle`

            - `ID string`

              Unique identifier for this handle

            - `Handle string`

              Phone number (E.164) or email address of the participant

            - `JoinedAt Time`

              When this participant joined the chat

            - `Service ServiceType`

              Messaging service type

              - `const ServiceTypeiMessage ServiceType = "iMessage"`

              - `const ServiceTypeSMS ServiceType = "SMS"`

              - `const ServiceTypeRCS ServiceType = "RCS"`

            - `IsMe bool`

              Whether this handle belongs to the sender (your phone number)

            - `LeftAt Time`

              When they left (if applicable)

            - `Status ChatHandleStatus`

              Participant status

              - `const ChatHandleStatusActive ChatHandleStatus = "active"`

              - `const ChatHandleStatusLeft ChatHandleStatus = "left"`

              - `const ChatHandleStatusRemoved ChatHandleStatus = "removed"`

          - `IsMe 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.

            - `const ReactionTypeLove ReactionType = "love"`

            - `const ReactionTypeLike ReactionType = "like"`

            - `const ReactionTypeDislike ReactionType = "dislike"`

            - `const ReactionTypeLaugh ReactionType = "laugh"`

            - `const ReactionTypeEmphasize ReactionType = "emphasize"`

            - `const ReactionTypeQuestion ReactionType = "question"`

            - `const ReactionTypeCustom ReactionType = "custom"`

            - `const ReactionTypeSticker ReactionType = "sticker"`

          - `CustomEmoji string`

            Custom emoji if type is "custom", null otherwise

          - `Sticker ReactionSticker`

            Sticker attachment details when reaction_type is "sticker". Null for non-sticker reactions.

            - `FileName string`

              Filename of the sticker

            - `Height int64`

              Sticker image height in pixels

            - `MimeType string`

              MIME type of the sticker image

            - `URL string`

              Presigned URL for downloading the sticker image (expires in 1 hour).

            - `Width int64`

              Sticker image width in pixels

        - `Type TextPartResponseType`

          Indicates this is a text message part

          - `const TextPartResponseTypeText TextPartResponseType = "text"`

        - `Value string`

          The text content

        - `TextDecorations []TextDecoration`

          Text decorations applied to character ranges in the value

          - `Range []int64`

            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 TextDecorationAnimation`

            Animated text effect to apply. Mutually exclusive with `style`.

            - `const TextDecorationAnimationBig TextDecorationAnimation = "big"`

            - `const TextDecorationAnimationSmall TextDecorationAnimation = "small"`

            - `const TextDecorationAnimationShake TextDecorationAnimation = "shake"`

            - `const TextDecorationAnimationNod TextDecorationAnimation = "nod"`

            - `const TextDecorationAnimationExplode TextDecorationAnimation = "explode"`

            - `const TextDecorationAnimationRipple TextDecorationAnimation = "ripple"`

            - `const TextDecorationAnimationBloom TextDecorationAnimation = "bloom"`

            - `const TextDecorationAnimationJitter TextDecorationAnimation = "jitter"`

          - `Style TextDecorationStyle`

            Text style to apply. Mutually exclusive with `animation`.

            - `const TextDecorationStyleBold TextDecorationStyle = "bold"`

            - `const TextDecorationStyleItalic TextDecorationStyle = "italic"`

            - `const TextDecorationStyleStrikethrough TextDecorationStyle = "strikethrough"`

            - `const TextDecorationStyleUnderline TextDecorationStyle = "underline"`

      - `type MediaPartResponse struct{…}`

        A media attachment part

        - `ID string`

          Unique attachment identifier

        - `Filename string`

          Original filename

        - `MimeType string`

          MIME type of the file

        - `Reactions []Reaction`

          Reactions on this message part

          - `Handle ChatHandle`

          - `IsMe 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.

          - `CustomEmoji string`

            Custom emoji if type is "custom", null otherwise

          - `Sticker ReactionSticker`

            Sticker attachment details when reaction_type is "sticker". Null for non-sticker reactions.

        - `SizeBytes int64`

          File size in bytes

        - `Type MediaPartResponseType`

          Indicates this is a media attachment part

          - `const MediaPartResponseTypeMedia MediaPartResponseType = "media"`

        - `URL string`

          Presigned URL for downloading the attachment (expires in 1 hour).

      - `type LinkPartResponse struct{…}`

        A rich link preview part

        - `Reactions []Reaction`

          Reactions on this message part

          - `Handle ChatHandle`

          - `IsMe 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.

          - `CustomEmoji string`

            Custom emoji if type is "custom", null otherwise

          - `Sticker ReactionSticker`

            Sticker attachment details when reaction_type is "sticker". Null for non-sticker reactions.

        - `Type LinkPartResponseType`

          Indicates this is a rich link preview part

          - `const LinkPartResponseTypeLink LinkPartResponseType = "link"`

        - `Value string`

          The URL

    - `SentAt Time`

      When the message was actually sent (null if still queued)

    - `DeliveredAt Time`

      When the message was delivered

    - `Effect MessageEffect`

      iMessage effect applied to a message (screen or bubble effect)

      - `Name string`

        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 MessageEffectType`

        Type of effect

        - `const MessageEffectTypeScreen MessageEffectType = "screen"`

        - `const MessageEffectTypeBubble MessageEffectType = "bubble"`

    - `FromHandle ChatHandle`

      The sender of this message as a full handle object

    - `PreferredService ServiceType`

      Messaging service type

    - `ReplyTo ReplyTo`

      Indicates this message is a threaded reply to another message

      - `MessageID string`

        The ID of the message to reply to

      - `PartIndex int64`

        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 ServiceType`

      Messaging service type

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/linq-team/linq-go"
  "github.com/linq-team/linq-go/option"
)

func main() {
  client := linqgo.NewClient(
    option.WithAPIKey("My API Key"),
  )
  response, err := client.Chats.Messages.Send(
    context.TODO(),
    "550e8400-e29b-41d4-a716-446655440000",
    linqgo.ChatMessageSendParams{
      Message: linqgo.MessageContentParam{
        Parts: []linqgo.MessageContentPartUnionParam{linqgo.MessageContentPartUnionParam{
          OfText: &linqgo.TextPartParam{
            Type: linqgo.TextPartTypeText,
            Value: "Hello, world!",
          },
        }},
      },
    },
  )
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", response.ChatID)
}
```

#### 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"
  }
}
```
