Inkbox

> # Documentation index
> Fetch the complete documentation index at: https://inkbox.ai/sitemap.xml
> Use this file to discover all available pages before exploring further.

---

# Tapbacks
description: Send tapback reactions to iMessages and read the live reactions on every message

---


# Tapbacks

Tapbacks are iMessage's inline reactions — the heart, thumbs-up, "haha", and friends that attach to a specific message bubble. Agents can send them, humans send them back, and message reads always carry the current live set.

Tapbacks follow Apple's semantics: **one live tapback per sender per message**. Sending a new tapback to a message you already reacted to replaces your previous one. When the human swaps or removes theirs, message reads and webhooks reflect it.

---

## Send tapback `POST`


React to a message in one of your agent's conversations. Any message can be the target — the human's or the agent's own.

### Request body

| Field | Type | Required | Description |
| :--- | :--- | :--- | :--- |
| `message_id` | UUID | Yes | The message being reacted to |
| `reaction` | string | Yes | One of `"love"`, `"like"`, `"dislike"`, `"laugh"`, `"emphasize"`, `"question"` |
| `part_index` | integer | No | Part of a multi-part message to react to. Defaults to `0` |

### Request example

```json
{
    "message_id": "1a90e8b0-0e1e-485f-b316-28f7dfa96afd",
    "reaction": "like"
}
```

### Response (201)

```json
{
    "id": "0f6b8a5e-1ca0-4a4f-8e94-44b3e4374f9a",
    "conversation_id": "82cf24f6-78fe-48da-a673-6a75b4f4a819",
    "assignment_id": "9b2e4a68-8cb1-4f18-b97d-a2324c8b4d1f",
    "target_message_id": "1a90e8b0-0e1e-485f-b316-28f7dfa96afd",
    "direction": "outbound",
    "reaction": "like",
    "custom_emoji": null,
    "remote_number": "+15555550123",
    "part_index": 0,
    "created_at": "2026-06-09T14:31:00Z",
    "updated_at": "2026-06-09T14:31:00Z"
}
```

If the agent already had a live tapback on that message part, it is replaced — exactly what the human sees happen on their device.

### Error responses

| Status | Description |
| :--- | :--- |
| 400 | The conversation's identity is not enabled for iMessage, or the target message cannot accept reactions yet |
| 403 | The conversation's recipient is blocked by a contact rule |
| 404 | Message not found, or not visible to the caller |
| 409 | The recipient has disconnected from this agent and must reconnect through the router |
| 422 | Unknown `reaction` value or invalid `part_index` |
| 502 | Upstream delivery failure — safe to retry |

---

## Receiving tapbacks

Tapbacks from humans arrive two ways:

- **On message reads** — every [message object](/docs/api/imessage/messages#message-object) carries a `reactions` array with the live tapbacks targeting it, oldest first.
- **As webhooks** — [`imessage.reaction_received`](/docs/api/imessage/webhooks#imessagereactionreceived) fires when a human tapbacks one of your agent's messages.

Humans can react with any emoji, not just the classic six. Those arrive with `reaction: "custom"` and the literal emoji in `custom_emoji`:

```json
{
    "id": "5d2c9f4a-3b21-47e0-9c8d-1f6a2b3c4d5e",
    "direction": "inbound",
    "reaction": "custom",
    "custom_emoji": "🌴",
    "remote_number": "+15555550123",
    "part_index": 0,
    "created_at": "2026-06-09T14:32:00Z"
}
```

Custom-emoji tapbacks are receive-only — sends accept the classic six.

When a human removes a tapback, it simply disappears from the message's `reactions` array on the next read. Removals do not fire a webhook.

## Reaction object

| Field | Type | Description |
| :--- | :--- | :--- |
| `id` | string (UUID) | Reaction ID |
| `conversation_id` | string (UUID) | The conversation containing the target message |
| `assignment_id` | string (UUID) | The connection carrying the conversation |
| `target_message_id` | string (UUID) | The message this tapback targets |
| `direction` | string | `"inbound"` (from the human) or `"outbound"` (from the agent) |
| `reaction` | string | `"love"`, `"like"`, `"dislike"`, `"laugh"`, `"emphasize"`, `"question"`, or `"custom"` |
| `custom_emoji` | string \| null | The literal emoji when `reaction` is `"custom"`; null for the classic six |
| `remote_number` | string | The human's phone number (E.164) |
| `part_index` | integer | Message part the tapback targets (`0` for single-part messages) |
| `created_at` | string (ISO 8601) | Creation timestamp |
| `updated_at` | string (ISO 8601) | Last update timestamp |

The compact reaction entries embedded in a message's `reactions` array omit the conversation/assignment/target IDs (they're implied by the message) and the `updated_at` field.
