On this page

Channel Groups API for C SDK

Channel groups allow PubNub developers to bundle thousands of channels into a group that can be identified by a name. These channel groups can then be subscribed to, receiving data from the many back-end channels the channel group contains.

Channel group operations

You can't publish to a channel group. You can only subscribe to it. To publish within the channel group, you need to publish to each channel individually.

This page covers the four channel-group operations: add channels to a group, remove channels from a group, list the channels in a group, and delete a group entirely. All four are declared in #include <pubnub/features/channel_groups.h> and gated by PUBNUB_ENABLE_CHANNEL_GROUPS. This flag is ON in the full CMake profile but OFF in minimal and embedded. A build using either of those must turn it on explicitly with -DPUBNUB_ENABLE_CHANNEL_GROUPS=ON. See Feature flags for the full flag matrix.

To receive messages published on the channels inside a group, subscribe to the group as an entity with pubnub_channel_group(). See Entities in Publish & Subscribe. This page covers only the group's membership CRUD operations, not subscribing to it.

Multiple channels are a single comma-separated string

Every function on this page that accepts more than one channel takes them as one comma-separated const char*, for example "ch1,ch2,ch3", never an array. There is no array-based overload. Build the comma-separated string yourself before populating an options struct.

Add channels to a channel group

pubnub_channel_group_add_channels() adds one or more channels to a channel group. Creating a channel group happens implicitly the first time a channel is added to a group name that does not yet exist.

Method(s)

pubnub_future_t pubnub_channel_group_add_channels(pubnub_context_t* ctx, const pubnub_channel_group_add_opts_t* opts);
* required
ParameterDescription
channel_group *
Type: const char*
Default:
Borrowed, NUL-terminated. Target channel group name.
channels *
Type: const char*
Default:
Borrowed, NUL-terminated. Comma-separated channel names to add, for example "ch1,ch2,ch3". Not an array.
timeout_ms
Type: uint32_t
Default:
0 (inherits pubnub_config_t::transaction_timeout_ms)
A non-zero value overrides the context-level timeout for this call only.

Zero-initialize with PUBNUB_CHANNEL_GROUP_ADD_OPTS_INIT (expands to {0}) so every unspecified field takes its protocol-safe default.

C-family contract

  • Header#include <pubnub/features/channel_groups.h>
  • Typespubnub_channel_group_add_opts_t
  • Prerequisite — an initialized context with subscribe_key and user_id set. Every shipped example configures only those two keys for channel-group calls; publish_key is not needed.
  • Feature flagPUBNUB_ENABLE_CHANNEL_GROUPS
  • Ownership / lifetimechannel_group and channels are borrowed, NUL-terminated strings; the SDK does not copy or retain them past the call
  • Blocking — never blocks; returns a pubnub_future_t immediately

Sample code

#include <pubnub/client.h>
#include <pubnub/features/channel_groups.h>
#include <pubnub/future.h>

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
pubnub_config_t cfg = pubnub_config_defaults();
cfg.subscribe_key = "demo";
cfg.user_id = "my_unique_user_id";

pubnub_context_t* ctx = pubnub_create(&cfg);
if (NULL == ctx) {
show all 39 lines

This sample is adapted from examples/channel_groups/add_channels.c (cooperative polling).

Returns

pubnub_channel_group_add_channels() returns a pubnub_future_t. On success, the future's status is PUBNUB_OK with no additional payload. There is no dedicated result-accessor function for this operation. Check the status only.

Remove channels from a channel group

pubnub_channel_group_remove_channels() removes one or more channels from a channel group. The group itself is not deleted, even if this call removes its last remaining channel. Use Delete a channel group to remove the group.

Method(s)

pubnub_future_t pubnub_channel_group_remove_channels(pubnub_context_t* ctx, const pubnub_channel_group_remove_opts_t* opts);
* required
ParameterDescription
channel_group *
Type: const char*
Default:
Borrowed, NUL-terminated. Target channel group name.
channels *
Type: const char*
Default:
Borrowed, NUL-terminated. Comma-separated channel names to remove, for example "ch1,ch2". Not an array.
timeout_ms
Type: uint32_t
Default:
0 (inherits pubnub_config_t::transaction_timeout_ms)
A non-zero value overrides the context-level timeout for this call only.

Zero-initialize with PUBNUB_CHANNEL_GROUP_REMOVE_OPTS_INIT (expands to {0}).

C-family contract

  • Header#include <pubnub/features/channel_groups.h>
  • Typespubnub_channel_group_remove_opts_t
  • Prerequisite — an initialized context with subscribe_key and user_id set; see Add channels
  • Feature flagPUBNUB_ENABLE_CHANNEL_GROUPS
  • Ownership / lifetimechannel_group and channels are borrowed, NUL-terminated strings
  • Blocking — never blocks; returns a pubnub_future_t immediately

Sample code

#include <pubnub/client.h>
#include <pubnub/features/channel_groups.h>
#include <pubnub/future.h>

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
pubnub_config_t cfg = pubnub_config_defaults();
cfg.subscribe_key = "demo";
cfg.user_id = "my_unique_user_id";

pubnub_context_t* ctx = pubnub_create(&cfg);
if (NULL == ctx) {
show all 39 lines

This sample is adapted from examples/channel_groups/remove_channels.c (cooperative polling).

Returns

pubnub_channel_group_remove_channels() returns a pubnub_future_t. On success, the future's status is PUBNUB_OK with no additional payload. There is no dedicated result-accessor function for this operation.

List channels in a channel group

pubnub_channel_group_list_channels() lists every channel currently in a channel group.

Method(s)

pubnub_future_t pubnub_channel_group_list_channels(pubnub_context_t* ctx, const pubnub_channel_group_list_opts_t* opts);
* required
ParameterDescription
channel_group *
Type: const char*
Default:
Borrowed, NUL-terminated. Target channel group name.
timeout_ms
Type: uint32_t
Default:
0 (inherits pubnub_config_t::transaction_timeout_ms)
A non-zero value overrides the context-level timeout for this call only.

This options struct has no channels field. Listing takes only the group name. Zero-initialize with PUBNUB_CHANNEL_GROUP_LIST_OPTS_INIT (expands to {0}).

C-family contract

  • Header#include <pubnub/features/channel_groups.h>
  • Typespubnub_channel_group_list_opts_t, pubnub_channel_group_list_result_t
  • Prerequisite — an initialized context with subscribe_key and user_id set; see Add channels
  • Feature flagPUBNUB_ENABLE_CHANNEL_GROUPS
  • Ownership / lifetimechannel_group is borrowed, NUL-terminated. Every pubnub_string_view_t returned by the result accessors below aliases internal response data. That data stays valid only until pubnub_future_release() is called on the same future, so copy the bytes out first if you need them afterward.
  • Blocking — never blocks; returns a pubnub_future_t immediately

Sample code

#include <pubnub/client.h>
#include <pubnub/features/channel_groups.h>
#include <pubnub/future.h>

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
pubnub_config_t cfg = pubnub_config_defaults();
cfg.subscribe_key = "demo";
cfg.user_id = "my_unique_user_id";

pubnub_context_t* ctx = pubnub_create(&cfg);
if (NULL == ctx) {
show all 42 lines

This sample is adapted from examples/channel_groups/list_channels.c (cooperative polling). Print with %.*s, exactly as shown. pubnub_string_view_t values are never NUL-terminated.

Returns

pubnub_channel_group_list_result_t   pubnub_channel_group_list_result(pubnub_future_t future);
pubnub_string_view_t pubnub_channel_group_list_result_channel_at(pubnub_future_t future, size_t index);

Call pubnub_channel_group_list_result(future) after the future completes with PUBNUB_OK. It returns pubnub_channel_group_list_result_t, a struct with a single field, count, the number of channels in the group. It is zero-initialized if the future is not ready or invalid.

Then iterate 0 <= i < count, calling pubnub_channel_group_list_result_channel_at(future, i) for each index to get a pubnub_string_view_t naming that channel. An out-of-range index returns a zero-initialized {NULL, 0} view rather than crashing.

Other examples

List channels with a callback

Adapted from examples/channel_groups/list_channels_async.c, which composes an add-then-list-then-delete flow as a teaching example. The listing step alone, in isolation, looks like this:

#include <pubnub/client.h>
#include <pubnub/features/channel_groups.h>
#include <pubnub/future.h>

#include <stdio.h>
#include <stdlib.h>

static volatile int s_list_done = 0;

static void on_list_complete(pubnub_future_t future, pubnub_res_t status, void* user_data)
{
(void)user_data;

if (PUBNUB_OK == status) {
pubnub_channel_group_list_result_t list = pubnub_channel_group_list_result(future);
show all 52 lines

Delete a channel group

pubnub_channel_group_remove() deletes a channel group entirely, including its membership list. This is a distinct operation from Remove channels from a channel group. That call removes individual channels and leaves the (possibly empty) group in place. This call removes the group itself.

Method(s)

pubnub_future_t pubnub_channel_group_remove(pubnub_context_t* ctx, const pubnub_channel_group_remove_group_opts_t* opts);
* required
ParameterDescription
channel_group *
Type: const char*
Default:
Borrowed, NUL-terminated. Channel group to delete.
timeout_ms
Type: uint32_t
Default:
0 (inherits pubnub_config_t::transaction_timeout_ms)
A non-zero value overrides the context-level timeout for this call only.

Zero-initialize with PUBNUB_CHANNEL_GROUP_REMOVE_GROUP_OPTS_INIT (expands to {0}).

C-family contract

  • Header#include <pubnub/features/channel_groups.h>
  • Typespubnub_channel_group_remove_group_opts_t
  • Prerequisite — an initialized context with subscribe_key and user_id set; see Add channels
  • Feature flagPUBNUB_ENABLE_CHANNEL_GROUPS
  • Ownership / lifetimechannel_group is borrowed, NUL-terminated
  • Blocking — never blocks; returns a pubnub_future_t immediately

Sample code

#include <pubnub/client.h>
#include <pubnub/features/channel_groups.h>
#include <pubnub/future.h>

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
pubnub_config_t cfg = pubnub_config_defaults();
cfg.subscribe_key = "demo";
cfg.user_id = "my_unique_user_id";

pubnub_context_t* ctx = pubnub_create(&cfg);
if (NULL == ctx) {
show all 38 lines

This sample is adapted from examples/channel_groups/delete_group.c (cooperative polling).

Returns

pubnub_channel_group_remove() returns a pubnub_future_t. On success, the future's status is PUBNUB_OK with no additional payload. There is no dedicated result-accessor function for this operation.

Error handling

pubnub_res_t is the single status type shared across every feature in this SDK, including channel groups. There are no per-feature error accessors. For the full result-code catalog and the pubnub_response_service_error() pattern for server-side error detail, see Status Events.

Two behaviors specific to channel groups are worth calling out:

  • Passing NULL for ctx or opts on any of the four functions on this page fails immediately with PUBNUB_ERR_INVALID_ARGUMENT, readable via pubnub_future_status() without polling or awaiting first.
  • On the wire, an HTTP 4xx response maps to PUBNUB_ERR_SERVER regardless of the response body, and a 200 response whose body contains "error":true also maps to PUBNUB_ERR_SERVER. Call pubnub_response_service_error() for normalized detail in either case. See Retrieving server error detail.