---
source_url: https://www.pubnub.com/docs/general/channels/overview
title: Channel Basics
updated_at: 2026-05-25T11:26:10.971Z
---

> Documentation Index
> For a curated overview of PubNub documentation, see: https://www.pubnub.com/docs/llms.txt
> For the full list of all documentation pages, see: https://www.pubnub.com/docs/llms-full.txt


# Channel Basics

A channel is a communication pathway for passing data between devices with PubNub.

Channels are hosted on PubNub. You interact with channels using PubNub [SDKs](https://www.pubnub.com/docs/sdks) (Software Development Kit, SDK) or the [REST API](https://www.pubnub.com/docs/sdks/rest-api) (Representational State Transfer, REST).

Pub/sub enables efficient, asynchronous message processing. Your app can deliver real-time updates while components work independently. For example, in chat, messaging, notifications, and analytics can each communicate through channels to keep the design modular and scalable.

:::tip We are fast
Devices listening on a channel typically receive messages in about **30 ms**, enabling swift global communication.
:::

###### Extend Pub/Sub with message types

The data you publish to channels takes the form of [messages](https://www.pubnub.com/docs/general/messages/overview) or signals. You can assign a [custom message type](https://www.pubnub.com/docs/general/messages/type) to each published payload to categorize, filter, and route messages without inspecting their content. This is useful for building apps that handle multiple content formats on the same channel.

###### Extend channel capabilities with platform features

Channels integrate with several platform features that add processing, management, and observability. [Functions](https://www.pubnub.com/docs/serverless/functions/overview) execute custom logic when messages are published to specific channels or wildcard patterns. [Events & Actions](https://www.pubnub.com/docs/serverless/events-and-actions/overview) let you configure listeners that react to channel-level events like publishes, subscribes, and metadata changes without writing code. [BizOps Workspace](https://www.pubnub.com/docs/bizops-workspace/channel-management) provides a UI for creating, updating, and deleting channel metadata and managing memberships. [Illuminate](https://www.pubnub.com/docs/illuminate/business-objects/basics) ingests message data from channels into Business Objects so you can build metrics scoped to specific channels or patterns. [Insights](https://www.pubnub.com/docs/pubnub-insights/dashboards/channels) reports per-channel analytics including message volume, subscriber counts, and usage trends.

## Channel creation

You don’t create channels in advance. PubNub creates a channel the first time you publish to it.

###### Enrich channels with persistent metadata

While channels are created implicitly on first publish, you can attach persistent metadata to any channel through [App Context](https://www.pubnub.com/docs/general/metadata/channel-metadata). Store a display name, description, type, status, and custom JSON attributes directly on the PubNub platform. When channel metadata changes, PubNub fires real-time events to subscribers so your UI stays current without polling. See [App Context configuration](https://www.pubnub.com/docs/general/metadata/basics#configuration) to enable channel metadata events on your keyset.

## Channel entity

PubNub SDKs provide local `Channel` entities to help you work with channels. These objects hide channel-management details and support clean patterns, such as decoupling app components for maintainability.

For more information, refer to [Entities](https://www.pubnub.com/docs/general/entities).

## Channel limits

There’s no limit on the number of channels or users per channel. A device can listen to thousands of channels over a single connection, which supports large-scale communication.

## Channel types

Channels represent places where messages are sent and received. Use direct channels for one-to-one private messaging and group channels for many-to-many conversations. Broadcast and unicast channels fit one‑to‑many and many‑to‑one use cases.

Here are some useful channel configurations:

**Direct channels** for one-to-one in-app messaging between two users. You can make these channels private to keep the messages secure between the users.

### JavaScript

```javascript
const PubNub = require('pubnub');

// Initialize the PubNub client with your publish and subscribe keys
const pubnub = new PubNub({
  publishKey: 'yourPublishKey',
  subscribeKey: 'yourSubscribeKey',
  userId: 'user1-unique-id', // Use unique user IDs for authentication
  authKey: 'user1AuthKey',   // Use an authentication key for security
  ssl: true                  // Enable SSL for secure communication
});

// Define the direct channel for one-to-one messaging between two specific users
const directChannel = 'direct.user1.user2'; // Example channel name

// Subscribe to the direct channel
const channel = pubnub.channel(directChannel);
const subscription = channel.subscription();

// Add event listeners for messages and presence
subscription.onMessage = (messageEvent) => {
  console.log('Received message:', messageEvent.message);
};

subscription.onPresence = (presenceEvent) => {
  console.log('Presence event:', presenceEvent);
};

// Subscribe to the channel
subscription.subscribe();

// Function to send a message to the direct channel
async function sendMessage(message) {
  return pubnub.publish({
    channel: directChannel,
    message: { text: message },
    meta: { sender: 'user1' },         // Add meta to store sender info
    storeInHistory: true,              // Store messages in history
    customMessageType: "text-message", // Label the message type
  });
}
// Example: sending a message
sendMessage('Hello, user2!')
  .then((result) => {
    console.log('Message sent successfully');
  })
  .catch((error) => {
    console.error('Error sending message:', error);
  }) ;
```

### Swift

```swift
import PubNub

// Initialize the PubNub client with your publish and subscribe keys
let config = PubNubConfiguration(
  publishKey: "yourPublishKey",
  subscribeKey: "yourSubscribeKey",
  userId: "user1-unique-id" // Unique ID for the user
)
let pubnub = PubNub(configuration: config)

// Define the direct channel for one-to-one messaging
let directChannel = "direct.user1.user2"

// Subscribe to the direct channel
let subscription = pubnub.channel(directChannel).subscription()

// Add event listeners for messages
subscription.onMessage = { message in
  print("Received message: \(message.payload)")
}

// Subscribe to the channel
subscription.subscribe()

// Function to send a message to the direct channel
func sendMessage(_ text: String) {
  pubnub.publish(
    channel: directChannel,
    message: ["text": text],
    customMessageType: "text-message"
  ) { result in
    switch result {
    case .success:
      print("Message sent successfully")
    case let .failure(error):
      print("Error sending message: \(error.localizedDescription)")
    }
  }
}

// Send a message to another user
sendMessage("Hello from user1!")
```

### Objective-C

```objectivec
#import <PubNub/PubNub.h>

@interface AppDelegate () <PNEventsListener>
@property (nonatomic, strong) PubNub *client;
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    PNConfiguration *configuration = [PNConfiguration configurationWithPublishKey:@"yourPublishKey" subscribeKey:@"yourSubscribeKey"];

    configuration.uuid = @"user1-unique-id"; // Unique ID for the user

    self.client = [PubNub clientWithConfiguration:configuration];
    [self.client addListener:self];

    // Define the direct channel for one-to-one messaging
    NSString *directChannel = @"direct.user1.user2";

    // Subscribe to the direct channel
    [self.client subscribeToChannels:@[directChannel] withPresence:NO];

    return YES;
}

- (void)client:(PubNub *)client didReceiveMessage:(PNMessageResult *)message {
    NSLog(@"Received message: %@ on channel %@", message.data.message, message.data.channel);
}

// Function to send a message to the direct channel
- (void)sendMessage:(NSString *)text {
    PNPublishRequest *request = [PNPublishRequest requestWithChannel:@"direct.user1.user2"];
    request.message = @{@"text": text};
    request.customMessageType = @"text-message";
    [self.client publishWithRequest:request completion:^(PNPublishStatus *status) {
        if (!status.isError) {
            NSLog(@"Message sent successfully");
        } else {
            NSLog(@"Error sending message: %@", status.errorData.information);
        }
    }];
}

@end
```

### Kotlin

```kotlin
import com.google.gson.JsonObject
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
import com.pubnub.api.models.consumer.pubsub.PNMessageResult
import com.pubnub.api.v2.PNConfiguration
import com.pubnub.api.v2.callbacks.EventListener

fun main() {
    val config = PNConfiguration.builder(UserId("user1-unique-id"), "yourSubscribeKey").apply {
        publishKey = "yourPublishKey"
    }
    val pubnub = PubNub.create(config.build())
    val directChannelName = "direct.user1.user2"

    // Create Subscription
    val channel = pubnub.channel(directChannelName)
    val subscription = channel.subscription()

    // Add Listeners
    subscription.addListener(object : EventListener {
        override fun message(pubnub: PubNub, result: PNMessageResult) {
            println("Received message: ${result.message.asJsonObject}")
        }
    })
    // Subscribe to the channel
    subscription.subscribe()
    // Function to send a message to the direct channel
    fun sendMessage(message: String) {
        val messageObject = JsonObject().apply {
            addProperty("text", message)
            addProperty("sender", "user1")
        }
        channel.publish(messageObject).async { result ->
            result.onFailure { exception ->
                println("Error sending message: ${exception.message}")
            }.onSuccess { value ->
                println("Message sent successfully with timetoken: ${value.timetoken}")
            }
        }
    }
    // Example: sending a message
    sendMessage("Hello, user2!")
}
```

### C#

```csharp
using PubnubApi;

class Program
{
    static void Main(string[] args)
    {
        PNConfiguration pnConfiguration = new PNConfiguration(new UserId("user1-unique-id"))
        {
            SubscribeKey = "yourSubscribeKey",
            PublishKey = "yourPublishKey"
        };
        Pubnub pubnub = new Pubnub(pnConfiguration);

        string directChannelName = "direct.user1.user2";
        Subscription subscription = pubnub.Channel(directChannelName).Subscription();

        subscription.AddListener(new SubscribeCallbackExt(
            (pn, messageEvent) =>
            {
                if (messageEvent != null)
                {
                    Console.WriteLine($"Received message: {messageEvent.Message}");
                }
            },
            (pn, presenceEvent) =>
            {
                if (presenceEvent != null)
                {
                    Console.WriteLine(
                        $"Presence event: {presenceEvent.Channel} {presenceEvent.Occupancy} {presenceEvent.Event}");
                }
            }
        ));

        subscription.Subscribe<object>();

        // Function to send a message to the direct channel
        void SendMessage(string message)
        {
            var userMessage = new Dictionary<string, string> { { "text", message }, { "sender", "user1" } };
            pubnub.Publish()
                .Channel(directChannelName)
                .Message(userMessage)
                .Execute(new PNPublishResultExt(
                    (result, status) =>
                    {
                        Console.WriteLine(!status.Error
                            ? $"Message sent, time-token: {result.Timetoken}"
                            : $"Error sending message: {status.ErrorData.Information}");
                    }
                ));
        }

        SendMessage("Hello, user2!");
    }
}
```

### Python

```python
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub
from pubnub.callbacks import SubscribeCallback

# Configuration setup
config = PNConfiguration()
config.subscribe_key = 'yourSubscribeKey'
config.publish_key = 'yourPublishKey'
config.user_id = 'user1-unique-id'
pubnub = PubNub(config)

# Listener Setup
class MySubscribeCallback(SubscribeCallback):
    def message(self, pubnub, message):
        print(f"Received message: {message.message}")

    def presence(self, pubnub, presence):
        print(f"Presence event: {presence.event}")

    def status(self, pubnub, status):
        print(f"Status: {status.category}")

pubnub.add_listener(MySubscribeCallback())

# Setup direct channel and subscribe
direct_channel = pubnub.channel("direct.user1.user2").subscription()
direct_channel.subscribe()

# Publish message to direct channel
def send_message(message):
    pubnub.publish().channel("direct.user1.user2").message({"text": message}).sync()

send_message("Hello, user2!")
```

**Group channels** serve as a collective category for many-to-many in-app messaging among multiple users, forming a community communication system, such as a chat room for friends or family.

#### JavaScript

```javascript
const PubNub = require('pubnub');

// Initialize the PubNub client with your publish and subscribe keys
const pubnub = new PubNub({
  publishKey: 'yourPublishKey',
  subscribeKey: 'yourSubscribeKey',
  userId: 'user1-unique-id', // Use unique user IDs for authentication
  authKey: 'user1AuthKey',   // Use an authentication key for security if necessary
  ssl: true                  // Enable SSL for secure communication
});

// Define the group channel for in-app messaging
const groupChannel = 'group.family'; // Example channel name for a family group

// Subscribe to the group channel
const channel = pubnub.channel(groupChannel);
const subscription = channel.subscription();

// Add event listeners for messages and presence
subscription.onMessage = (messageEvent) => {
  console.log('Received message:', messageEvent.message);
};

subscription.onPresence = (presenceEvent) => {
  console.log('Presence event:', presenceEvent);
};

// Subscribe to the channel
subscription.subscribe();

// Function to send a message to the group channel
async function sendMessage(message) {
  try {
    await pubnub.publish({
      channel: groupChannel,
      message: { text: message },
      meta: { sender: 'user1' },     // Add meta to store sender info
      storeInHistory: true,          // Store messages in history
      customMessageType: "text-message", // Label the message type
    });
    console.log('Message sent successfully');
  } catch (error) {
    console.error('Error sending message:', error);
  }
}

// Example: sending a message
sendMessage('Hello, family group!');

// Optional: manage access (only required if making the group private)
function manageAccess() {
  pubnub.grant({
    channels: [groupChannel],
    authKeys: ['user1AuthKey', 'user2AuthKey', 'user3AuthKey'], // Auth keys for allowed users
    read: true,
    write: true,
    ttl: 60          // Time-to-live for the grant in minutes
  }, (status) => {
    if (status.error) {
      console.error('Error managing access:', status);
    } else {
      console.log('Access managed successfully');
    }
  });
}

// Call this function if you want to restrict the channel to certain users
manageAccess();
```

#### Swift

```swift
import PubNub

// Initialize the PubNub client with your publish and subscribe keys
let config = PubNubConfiguration(
  publishKey: "yourPublishKey",
  subscribeKey: "yourSubscribeKey",
  userId: "user1-unique-id" // Unique ID for the user
)
let pubnub = PubNub(configuration: config)

// Define the group channel for many-to-many messaging
let groupChannel = "group.family"

// Subscribe to the group channel
let subscription = pubnub.channel(groupChannel).subscription()

// Add event listeners for messages
subscription.onMessage = { message in
  print("Received message: \(message.payload)")
}

// Subscribe to the channel
subscription.subscribe()

// Function to send a message to the group channel
func sendMessage(_ text: String) {
  pubnub.publish(
    channel: groupChannel,
    message: ["text": text],
    customMessageType: "text-message"
  ) { result in
    switch result {
    case .success:
      print("Message sent successfully")
    case let .failure(error):
      print("Error sending message: \(error.localizedDescription)")
    }
  }
}

// Send a message to the group
sendMessage("Hello family group!")
```

#### Objective-C

```objectivec
#import <PubNub/PubNub.h>

@interface AppDelegate () <PNEventsListener>
@property (nonatomic, strong) PubNub *client;
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    PNConfiguration *configuration = [PNConfiguration configurationWithPublishKey:@"yourPublishKey" subscribeKey:@"yourSubscribeKey"];

    configuration.uuid = @"user1-unique-id"; // Unique ID for the user

    self.client = [PubNub clientWithConfiguration:configuration];
    [self.client addListener:self];

    // Define the group channel for many-to-many messaging
    NSString *groupChannel = @"group.family";

    // Subscribe to the group channel
    [self.client subscribeToChannels:@[groupChannel] withPresence:YES];

    return YES;
}

- (void)client:(PubNub *)client didReceiveMessage:(PNMessageResult *)message {
    NSLog(@"Received message: %@ on channel %@", message.data.message, message.data.channel);
}

// Function to send a message to the group channel
- (void)sendMessage:(NSString *)text {
    [self.client publish:@{@"text": text} toChannel:@"group.family"
               withCompletion:^(PNPublishStatus *status) {
        if (!status.isError) {
            NSLog(@"Message sent successfully");
        } else {
            NSLog(@"Error sending message: %@", status.errorData.information);
        }
    }];
}

@end
```

#### Kotlin

```kotlin
import com.google.gson.JsonObject
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
import com.pubnub.api.models.consumer.pubsub.PNMessageResult
import com.pubnub.api.v2.PNConfiguration
import com.pubnub.api.v2.callbacks.EventListener

fun main() {
    val config = PNConfiguration.builder(UserId("user1-unique-id"), "yourSubscribeKey").apply {
        publishKey = "yourPublishKey"
    }
    val pubnub = PubNub.create(config.build())
    val groupChannelName = "group.family"
    // Create Subscription
    val channel = pubnub.channel(groupChannelName)
    val subscription = channel.subscription()
    // Add Listeners
    subscription.addListener(object : EventListener {
        override fun message(pubnub: PubNub, result: PNMessageResult) {
            println("Received message: ${result.message.asJsonObject}")
        }
    })
    // Subscribe to the channel
    subscription.subscribe()
    // Function to send a message to the group channel
    fun sendMessage(message: String) {
        val messageObject = JsonObject().apply {
            addProperty("text", message)
            addProperty("sender", "user1")
        }
        channel.publish(messageObject).async { result ->
            result.onFailure { exception ->
                println("Error sending message: ${exception.message}")
            }.onSuccess { value ->
                println("Message sent successfully with timetoken: ${value.timetoken}")
            }
        }
    }
    // Example: sending a message
    sendMessage("Hello, family group!")
}
```

#### C#

```csharp
using PubnubApi;
using System;
using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        PNConfiguration pnConfiguration = new PNConfiguration(new UserId("user1-unique-id"));
        pnConfiguration.SubscribeKey = "yourSubscribeKey";
        pnConfiguration.PublishKey = "yourPublishKey";
        Pubnub pubnub = new Pubnub(pnConfiguration);

        string groupChannelName = "group.family";
        Subscription subscription = pubnub.Channel(groupChannelName).Subscription();

        subscription.AddListener(new SubscribeCallbackExt(
            (pnObj, pubMsg) => {
                if (pubMsg != null)
                {
                    Console.WriteLine("Received message: " + pubMsg.Message);
                }
            },
            (pnObj, presenceEvnt) => {
                if (presenceEvnt != null)
                {
                    Console.WriteLine($"Presence event: {presenceEvnt.Channel} {presenceEvnt.Occupancy} {presenceEvnt.Event}");
                }
            }
        ));

        subscription.Subscribe<object>();

        // Function to send a message to the group channel
        void SendMessage(string message)
        {
            var msg = new Dictionary<string, string> { { "text", message }, { "sender", "user1" } };
            pubnub.Publish()
                  .Channel(groupChannelName)
                  .Message(msg)
                  .Execute(new PNPublishResultExt(
                      (result, status) => {
                          if (!status.Error)
                          {
                              Console.WriteLine(string.Format("Message sent, timetoken: {0}", result.Timetoken));
                          }
                          else
                          {
                              Console.WriteLine("Error sending message: " + status.ErrorData.Information);
                          }
                      }
                  ));
        }

        SendMessage("Hello, family group!");
    }
}
```

#### Python

```python
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub
from pubnub.callbacks import SubscribeCallback

# Configuration setup
config = PNConfiguration()
config.subscribe_key = 'yourSubscribeKey'
config.publish_key = 'yourPublishKey'
config.user_id = 'user1-unique-id'
pubnub = PubNub(config)

# Listener Setup
class MySubscribeCallback(SubscribeCallback):
    def message(self, pubnub, message):
        print(f"Received message: {message.message}")

    def presence(self, pubnub, presence):
        print(f"Presence event: {presence.event}")

    def status(self, pubnub, status):
        print(f"Status: {status.category}")

pubnub.add_listener(MySubscribeCallback())

# Setup group channel and subscribe
group_channel = pubnub.channel("group.family").subscription()
group_channel.subscribe()

# Publish message to group channel
def send_message(message):
    pubnub.publish().channel("group.family").message({"text": message}).sync()

send_message("Hello, family group!")
```

**Broadcast channels** for announcements, polls, and other situations in which you want to broadcast messages in a one-to-many arrangement.

##### JavaScript

```javascript
const PubNub = require('pubnub');

// Initialize the PubNub client with your publish and subscribe keys
const pubnub = new PubNub({
  publishKey: 'yourPublishKey',
  subscribeKey: 'yourSubscribeKey',
  userId: 'broadcaster-unique-id', // Use a unique ID for the broadcaster
  ssl: true                        // Enable SSL for secure communication
});

// Define the broadcast channel for one-to-many communication
const broadcastChannel = 'broadcast.announcements'; // Example channel for announcements

// Subscribe to the broadcast channel
const channel = pubnub.channel(broadcastChannel);
const subscription = channel.subscription();

// Add an event listener for messages
subscription.onMessage = (messageEvent) => {
  console.log('Received broadcast message:', messageEvent.message);
};

// Subscribe to the channel
subscription.subscribe();

// Function to send a broadcast message to the broadcast channel
async function sendBroadcastMessage(message) {
  try {
    await pubnub.publish({
      channel: broadcastChannel,
      message: { text: message },
      storeInHistory: false,            // Typically, broadcasts do not need to be stored
      customMessageType: "broadcast",   // Label the message as a broadcast
    });
    console.log('Broadcast message sent successfully');
  } catch (error) {
    console.error('Error sending broadcast message:', error);
  }
}

// Example: sending a broadcast message
sendBroadcastMessage('Attention all users, system maintenance at midnight!');

// Function to configure broadcast settings
function configureBroadcastChannel() {
  // You might implement additional logic here to ensure only certain clients can publish to the channel
  // This could involve permissions management if implemented server-side
}

// Optionally call this function to manage and configure channel access and settings
configureBroadcastChannel();
```

##### Swift

```swift
import PubNub

// Initialize the PubNub client with your publish and subscribe keys
let config = PubNubConfiguration(
  publishKey: "yourPublishKey",
  subscribeKey: "yourSubscribeKey",
  userId: "broadcaster-unique-id" // Unique ID for the broadcaster
)
let pubnub = PubNub(configuration: config)

// Define the broadcast channel for one-to-many communication
let broadcastChannel = "broadcast.announcements"

// Subscribe to the broadcast channel
let subscription = pubnub.channel(broadcastChannel).subscription()

// Add event listeners for messages
subscription.onMessage = { message in
  print("Received broadcast message: \(message.message)")
}

// Subscribe to the channel
subscription.subscribe()

// Function to send a broadcast message
func sendBroadcastMessage(_ text: String) {
  pubnub.publish(
    channel: broadcastChannel,
    message: ["text": text],
    customMessageType: "broadcast"
  ) { result in
    switch result {
    case .success:
      print("Broadcast message sent successfully")
    case let .failure(error):
      print("Error sending broadcast message: \(error.localizedDescription)")
    }
  }
}

// Send a broadcast message
sendBroadcastMessage("System maintenance at midnight!")
```

##### Objective-C

```objectivec
#import <PubNub/PubNub.h>

@interface AppDelegate () <PNEventsListener>
@property (nonatomic, strong) PubNub *client;
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    PNConfiguration *configuration = [PNConfiguration configurationWithPublishKey:@"yourPublishKey" subscribeKey:@"yourSubscribeKey"];

    configuration.uuid = @"broadcaster-unique-id"; // Unique ID for the broadcaster

    self.client = [PubNub clientWithConfiguration:configuration];
    [self.client addListener:self];

    // Define the broadcast channel for one-to-many communication
    NSString *broadcastChannel = @"broadcast.announcements";

    // Subscribe to the broadcast channel
    [self.client subscribeToChannels:@[broadcastChannel] withPresence:NO];

    return YES;
}

- (void)client:(PubNub *)client didReceiveMessage:(PNMessageResult *)message {
    NSLog(@"Received broadcast message: %@ on channel %@", message.data.message, message.data.channel);
}

// Function to send a broadcast message
- (void)sendBroadcastMessage:(NSString *)text {
    [self.client publish:@{@"text": text} toChannel:@"broadcast.announcements"
               withCompletion:^(PNPublishStatus *status) {
        if (!status.isError) {
            NSLog(@"Broadcast message sent successfully");
        } else {
            NSLog(@"Error sending broadcast message: %@", status.errorData.information);
        }
    }];
}

@end
```

##### Kotlin

```kotlin
import com.google.gson.JsonObject
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
import com.pubnub.api.models.consumer.pubsub.PNMessageResult
import com.pubnub.api.v2.PNConfiguration
import com.pubnub.api.v2.callbacks.EventListener

fun main() {
    val config = PNConfiguration.builder(UserId("broadcaster-unique-id"), "yourSubscribeKey").apply {
        publishKey = "yourPublishKey"
    }
    val pubnub = PubNub.create(config.build())
    val broadcastChannelName = "broadcast.announcements"
    // Create Subscription
    val channel = pubnub.channel(broadcastChannelName)
    val subscription = channel.subscription()
    // Add Listener for messages (subscribers)
    subscription.addListener(object : EventListener {
        override fun message(pubnub: PubNub, result: PNMessageResult) {
            println("Received broadcast message: ${result.message.asJsonObject}")
        }
    })
    // Subscribe to the channel
    subscription.subscribe()
    // Function to send a broadcast message
    fun sendBroadcastMessage(message: String) {
        val messageObject = JsonObject().apply {
            addProperty("text", message)
        }
        channel.publish(messageObject, shouldStore = false).async { result ->
            result.onFailure { exception ->
                println("Error sending broadcast message: ${exception.message}")
            }.onSuccess { value ->
                println("Broadcast message sent successfully with timetoken: ${value.timetoken}")
            }
        }
    }
    // Example: sending a broadcast message
    sendBroadcastMessage("Attention all users, system maintenance at midnight!")
}
```

##### C#

```csharp
using PubnubApi;
using System;
using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        PNConfiguration pnConfiguration = new PNConfiguration(new UserId("broadcaster-unique-id"));
        pnConfiguration.SubscribeKey = "yourSubscribeKey";
        pnConfiguration.PublishKey = "yourPublishKey";
        Pubnub pubnub = new Pubnub(pnConfiguration);

        string broadcastChannelName = "broadcast.announcements";
        Subscription subscription = pubnub.Channel(broadcastChannelName).Subscription();

        subscription.AddListener(new SubscribeCallbackExt(
            (pnObj, pubMsg) => {
                if (pubMsg != null)
                {
                    Console.WriteLine("Received broadcast message: " + pubMsg.Message);
                }
            },
            (pnObj, presenceEvnt) => {
                if (presenceEvnt != null)
                {
                    Console.WriteLine($"Presence event: {presenceEvnt.Channel} {presenceEvnt.Occupancy} {presenceEvnt.Event}");
                }
            }
        ));

        subscription.Subscribe<object>();

        // Function to send a broadcast message
        void SendBroadcastMessage(string message)
        {
            var msg = new Dictionary<string, string> { { "text", message } };
            pubnub.Publish()
                  .Channel(broadcastChannelName)
                  .Message(msg)
                  .ShouldStore(false) // Typically, broadcasts do not need to be stored
                  .Execute(new PNPublishResultExt(
                      (result, status) => {
                          if (!status.Error)
                          {
                              Console.WriteLine(string.Format("Broadcast message sent, timetoken: {0}", result.Timetoken));
                          }
                          else
                          {
                              Console.WriteLine("Error sending broadcast message: " + status.ErrorData.Information);
                          }
                      }
                  ));
        }

        SendBroadcastMessage("Attention all users, system maintenance at midnight!");
    }
}
```

##### Python

```python
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub
from pubnub.callbacks import SubscribeCallback

# Configuration setup
config = PNConfiguration()
config.subscribe_key = 'yourSubscribeKey'
config.publish_key = 'yourPublishKey'
config.user_id = 'broadcaster-unique-id'
pubnub = PubNub(config)

# Listener Setup
class BroadcastSubscribeCallback(SubscribeCallback):
    def message(self, pubnub, message):
        print(f"Received broadcast message: {message.message}")

    def presence(self, pubnub, presence):
        print(f"Presence event: {presence.event}")

    def status(self, pubnub, status):
        print(f"Status: {status.category}")

pubnub.add_listener(BroadcastSubscribeCallback())

# Setup broadcast channel and subscribe
broadcast_channel = pubnub.channel("broadcast.announcements").subscription()
broadcast_channel.subscribe()

# Publish message to broadcast channel
def send_broadcast_message(message):
    pubnub.publish().channel("broadcast.announcements").message({"text": message}).should_store(False).sync()

send_broadcast_message("Attention all users, system maintenance at midnight!")
```

**Unicast channels** for poll responses, sensor inputs, location data, and other situations in which you want to *aggregate* messages in a many-to-one arrangement.

###### JavaScript

```javascript
const PubNub = require('pubnub');

// Initialize the PubNub client with your publish and subscribe keys
const pubnub = new PubNub({
  publishKey: 'yourPublishKey',
  subscribeKey: 'yourSubscribeKey',
  userId: 'listener-unique-id', // Unique ID for the device/server listening for inputs
  ssl: true                      // Enable SSL for secure communication
});

// Define the unicast channel for aggregating messages
const unicastChannel = 'unicast.dataCollector'; // Example channel for aggregating data

// Subscribe to the unicast channel
const channel = pubnub.channel(unicastChannel);
const subscription = channel.subscription();

// Add an event listener for messages
subscription.onMessage = (messageEvent) => {
  console.log('Received message:', messageEvent.message);
  // Process the incoming data
  processIncomingData(messageEvent.message);
};

// Subscribe to the channel
subscription.subscribe();

// The function for processing incoming data
function processIncomingData(data) {
  // Implement your data processing logic here
  console.log('Processing data:', data);
}

// Function for sending data to the unicast channel from different devices
async function sendData(deviceId, data) {
  try {
    await pubnub.publish({
      channel: unicastChannel,
      message: { deviceId: deviceId, data: data },
      storeInHistory: true,  // Optional: store data for historical analysis
      customMessageType: "sensor-data", // Label the message type
    });
    console.log('Data sent successfully from device:', deviceId);
  } catch (error) {
    console.error('Error sending data from device:', deviceId, error);
  }
}

// Example: devices sending data to the unicast channel
sendData('device1', { temperature: 22.5, humidity: 45 });
sendData('device2', { location: { lat: 37.7749, lon: -122.4194 } });

// Optionally, function for configuring access if needed
function configureUnicastChannel() {
  // You can manage which users or devices are allowed to publish to the channel
  // This can involve permissions management if implemented server-side
}

// Optionally call this function to set up access and permissions
configureUnicastChannel();
```

###### Swift

```swift
import PubNub

// Initialize the PubNub client with your publish and subscribe keys
let config = PubNubConfiguration(
  publishKey: "yourPublishKey",
  subscribeKey: "yourSubscribeKey",
  userId: "listener-unique-id" // Unique ID for the listener
)
let pubnub = PubNub(configuration: config)

// Define the unicast channel for aggregating messages
let unicastChannel = "unicast.dataCollector"

// Subscribe to the unicast channel
let subscription = pubnub.channel(unicastChannel).subscription()

// Add event listeners for messages
subscription.onMessage = { message in
  print("Received data message: \(message.message)")
}

// Subscribe to the channel
subscription.subscribe()

// Function to send data from a device
func sendData(deviceId: String, data: [String: Any]) {
  pubnub.publish(
    channel: unicastChannel,
    message: ["deviceId": deviceId, "data": data],
    customMessageType: "sensor-data"
  ) { result in
    switch result {
    case .success:
      print("Data sent from device \(deviceId) successfully")
    case let .failure(error):
      print("Error sending data from device \(deviceId): \(error.localizedDescription)")
    }
  }
}

// Send data from multiple devices
sendData(deviceId: "device1", data: ["temperature": 22.5, "humidity": 45])
sendData(deviceId: "device2", data: ["location": ["lat": 37.7749, "lon": -122.4194]])
```

###### Objective-C

```objectivec
#import <PubNub/PubNub.h>

@interface AppDelegate () <PNEventsListener>
@property (nonatomic, strong) PubNub *client;
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    PNConfiguration *configuration = [PNConfiguration configurationWithPublishKey:@"yourPublishKey" subscribeKey:@"yourSubscribeKey"];

    configuration.uuid = @"listener-unique-id"; // Unique ID for the listener

    self.client = [PubNub clientWithConfiguration:configuration];
    [self.client addListener:self];

    // Define the unicast channel for aggregating messages
    NSString *unicastChannel = @"unicast.dataCollector";

    // Subscribe to the unicast channel
    [self.client subscribeToChannels:@[unicastChannel] withPresence:NO];

    return YES;
}

- (void)client:(PubNub *)client didReceiveMessage:(PNMessageResult *)message {
    NSLog(@"Received data message: %@ on channel %@", message.data.message, message.data.channel);
}

// Function to send data from a device
- (void)sendDataFromDevice:(NSString *)deviceId data:(NSDictionary *)data {
    [self.client publish:@{@"deviceId": deviceId, @"data": data} toChannel:@"unicast.dataCollector"
               withCompletion:^(PNPublishStatus *status) {
        if (!status.isError) {
            NSLog(@"Data sent from device %@ successfully", deviceId);
        } else {
            NSLog(@"Error sending data from device %@: %@", deviceId, status.errorData.information);
        }
    }];
}

@end
```

###### Kotlin

```kotlin
import com.google.gson.JsonObject
import com.pubnub.api.PubNub
import com.pubnub.api.UserId
import com.pubnub.api.models.consumer.pubsub.PNMessageResult
import com.pubnub.api.v2.PNConfiguration
import com.pubnub.api.v2.callbacks.EventListener

fun main() {
    val config = PNConfiguration.builder(UserId("listener-unique-id"), "yourSubscribeKey").apply {
        publishKey = "yourPublishKey"
    }
    val pubnub = PubNub.create(config.build())
    val unicastChannelName = "unicast.dataCollector"
    // Create Subscription
    val channel = pubnub.channel(unicastChannelName)
    val subscription = channel.subscription()
    // Add Listener for messages
    subscription.addListener(object : EventListener {
        override fun message(pubnub: PubNub, result: PNMessageResult) {
            println("Received data: ${result.message.asJsonObject}")
            processIncomingData(result.message.asJsonObject)
        }
    })
    // Subscribe to the channel
    subscription.subscribe()
    // Process incoming data

    // Function to send data from a device
    fun sendData(deviceId: String, data: JsonObject) {
        channel.publish(data).async { result ->
            result.onFailure { exception ->
                println("Error sending data from device $deviceId: ${exception.message}")
            }.onSuccess { value ->
                println("Data sent successfully from device $deviceId with timetoken: ${value.timetoken}")
            }
        }
    }
    // Example: devices sending data
    val data1 = JsonObject().apply {
        addProperty("temperature", 22.5)
        addProperty("humidity", 45)
    }
    sendData("device1", data1)

    // simulate pause between two device sending data
    Thread.sleep(100)    

    val data2 = JsonObject().apply {
        addProperty("lat", 37.7749)
        addProperty("lon", -122.4194)
    }
    sendData("device2", data2)
}

fun processIncomingData(data: JsonObject) {
    println("Processing data: $data")
    // Your data processing logic here
}
```

###### C#

```csharp
using PubnubApi;
using System;
using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        PNConfiguration pnConfiguration = new PNConfiguration(new UserId("listener-unique-id"));
        pnConfiguration.SubscribeKey = "yourSubscribeKey";
        pnConfiguration.PublishKey = "yourPublishKey";
        Pubnub pubnub = new Pubnub(pnConfiguration);

        string unicastChannelName = "unicast.dataCollector";
        Subscription subscription = pubnub.Channel(unicastChannelName).Subscription();

        subscription.AddListener(new SubscribeCallbackExt(
            (pnObj, pubMsg) => {
                if (pubMsg != null)
                {
                    Console.WriteLine("Received data: " + pubMsg.Message);
                    ProcessIncomingData(pubMsg.Message);
                }
            },
            (pnObj, presenceEvnt) => {
                if (presenceEvnt != null)
                {
                    Console.WriteLine($"Presence event: {presenceEvnt.Channel} {presenceEvnt.Occupancy} {presenceEvnt.Event}");
                }
            }
        ));

        subscription.Subscribe<object>();

        // Method to process incoming data
        void ProcessIncomingData(object data)
        {
            Console.WriteLine("Processing data: " + data);
            // Implement your data processing logic here
        }

        // Function to send data from devices
        void SendData(string deviceId, Dictionary<string, object> data)
        {
            pubnub.Publish()
                  .Channel(unicastChannelName)
                  .Message(new Dictionary<string, object> { { "deviceId", deviceId }, { "data", data } })
                  .Execute(new PNPublishResultExt(
                      (result, status) => {
                          if (!status.Error)
                          {
                              Console.WriteLine(string.Format("Data sent from device {0}, timetoken: {1}", deviceId, result.Timetoken));
                          }
                          else
                          {
                              Console.WriteLine(string.Format("Error sending data from device {0}: {1}", deviceId, status.ErrorData.Information));
                          }
                      }
                  ));
        }

        // Example: devices sending data
        SendData("device1", new Dictionary<string, object> { { "temperature", 22.5 }, { "humidity", 45 } });
        SendData("device2", new Dictionary<string, object> { { "lat", 37.7749 }, { "lon", -122.4194 } });
    }
}
```

###### Python

```python
from pubnub.pnconfiguration import PNConfiguration
from pubnub.pubnub import PubNub
from pubnub.callbacks import SubscribeCallback

# Configuration setup
config = PNConfiguration()
config.subscribe_key = 'yourSubscribeKey'
config.publish_key = 'yourPublishKey'
config.user_id = 'listener-unique-id'
pubnub = PubNub(config)

# Listener Setup
class UnicastSubscribeCallback(SubscribeCallback):
    def message(self, pubnub, message):
        print(f"Received data: {message.message}")
        process_incoming_data(message.message)

    def presence(self, pubnub, presence):
        print(f"Presence event: {presence.event}")

    def status(self, pubnub, status):
        print(f"Status: {status.category}")

pubnub.add_listener(UnicastSubscribeCallback())

# Setup unicast channel and subscribe
unicast_channel = pubnub.channel("unicast.dataCollector").subscription()
unicast_channel.subscribe()

# Function to process incoming data
def process_incoming_data(data):
    print(f"Processing data: {data}")

# Publish sensor data to unicast channel
def send_data(device_id, data):
    pubnub.publish().channel("unicast.dataCollector").message({"deviceId": device_id, "data": data}).sync()

# Example: devices sending data
send_data("device1", {"temperature": 22.5, "humidity": 45})
send_data("device2", {"lat": 37.7749, "lon": -122.4194})
```

[Channel groups](https://www.pubnub.com/docs/general/channels/subscribe#channel-groups) allow you to bundle thousands of channels into a group that can be identified by name. When you subscribe to a channel group, you receive data from all the channels the channel group contains.

## Channel names

A channel name can be any alphanumeric string up to 92 UTF‑8 characters. Channel names are unique per PubNub key set. You can reuse the same name in a different key set, even within the same account. A key set is the namespace for your channels.

### Invalid characters

`, : * / \` and Unicode Null, whitespace, and non‑printable ASCII characters.

### Valid characters

`_ - = @ . ! $ # % & ^ ;`

**A period (.) is valid.** It is also a special character for wildcard features. Use it strategically to enable wildcard channel subscribe and Function wildcard channel binding.

### Channel name validator

Check if your channel name is valid using the channel name validator.

Channel name

### Naming conventions

When it comes to naming your channels, we recommend that you provide a prefix that identifies the purpose of the channel or the types of messages that will be sent over those types of channels.

Following that prefix with a `.` character further enhances the usefulness of the channel name concerning the wildcard features with several PubNub features, like wildcard subscribe, wildcard channel function binding, and advanced Presence configuration.

For further details on channel naming recommendations, refer to [Channel Naming Conventions](https://www.pubnub.com/docs/general/channels/channel-naming).

## Securing channels

Secure channels by controlling access with PubNub’s [Access Manager](https://www.pubnub.com/docs/general/security/access-control).

While you are learning PubNub, you can keep Access Manager disabled so any client can send and receive on any channel. For production, enable access control to protect your channels.

For app‑wide protection, see [Access Control in the Security section](https://www.pubnub.com/docs/general/security/access-control).

###### Add presence tracking and access control to channels

Every channel automatically supports [presence](https://www.pubnub.com/docs/general/presence/overview) tracking. PubNub creates a companion `-pnpres` channel for each channel that delivers real-time join, leave, and timeout events to subscribers. Use [Here Now](https://www.pubnub.com/docs/general/presence/overview#get-online-users-in-channel) to query current occupancy and [Presence Events](https://www.pubnub.com/docs/general/presence/presence-events) to keep your UI in sync. To restrict who can publish, subscribe, or query presence on a channel, grant scoped permissions with [Access Manager](https://www.pubnub.com/docs/general/security/access-control). You can target individual channels or apply pattern-based grants across channels that share a [naming convention](https://www.pubnub.com/docs/general/channels/channel-naming#naming-consistency).

## Terms in this document

* **Channel** - A pathway for sending and receiving messages between devices, created automatically when you first use it, that can handle any number of users and messages for different communication needs, like 1-1 text chats, group conversations, and other data streaming.
* **Channel pattern** - A way to group and analyze channel data to track performance metrics like message counts and user engagement over time with PubNub Insights.
