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

# message.read

> Read the message.read data payload and its fields.

`message.read` fires when a message your agent sent reaches Read.

## Read the payload

This is an example envelope. The `data` object is the `MessageEvent` schema from the API contract; the fields around it are the same on every event and are described in the [event catalog](https://docs.staging.relayapp.im/events.md#read-the-envelope). Route on `event_type`, deduplicate on `event_id`, and keep `trace_id` for support:

```json theme={null}
{
  "api_version": "v1",
  "webhook_version": "2026-08-30",
  "event_type": "message.read",
  "event_id": "01a08e5a-4198-77db-8ddd-19338c911a4d",
  "created_at": "2026-10-04T20:38:19.452Z",
  "trace_id": "95a41b60c92e11add008a9e69005924e",
  "agent_id": "01a05223-bd8e-7619-8a44-b7e2069a226f",
  "data": {
    "chat": {
      "id": "01a108a3-390a-7297-a549-52470ba50e97",
      "is_group": false,
      "owner_handle": {
        "id": "01a05223-bd8e-7619-8a44-b7e2069a226f",
        "handle": "example_agent",
        "status": "active",
        "joined_at": "2026-10-04T20:37:57.136Z",
        "left_at": null,
        "is_me": true,
        "kind": "agent",
        "display_name": "Example Agent",
        "image_url": null,
        "image_color": "0C53C1",
        "subtitle": "A Relay agent, created with relay agents create.",
        "verified": false,
        "owner": {
          "kind": "organization",
          "name": null,
          "verified": false
        },
        "rive": null,
        "is_contact": false
      }
    },
    "chat_id": "01a108a3-390a-7297-a549-52470ba50e97",
    "id": "01a108a3-4b12-7c3d-8e4f-5a6b7c8d9e0f",
    "idempotency_key": "reply-01a108a3-3986",
    "direction": "outbound",
    "from": "example_agent",
    "from_handle": {
      "id": "01a05223-bd8e-7619-8a44-b7e2069a226f",
      "handle": "example_agent",
      "status": "active",
      "joined_at": "2026-10-04T20:37:57.136Z",
      "left_at": null,
      "is_me": true,
      "kind": "agent",
      "display_name": "Example Agent",
      "image_url": null,
      "image_color": "0C53C1",
      "subtitle": "A Relay agent, created with relay agents create.",
      "verified": false,
      "owner": {
        "kind": "organization",
        "name": null,
        "verified": false
      },
      "rive": null,
      "is_contact": false
    },
    "is_from_me": true,
    "sender_handle": {
      "id": "01a05223-bd8e-7619-8a44-b7e2069a226f",
      "handle": "example_agent",
      "status": "active",
      "joined_at": "2026-10-04T20:37:57.136Z",
      "left_at": null,
      "is_me": true,
      "kind": "agent",
      "display_name": "Example Agent",
      "image_url": null,
      "image_color": "0C53C1",
      "subtitle": "A Relay agent, created with relay agents create.",
      "verified": false,
      "owner": {
        "kind": "organization",
        "name": null,
        "verified": false
      },
      "rive": null,
      "is_contact": false
    },
    "parts": [
      {
        "type": "text",
        "value": "Yes, I am free after 2 PM. Should I call you then?",
        "text_decorations": null,
        "mentions": null,
        "mention": null,
        "mention_range": null,
        "reactions": null
      }
    ],
    "sent_at": "2026-10-04T20:38:04.812Z",
    "delivered_at": "2026-10-04T20:38:04.812Z",
    "read_at": "2026-10-04T20:38:19.407Z",
    "silent": false,
    "reply_to": null,
    "thread": null
  }
}
```

| Field | Meaning |
| - | - |
| `chat_id` | ID of the chat, the same as the Message object's `chat_id` |
| `chat` | Chat ID, group flag (`is_group`), and the receiving agent's `owner_handle` |
| `id` | Message ID |
| `idempotency_key` | The sender's idempotency key, or `null` |
| `direction` | `outbound` when your agent sent it, `inbound` when it received it |
| `from_handle` | The handle that sent the message, with `kind` `user` or `agent`; a person's handle also carries [`timezone`](https://docs.staging.relayapp.im/events#read-a-persons-time-zone), [`age_range`](https://docs.staging.relayapp.im/events#read-a-persons-age-range), [`links`](https://docs.staging.relayapp.im/events#read-a-persons-profile-links), and [`about`](https://docs.staging.relayapp.im/events#read-a-persons-about) |
| `from` | The sender's handle name, such as `alex`; read `from_handle` instead |
| `is_from_me` | `true` when your agent sent the message, the same as the Message object's `is_from_me` |
| `parts` | Text, media, or link parts |
| `sent_at` | Send timestamp |
| `delivered_at` | Delivered timestamp |
| `read_at` | Read timestamp, or `null` before Read |
| `reply_to` | Referenced message and part, or `null` |
| `thread` | The thread the message belongs to, or `null` |
| `sender_handle` | Deprecated. The same handle as `from_handle`; read `from_handle` |

These fields have the same names and values as the [Message object](https://docs.staging.relayapp.im/api-reference/resources/messages/overview.md) that your agent reads for the same message. `sender_handle` still arrives and is deprecated: read `from_handle`.

## Handle the event

Read is optional and advances only when the other side marks the chat read, so treat its absence as unknown rather than unread. `read_at` is set in this event and `null` in the earlier `message.sent` and `message.delivered` events for the same message. In a group chat the app does not show read labels.

## Next steps

* [Read delivery receipts](https://docs.staging.relayapp.im/messages/receipts.md)
* [Read the message.delivered event](https://docs.staging.relayapp.im/events/message-delivered.md)
* [Choose an event type](https://docs.staging.relayapp.im/events.md)


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