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

# React to a message

> POST /api/v1/comms/messages/:id/reactions — add or remove a native iMessage tapback.

Add or remove one of the six native iMessage tapbacks on an existing message.

**Scope:** `comms_send`

Native types: `love`, `like`, `dislike`, `laugh`, `emphasize`, `question`.

```bash theme={null}
curl -X POST "https://osis.co/api/v1/comms/messages/$MESSAGE_ID/reactions" \
  -H "Authorization: Bearer $COMMS_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: love-msg-4242" \
  -d '{ "type": "love", "action": "added" }'
```

`action` defaults to `added`. Pass `removed` to take the tapback off.

## Response

### 202 Accepted

```json theme={null}
{
  "reaction": {
    "id": "react_…",
    "message_id": "msg_…",
    "type": "love",
    "emoji": "❤️",
    "action": "added",
    "actor": {
      "kind": "line",
      "handle": "+16282646448",
      "contact_id": null,
      "is_from_me": true
    },
    "created_at": "2026-08-25T12:00:00.000Z",
    "removed_at": null
  },
  "duplicate": false
}
```

### 200 OK (duplicate)

Same idempotency key already processed — no second send.

## Errors

| Status | Code                                | Meaning                                      |
| ------ | ----------------------------------- | -------------------------------------------- |
| 400    | `invalid_tapback`                   | `type` is not one of the six native tapbacks |
| 404    | `message_not_found`                 | Message id is not in this workspace          |
| 409    | `unsupported_transport`             | SMS, RCS, or a non-iMessage conversation     |
| 409    | `reactions_outbound_disabled`       | Outbound tapbacks are gated (canary rollout) |
| 409    | `provider_message_unavailable`      | The bubble has no provider GUID yet          |
| 409    | `provider_conversation_unavailable` | No live iMessage thread id                   |

Inbound tapbacks still persist and fan out even when outbound is gated.
