# Message
A `Message` represents an individual message that is sent to or received from Ably. Messages are delivered through a channel's [`subscribe()`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel.md#subscribe) method or retrieved via [`history()`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel.md#history).
#### Javascript
```
channel.subscribe((message) => {
console.log(message.name, message.data);
});
```
## Properties
The `Message` interface has the following properties:
| Property | Description | Type |
| --- | --- | --- |
| name | The event name, if provided. | String |
| data | The message payload, if provided. | String, JSON Object, or Buffer |
| extras | Metadata and/or ancillary payloads, if provided. Valid payloads include [`push`](https://ably.com/docs/push/publish.md#payload), [`headers`](https://ably.com/docs/channels.md#metadata) (a map of strings to strings for arbitrary customer-supplied metadata), [`ephemeral`](https://ably.com/docs/pub-sub/advanced.md#ephemeral), and [`privileged`](https://ably.com/docs/platform/integrations/skip-integrations.md). | JSON Object |
| id | A Unique ID assigned by Ably to this message. | String |
| clientId | The client ID of the publisher of this message. | String |
| connectionId | The connection ID of the publisher of this message. | String |
| connectionKey | A connection key, which can optionally be included for a REST publish as part of the [publishing on behalf of a realtime client functionality](https://ably.com/docs/pub-sub/advanced.md#publish-on-behalf). | String |
| timestamp | Timestamp when the message was first received by the Ably, as milliseconds since the epoch. | Integer |
| encoding | This will typically be empty as all messages received from Ably are automatically decoded client-side using this value. However, if the message encoding cannot be processed, this attribute will contain the remaining transformations not applied to the `data` payload. | String |
| action | The action type of the message. | |
| serial | A server-assigned identifier that will be the same in all future updates of this message. It can be used to add [annotations](https://ably.com/docs/messages/annotations.md) to a message or to [update or delete](https://ably.com/docs/messages/updates-deletes.md) it. Serial will only be set if you enable annotations, updates, deletes, and appends in [rules](https://ably.com/docs/channels.md#rules). | String |
| annotations | An object containing information about annotations that have been made to the object. | |
| version | An object containing version metadata for messages that have been [updated or deleted](https://ably.com/docs/messages/updates-deletes.md). | |
| Value | Description |
| --- | --- |
| MESSAGE_CREATE | A new message was created. The value is `message.create`. |
| MESSAGE_UPDATE | A message was updated. The value is `message.update`. |
| MESSAGE_DELETE | A message was deleted. The value is `message.delete`. |
| META | A meta-message from the Ably system. The value is `meta`. |
| MESSAGE_SUMMARY | A summary of annotations for a message. The value is `message.summary`. |
| MESSAGE_APPEND | A message was appended to an existing message. The value is `message.append`. |
| Property | Description | Type |
| --- | --- | --- |
| summary | An object whose keys are [annotation types](https://ably.com/docs/messages/annotations.md#annotation-types) and whose values are aggregated [annotation summaries](https://ably.com/docs/messages/annotations.md#annotation-summaries) for that annotation type. The structure of each value depends on the summarization method, for example a `total.v1` entry has a `total` field, while a `flag.v1` entry has `total` and `clientIds` fields. Always populated for a `message.summary` action and may be populated for any other action (in particular, a message retrieved from history will have its latest summary included). | `Record`>` |
| Shape | Description | Type |
| --- | --- | --- |
| SummaryClientIdList | The summary entry for `flag.v1`, and the per-name value for `distinct.v1` and `unique.v1`. | |
| SummaryDistinctValues | The summary entry for `distinct.v1`, an object mapping each name to a `SummaryClientIdList` value. | `Record` |
| SummaryUniqueValues | The summary entry for `unique.v1`, an object mapping each name to a `SummaryClientIdList` value. | `Record` |
| SummaryMultipleValues | The summary entry for `multiple.v1`, an object mapping each name to a summary client ID counts value. | `Record`>` |
| SummaryTotal | The summary entry for `total.v1`. | |
| Property | Description | Type |
| --- | --- | --- |
| total | The total number of clients who have published an annotation with this name (or type, depending on context). | Number |
| clientIds | A list of the clientIds of all clients who have published an annotation with this name (or type, depending on context). | `String[]` |
| clipped | Whether the list of clientIds has been clipped due to exceeding the maximum number of clients. | Boolean |
| Property | Description | Type |
| --- | --- | --- |
| total | The sum of the counts from all clients who have published an annotation with this name. | Number |
| clientIds | A map from clientIds to the count each of those clients has contributed. | `Record` |
| totalUnidentified | The sum of the counts from all unidentified clients who have published an annotation with this name, and so who are not included in the `clientIds` map. | Number |
| clipped | Whether the `clientIds` map has been clipped due to exceeding the maximum number of clients. | Boolean |
| totalClientIds | The total number of distinct identified clients (equal to the size of `clientIds` if `clipped` is false). | Number |
| Property | Description | Type |
| --- | --- | --- |
| total | The total number of annotations of this type that have been published for the message. | Number |
| Property | Required | Description | Type |
| --- | --- | --- | --- |
| serial | Optional | An Ably-generated ID that uniquely identifies this version of the message. Can be compared lexicographically to determine version ordering. For an original message with an action of `message.create`, this will be equal to the top-level `serial`. | String |
| timestamp | Optional | The time this version was created (when the update or delete operation was performed). For an original message, this will be equal to the top-level `timestamp`. | Integer |
| clientId | Optional | The client identifier of the user who performed the update or delete operation. Only present for `message.update` and `message.delete` actions. | String |
| description | Optional | Optional description provided when the update or delete was performed. Only present for `message.update` and `message.delete` actions. | String |
| metadata | Optional | Optional metadata provided when the update or delete was performed. Only present for `message.update` and `message.delete` actions. | `Record` |
## Create a message from an encoded object
`Message.fromEncoded(JsonObject: any, channelOptions?: ChannelOptions): Promise`
A static factory method to create a `Message` from a deserialized `Message`-like object encoded using Ably's wire protocol. The returned promise resolves with the decoded message.
### Javascript
```
const message = await Ably.Realtime.Message.fromEncoded(encodedMsg);
```
### Parameters
The `Message.fromEncoded()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| JsonObject | Required | A `Message`-like deserialized object. | Any |
| channelOptions | Optional | If you have an encrypted channel, use this to allow the SDK to decrypt the data. | [ChannelOptions](https://ably.com/docs/pub-sub/api/javascript/realtime/channels.md#get) |
### Returns
`Promise`
Returns a promise. The promise is fulfilled with the decoded message, typed `InboundMessage`: a `Message` whose `id`, `timestamp`, `action`, `version`, and `annotations` fields are guaranteed to be present. The promise is rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object if the object cannot be decoded.
## Create messages from an encoded array
`Message.fromEncodedArray(JsonArray: any[], channelOptions?: ChannelOptions): Promise`
A static factory method to create an array of `Message` objects from an array of deserialized `Message`-like objects encoded using Ably's wire protocol. The returned promise resolves with the decoded messages.
### Javascript
```
const messages = await Ably.Realtime.Message.fromEncodedArray(encodedMsgs);
```
### Parameters
The `Message.fromEncodedArray()` method takes the following parameters:
| Parameter | Required | Description | Type |
| --- | --- | --- | --- |
| JsonArray | Required | An array of `Message`-like deserialized objects. | `Any[]` |
| channelOptions | Optional | If you have an encrypted channel, use this to allow the SDK to decrypt the data. | [ChannelOptions](https://ably.com/docs/pub-sub/api/javascript/realtime/channels.md#get) |
### Returns
`Promise`
Returns a promise. The promise is fulfilled with an array of decoded messages, typed `InboundMessage` as for [`fromEncoded()`](#from-encoded-returns). The promise is rejected with an [`ErrorInfo`](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-client.md#errorinfo) object if the array cannot be decoded.
## Related Topics
- [Channels](https://ably.com/docs/pub-sub/api/javascript/realtime/channels.md): API reference for the Channels interface in the Ably Pub/Sub JavaScript Realtime SDK.
- [RealtimeChannel](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-channel.md): API reference for the Channel (RealtimeChannel) interface in the Ably Pub/Sub JavaScript Realtime SDK.
- [ChannelDetails](https://ably.com/docs/pub-sub/api/javascript/realtime/channel-details.md): API reference for channel metadata (ChannelDetails) in the Ably Pub/Sub JavaScript Realtime SDK.
- [RealtimeAnnotations](https://ably.com/docs/pub-sub/api/javascript/realtime/realtime-annotations.md): API reference for message annotations (the RealtimeAnnotations interface) in the Ably Pub/Sub JavaScript Realtime SDK.
## Documentation Index
To discover additional Ably documentation:
1. Fetch [llms.txt](https://ably.com/llms.txt) for the canonical list of available pages.
2. Identify relevant URLs from that index.
3. Fetch target pages as needed.
Avoid using assumed or outdated documentation paths.