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

# Message Format and Metadata

Messages contain the data that a client is communicating, such as the contents of a chat message. Clients publish messages on [channels](/docs/pubsub/channels/overview), and these messages are received by clients that have [subscribed](/docs/pubsub/channels/subscribe) to them.

<Aside data-type="note">
  Messages are counted in 5KiB chunks. See [what counts as a message](https://faqs.ably.com/how-does-ably-count-messages).
</Aside>

## Message properties

The following are the properties of a message:

| Property         | Description                                                                                                                                                                     |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **name**         | The name of the message                                                                                                                                                         |
| **data**         | The contents of the message. Also known as the message payload                                                                                                                  |
| **id**           | Each message sent through Ably is assigned a unique ID, unless you provide your own ID, which serves as the idempotency key                                                     |
| **clientId**     | The ID of the client that published the message                                                                                                                                 |
| **connectionId** | The ID of the connection used to publish the message                                                                                                                            |
| **timestamp**    | The timestamp of when the message was first received by Ably, as milliseconds since the Unix epoch                                                                              |
| **extras**       | A JSON object of arbitrary key-value pairs that may contain metadata, and/or ancillary payloads. Valid payloads include those related to Push Notifications, deltas and headers |
| **encoding**     | This is typically empty, as all messages received from Ably are automatically decoded client-side using this value                                                              |

## Accessing message properties

When you receive a message, you can access all its properties:

<Code>
  ```javascript theme={null}
  await channel.subscribe((message) => {
    console.log('Name:', message.name);
    console.log('Data:', message.data);
    console.log('Client ID:', message.clientId);
    console.log('Connection ID:', message.connectionId);
    console.log('Timestamp:', message.timestamp);
    console.log('Message ID:', message.id);
    console.log('Extras:', message.extras);
  });
  ```

  ```python theme={null}
  def listener(message):
      print('Name:', message.name)
      print('Data:', message.data)
      print('Client ID:', message.client_id)
      print('Connection ID:', message.connection_id)
      print('Timestamp:', message.timestamp)
      print('Message ID:', message.id)
      print('Extras:', message.extras)

  await channel.subscribe(listener)
  ```

  ```java theme={null}
  channel.subscribe(new MessageListener() {
      @Override
      public void onMessage(Message message) {
          System.out.println("Name: " + message.name);
          System.out.println("Data: " + message.data);
          System.out.println("Client ID: " + message.clientId);
          System.out.println("Connection ID: " + message.connectionId);
          System.out.println("Timestamp: " + message.timestamp);
          System.out.println("Message ID: " + message.id);
      }
  });
  ```
</Code>

## Message data types

The `data` property of a message can contain different types of data:

### String data

<Code>
  ```javascript theme={null}
  await channel.publish('greeting', 'Hello, World!');
  ```
</Code>

### JSON objects

<Code>
  ```javascript theme={null}
  await channel.publish('user-update', {
    userId: '123',
    status: 'online',
    lastSeen: Date.now()
  });
  ```
</Code>

### Binary data

<Code>
  ```javascript theme={null}
  const buffer = new ArrayBuffer(8);
  await channel.publish('binary-data', buffer);
  ```
</Code>

## Message extras

The `extras` field allows you to include additional metadata with your messages:

<Code>
  ```javascript theme={null}
  await channel.publish({
    name: 'notification',
    data: 'New message received',
    extras: {
      headers: {
        priority: 'high',
        category: 'alert',
        sender: 'system'
      }
    }
  });
  ```
</Code>

### Push notification extras

When publishing push notifications, use the `extras` field to include push-specific data:

<Code>
  ```javascript theme={null}
  await channel.publish({
    name: 'notification',
    data: 'You have a new message',
    extras: {
      push: {
        notification: {
          title: 'New Message',
          body: 'You have a new message from Sarah'
        },
        data: {
          messageId: '12345'
        }
      }
    }
  });
  ```
</Code>

## Message idempotency

You can provide your own message ID to ensure idempotent publishing. If you publish a message with the same ID twice, only one message will be delivered:

<Code>
  ```javascript theme={null}
  await channel.publish({
    id: 'unique-message-id',
    name: 'event',
    data: 'data'
  });
  ```
</Code>

This is useful for ensuring messages aren't duplicated during retries or network issues.

## Message encoding

Ably automatically handles encoding and decoding of messages:

* JSON objects are automatically serialized and deserialized
* Binary data is properly encoded
* String data is UTF-8 encoded

The `encoding` property tells you what transformations were applied to the message data. In most cases, this will be empty as the SDK handles decoding automatically.

## Message size limits

Messages have the following size limits:

* Maximum message size: 65,536 bytes (64 KiB)
* Messages are counted in 5 KiB chunks for billing purposes

<Aside data-type="note">
  If you need to send larger payloads, consider splitting them into multiple messages or using an external storage service and sending a reference in the message.
</Aside>

## Next steps

* Learn how to [publish messages](/docs/pubsub/channels/publish)
* Learn how to [subscribe to messages](/docs/pubsub/channels/subscribe)
* Explore [message history](/docs/pubsub/history)
* Understand [message delivery tracking](/docs/messages#delivery-tracking)
