> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blujay.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Effects and text styles

> Add iMessage screen and bubble effects to a message, and style ranges of text as bold, italic, strikethrough or underline.

iMessage lets a message arrive with a full-screen effect, such as confetti, or a bubble effect, such as slam. It also lets parts of the text appear bold, italic, struck through or underlined. You add effects with `message.effect` and text styles with `text_decorations` on a text part, both on follow-up messages sent with `POST /v1/chats/{chat_id}/messages`.

## Send a message with an effect

Set `message.effect` to an object with a `type` and a `name`.

```bash curl theme={null}
curl https://api.blujay.io/v1/chats/chat_abc123/messages \
  -H "Authorization: Bearer blu_your_api_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: launch-confetti-001" \
  -d '{
    "message": {
      "parts": [{ "type": "text", "text": "Your account is live. Welcome aboard!" }],
      "effect": { "type": "screen", "name": "confetti" }
    }
  }'
```

```json Response (202) theme={null}
{
  "status": "success",
  "data": {
    "chat_id": "chat_abc123",
    "message": {
      "id": "msg_abc123",
      "direction": "outbound",
      "delivery_status": "queued",
      "preferred_service": null,
      "service": null,
      "from": "+15555550100",
      "to": ["+15555550123"],
      "created_at": "2026-10-14T17:30:00.000Z",
      "parts": [{ "type": "text", "text": "Your account is live. Welcome aboard!" }]
    }
  },
  "trace_id": "trc_7a9c1e3b5d0f",
  "timestamp": "2026-10-14T17:30:00.130Z"
}
```

`name` must be one of the names for its `type`. Anything else returns `400` [`VALIDATION_ERROR`](/errors/validation-error).

| `type` | Valid `name` values |
| - | - |
| `screen` | `confetti`, `fireworks`, `lasers`, `sparkles`, `celebration`, `hearts`, `love`, `balloons`, `happy_birthday`, `echo`, `spotlight` |
| `bubble` | `slam`, `loud`, `gentle`, `invisible` |

## Know where effects work

Effects work on text-only follow-up messages in these chats:

* **Direct chats, on any service.** You can leave `preferred_service` out or set it to any value. Effects are delivered only over iMessage. If the message goes out as SMS or RCS, the text is still sent without the effect. With `preferred_service: "iMessage"`, the message fails instead if it can't go out as iMessage.
* **Established iMessage group chats.** See [Group chats](/messaging/group-chats.md#know-which-features-need-an-established-imessage-group).

These requests return `400` [`FEATURE_NOT_ENABLED`](/errors/feature-not-enabled) before anything is sent:

* An effect on a chat's first message (`POST /v1/chats`).
* An effect on a message with a link, media or contact card part.
* An effect in a group that isn't an established iMessage group.

The pre-reply rules apply too: an effect doesn't change what you can send before the contact replies. See [Sending rules](/messaging/sending-rules.md).

## Check whether the effect was delivered

Read the message with `GET /v1/messages/{message_id}`. `effect` shows what you asked for, and `degradations` lists anything that was dropped because the message went out as SMS or RCS. `effect` appears only on messages you sent with one; Blujay doesn't report effects on messages your contacts send.

```json theme={null}
{
  "message_id": "msg_abc123",
  "service": "SMS",
  "status": "sent",
  "effect": { "type": "screen", "name": "confetti" },
  "degradations": [
    {
      "code": "effect_not_delivered",
      "reason": "The iMessage effect was not delivered because the message was sent as SMS or RCS."
    }
  ]
}
```

`degradations` is an empty array when nothing was dropped. Message webhooks carry the same entries.

## Style text

Add `text_decorations` to a text part. Each decoration has a `range` and a `style`:

* `range` is `[start, end)` in UTF-16 code units: `start` is the first character to style and `end` is one past the last. `end` must be greater than `start` and no greater than the text's length, and a range can't split a character that takes two UTF-16 code units, such as many emoji.
* `style` is `bold`, `italic`, `strikethrough` or `underline`.
* A text part can have up to 100 decorations. Style ranges can overlap, so a word can be both bold and underlined.

```bash curl theme={null}
curl https://api.blujay.io/v1/chats/chat_abc123/messages \
  -H "Authorization: Bearer blu_your_api_key" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: reminder-styled-001" \
  -d '{
    "message": {
      "parts": [
        {
          "type": "text",
          "text": "Reminder: your appointment is Friday at 10am.",
          "text_decorations": [
            { "range": [0, 8], "style": "bold" },
            { "range": [30, 44], "style": "underline" }
          ]
        }
      ]
    }
  }'
```

> [!TIP]
>
> JavaScript string positions are already UTF-16 code units, so `text.indexOf("Friday")` gives you a valid `start`. In Python, convert a character position with `len(text[:i].encode("utf-16-le")) // 2`.

Text styles work only on text-only follow-up messages in direct iMessage chats. These requests return `400` [`FEATURE_NOT_ENABLED`](/errors/feature-not-enabled) before anything is sent:

* Styles on a chat's first message.
* Styles in group chats, or in direct chats that aren't iMessage.
* Styles on a message that also has a link, media or contact card part.
* Any decoration with `animation` instead of `style` (see [Limitations](#limitations)).

To know whether a direct chat is iMessage before you send, read `service` on `GET /v1/chats/{chat_id}`, or send with `preferred_service: "iMessage"`. See [iMessage, RCS or SMS](/messaging/choosing-a-service.md).

The checks above use the chat's confirmed `service`. If a styled message in an iMessage chat still ends up going out as SMS or RCS, the text is sent without styling and `degradations` includes `text_decorations_not_delivered`.

Range problems, such as a range past the end of the text or a decoration with both `style` and `animation`, return `400` [`VALIDATION_ERROR`](/errors/validation-error).

Text styles are outbound only. When a contact sends you bold or italic text, the message's text part carries the plain text with no `text_decorations`.

> [!WARNING]
>
> **Common mistakes**
>
> * Effects and styles are for follow-ups. On a first message they return `400` [`FEATURE_NOT_ENABLED`](/errors/feature-not-enabled).
> * An effect or style on a message with a link, media or contact card returns `400` [`FEATURE_NOT_ENABLED`](/errors/feature-not-enabled). Send the text with the effect, then the file.
> * A `202` doesn't mean the effect played. Check `degradations` on the message or the webhook.
> * `range` is in UTF-16 code units, not characters. Emoji usually count as two.

## Limitations

* **Text animations aren't supported today.** The API reference lists `animation` names (`big`, `small`, `shake`, `nod`, `explode`, `ripple`, `bloom`, `jitter`) in the `text_decorations` schema, but any decoration that uses `animation` returns `400` [`FEATURE_NOT_ENABLED`](/errors/feature-not-enabled) and nothing is sent. Use `style` only.
* Effects and styles are delivered over iMessage only. Over SMS or RCS the text goes out and `degradations` records what was dropped.
* Text styles work in direct chats only (`400` [`FEATURE_NOT_ENABLED`](/errors/feature-not-enabled) in groups). Effects in groups need an established iMessage group. See [Group chats](/messaging/group-chats.md).
* Neither works on a first message, on a message with a link, media or contact card, or before the contact has replied (`400` [`FEATURE_NOT_ENABLED`](/errors/feature-not-enabled), `400` [`PRE_REPLY_CONTENT_BLOCKED`](/errors/pre-reply-content-blocked) for the file). See [Sending rules](/messaging/sending-rules.md).
* Inbound effects and text styles aren't reported. A contact's slam or bold text arrives as plain text with no `effect` and no `text_decorations`.
* Up to 100 decorations per text part (`400` [`VALIDATION_ERROR`](/errors/validation-error)).

## Next steps

> **[iMessage, RCS or SMS](/messaging/choosing-a-service.md)**
>
> Control when a direct message goes out as iMessage, RCS or SMS.

> **[Group chats](/messaging/group-chats.md)**
>
> Learn what makes a group an established iMessage group.

> **[Threaded replies](/messaging/replies.md)**
>
> Reply to a specific message in its iMessage thread.

> **[Track a message](/messaging/lifecycle.md)**
>
> Follow a message from `accepted` to `delivered` or `failed`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.