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

# Pub/Sub Quickstart

This quickstart guide will get you up and running with Ably Pub/Sub. You'll establish a realtime connection to Ably and learn to publish and subscribe to messages.

## Prerequisites

1. [Sign up](https://ably.com/signup) for an Ably account.
2. Create a [new app](https://ably.com/accounts/any/apps/new), and create your first API key in the **API Keys** tab of the dashboard.
3. Your API key will need the `publish` and `subscribe` capabilities.

## Step 1: Install the SDK

Install the Ably SDK for your platform:

<CodeGroup>
  ```javascript JavaScript theme={null}
  npm install ably
  ```

  ```python Python theme={null}
  pip install ably
  ```

  ```java Java theme={null}
  // Add to your pom.xml
  <dependency>
    <groupId>io.ably</groupId>
    <artifactId>ably-java</artifactId>
    <version>1.2.0</version>
  </dependency>
  ```

  ```ruby Ruby theme={null}
  gem install ably
  ```

  ```swift Swift theme={null}
  // Add to your Podfile
  pod 'Ably'
  ```

  ```go Go theme={null}
  go get github.com/ably/ably-go/ably
  ```
</CodeGroup>

## Step 2: Connect to Ably

Create a realtime client instance using your API key:

<CodeGroup>
  ```javascript JavaScript theme={null}
  import Ably from 'ably';

  const realtime = new Ably.Realtime('YOUR_API_KEY');

  await realtime.connection.once('connected');
  console.log('Connected to Ably!');
  ```

  ```python Python theme={null}
  from ably import AblyRealtime

  realtime = AblyRealtime('YOUR_API_KEY')
  await realtime.connection.once('connected')
  print('Connected to Ably!')
  ```

  ```java Java theme={null}
  import io.ably.lib.realtime.AblyRealtime;

  AblyRealtime realtime = new AblyRealtime("YOUR_API_KEY");
  realtime.connection.on(ConnectionState.connected, new ConnectionStateListener() {
      @Override
      public void onConnectionStateChanged(ConnectionStateChange state) {
          System.out.println("Connected to Ably!");
      }
  });
  ```

  ```ruby Ruby theme={null}
  require 'ably'

  realtime = Ably::Realtime.new('YOUR_API_KEY')
  realtime.connection.once(:connected) do
    puts 'Connected to Ably!'
  end
  ```

  ```swift Swift theme={null}
  import Ably

  let realtime = ARTRealtime(key: "YOUR_API_KEY")
  realtime.connection.on(.connected) { stateChange in
      print("Connected to Ably!")
  }
  ```

  ```go Go theme={null}
  import "github.com/ably/ably-go/ably"

  realtime, err := ably.NewRealtime(
      ably.WithKey("YOUR_API_KEY"))
  if err != nil {
      panic(err)
  }

  realtime.Connection.On(ably.ConnectionEventConnected, func(change ably.ConnectionStateChange) {
      fmt.Println("Connected to Ably!")
  })
  ```
</CodeGroup>

<Aside data-type="important">
  Never use API keys in client-side code. Use [token authentication](/docs/pubsub/auth/token) in production applications.
</Aside>

## Step 3: Get a channel

Channels are used to organize messages into different topics:

<CodeGroup>
  ```javascript JavaScript theme={null}
  const channel = realtime.channels.get('my-channel');
  ```

  ```python Python theme={null}
  channel = realtime.channels.get('my-channel')
  ```

  ```java Java theme={null}
  Channel channel = realtime.channels.get("my-channel");
  ```

  ```ruby Ruby theme={null}
  channel = realtime.channels.get('my-channel')
  ```

  ```swift Swift theme={null}
  let channel = realtime.channels.get("my-channel")
  ```

  ```go Go theme={null}
  channel := realtime.Channels.Get("my-channel")
  ```
</CodeGroup>

## Step 4: Subscribe to messages

Subscribe to receive messages published to the channel:

<CodeGroup>
  ```javascript JavaScript theme={null}
  await channel.subscribe((message) => {
    console.log('Received:', message.data);
  });
  ```

  ```python Python theme={null}
  def listener(message):
      print(f'Received: {message.data}')

  await channel.subscribe(listener)
  ```

  ```java Java theme={null}
  channel.subscribe(new MessageListener() {
      @Override
      public void onMessage(Message message) {
          System.out.println("Received: " + message.data);
      }
  });
  ```

  ```ruby Ruby theme={null}
  channel.subscribe do |message|
    puts "Received: #{message.data}"
  end
  ```

  ```swift Swift theme={null}
  channel.subscribe { message in
      print("Received: \(message.data)")
  }
  ```

  ```go Go theme={null}
  _, err = channel.SubscribeAll(context.Background(), func(msg *ably.Message) {
      fmt.Printf("Received: %v\n", msg.Data)
  })
  ```
</CodeGroup>

## Step 5: Publish a message

Publish a message to the channel:

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

  ```python Python theme={null}
  await channel.publish('greeting', 'Hello, World!')
  ```

  ```java Java theme={null}
  channel.publish("greeting", "Hello, World!");
  ```

  ```ruby Ruby theme={null}
  channel.publish('greeting', 'Hello, World!')
  ```

  ```swift Swift theme={null}
  channel.publish("greeting", data: "Hello, World!")
  ```

  ```go Go theme={null}
  err = channel.Publish(context.Background(), "greeting", "Hello, World!")
  ```
</CodeGroup>

## Complete example

Here's a complete working example:

<CodeGroup>
  ```javascript JavaScript theme={null}
  import Ably from 'ably';

  const realtime = new Ably.Realtime('YOUR_API_KEY');

  await realtime.connection.once('connected');
  console.log('Connected to Ably!');

  const channel = realtime.channels.get('my-channel');

  await channel.subscribe((message) => {
    console.log('Received:', message.data);
  });

  await channel.publish('greeting', 'Hello, World!');
  ```

  ```python Python theme={null}
  from ably import AblyRealtime

  realtime = AblyRealtime('YOUR_API_KEY')
  await realtime.connection.once('connected')
  print('Connected to Ably!')

  channel = realtime.channels.get('my-channel')

  def listener(message):
      print(f'Received: {message.data}')

  await channel.subscribe(listener)
  await channel.publish('greeting', 'Hello, World!')
  ```
</CodeGroup>

## Next steps

* Learn about [authentication](/docs/pubsub/auth/overview) to secure your applications
* Explore [channels](/docs/pubsub/channels/overview) to organize your messages
* Understand [message format](/docs/pubsub/messages/format) and metadata
* Try [presence](/docs/pubsub/presence) to track who's online
* Access [message history](/docs/pubsub/history) to retrieve past messages
