> ## 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.

# Publishing Messages

Publishing messages to a channel is how clients communicate with one another. Any subscribers will receive published messages as long as they are subscribed and have the `subscribe` [capability](/docs/auth/capabilities) for that channel.

Publishing is an operation available to the realtime and REST interfaces of Pub/Sub SDKs. REST publishing is more efficient if you don't need to establish a persistent [connection](/docs/connect) to Ably, such as to subscribe to messages. For example, if you have a server publishing messages to channels that doesn't need to receive any updates from them.

## Publish a message

Use the [`publish()`](/docs/api/realtime-sdk/channels#publish) method to send messages to a channel.

<Code>
  ```realtime_javascript theme={null}
  const realtime = new Ably.Realtime('{{API_KEY}}');
  const channel = realtime.channels.get('my-channel');
  await channel.publish('event-name', 'message data');
  ```

  ```realtime_nodejs theme={null}
  const realtime = new Ably.Realtime('{{API_KEY}}');
  const channel = realtime.channels.get('my-channel');
  await channel.publish('event-name', 'message data');
  ```

  ```realtime_ruby theme={null}
  realtime = Ably::Realtime.new('{{API_KEY}}')
  channel = realtime.channels.get('my-channel')
  channel.publish 'event-name', 'message data'
  ```

  ```realtime_python theme={null}
  realtime = AblyRealtime('{{API_KEY}}')
  channel = realtime.channels.get('my-channel')
  await channel.publish('event-name', 'message data')
  ```

  ```realtime_java theme={null}
  AblyRealtime realtime = new AblyRealtime("{{API_KEY}}");
  Channel channel = realtime.channels.get("my-channel");
  channel.publish("event-name", "message data");
  ```

  ```realtime_csharp theme={null}
  AblyRealtime realtime = new AblyRealtime("{{API_KEY}}");
  IRealtimeChannel channel = realtime.Channels.Get("my-channel");
  channel.Publish("event-name", "message data");
  ```

  ```realtime_swift theme={null}
  let realtime = ARTRealtime(key: "{{API_KEY}}")
  let channel = realtime.channels.get("my-channel")
  channel.publish("event-name", data: "message data")
  ```

  ```realtime_go theme={null}
  realtime, err := ably.NewRealtime(
      ably.WithKey("{{API_KEY}}"))
  channel := realtime.Channels.Get("my-channel")
  channel.Publish(context.Background(), "event-name", "message data")
  ```

  ```rest_javascript theme={null}
  const rest = new Ably.Rest('{{API_KEY}}');
  const channel = rest.channels.get('my-channel');
  await channel.publish('event-name', 'message data');
  ```

  ```rest_nodejs theme={null}
  const rest = new Ably.Rest('{{API_KEY}}');
  const channel = rest.channels.get('my-channel');
  await channel.publish('event-name', 'message data');
  ```

  ```rest_python theme={null}
  rest = AblyRest('{{API_KEY}}')
  channel = rest.channels.get('my-channel')
  await channel.publish('event-name', 'message data')
  ```

  ```rest_java theme={null}
  AblyRest rest = new AblyRest("{{API_KEY}}");
  Channel channel = rest.channels.get("my-channel");
  channel.publish("event-name", "message data");
  ```
</Code>

## Message name and data

When publishing a message, you provide two key pieces of information:

* **name**: An event name that identifies the type of message. This is useful when you have different types of messages on the same channel.
* **data**: The message payload. This can be a string, JSON object, or binary data.

<Code>
  ```javascript theme={null}
  // Publish with name and data
  await channel.publish('temperature', { value: 25.5, unit: 'celsius' });

  // Publish with just data (name will be empty string)
  await channel.publish('message data');

  // Publish multiple messages in a single call
  await channel.publish([
    { name: 'temperature', data: { value: 25.5 } },
    { name: 'humidity', data: { value: 60 } }
  ]);
  ```
</Code>

## Publishing from REST

When you only need to publish messages and don't need to subscribe to them, use the REST interface. This is more efficient as it doesn't maintain a persistent connection:

<Code>
  ```javascript theme={null}
  const rest = new Ably.Rest('{{API_KEY}}');
  const channel = rest.channels.get('notifications');
  await channel.publish('alert', 'Server maintenance in 10 minutes');
  ```

  ```python theme={null}
  rest = AblyRest('{{API_KEY}}')
  channel = rest.channels.get('notifications')
  await channel.publish('alert', 'Server maintenance in 10 minutes')
  ```
</Code>

## Batch publishing

You can publish multiple messages in a single API call for better performance:

<Code>
  ```javascript theme={null}
  const messages = [
    { name: 'event1', data: 'data1' },
    { name: 'event2', data: 'data2' },
    { name: 'event3', data: 'data3' }
  ];

  await channel.publish(messages);
  ```

  ```python theme={null}
  messages = [
    { 'name': 'event1', 'data': 'data1' },
    { 'name': 'event2', 'data': 'data2' },
    { 'name': 'event3', 'data': 'data3' }
  ]

  await channel.publish(messages)
  ```
</Code>

## Publishing with extras

You can include additional metadata with your messages using the `extras` field:

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

## Message acknowledgment

When using the realtime interface, you can provide a callback to know when the message has been successfully published:

<Code>
  ```javascript theme={null}
  channel.publish('event', 'data', (err) => {
    if (err) {
      console.error('Failed to publish:', err);
    } else {
      console.log('Message published successfully');
    }
  });
  ```

  ```java theme={null}
  channel.publish("event", "data", new CompletionListener() {
      @Override
      public void onSuccess() {
          System.out.println("Message published successfully");
      }

      @Override
      public void onError(ErrorInfo errorInfo) {
          System.err.println("Failed to publish: " + errorInfo.message);
      }
  });
  ```
</Code>

## Publishing on behalf of others

Servers can publish messages on behalf of clients by specifying a `clientId` in the message:

<Code>
  ```javascript theme={null}
  const rest = new Ably.Rest({ key: '{{API_KEY}}' });
  const channel = rest.channels.get('chat');

  await channel.publish({
    name: 'message',
    data: 'Hello from user123',
    clientId: 'user123'
  });
  ```
</Code>

<Aside data-type="note">
  To publish on behalf of others, you must use basic authentication with an API key or a token with wildcard `clientId` (`*`).
</Aside>

## Next steps

* Learn how to [subscribe to messages](/docs/pubsub/channels/subscribe)
* Understand [message format](/docs/pubsub/messages/format) and metadata
* Explore [message history](/docs/pubsub/history)
