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);
| Parameter | Description |
|---|---|
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_msType: uint32_tDefault: 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> - Types —
pubnub_channel_group_add_opts_t - Prerequisite — an initialized context with
subscribe_keyanduser_idset. Every shipped example configures only those two keys for channel-group calls;publish_keyis not needed. - Feature flag —
PUBNUB_ENABLE_CHANNEL_GROUPS - Ownership / lifetime —
channel_groupandchannelsare borrowed, NUL-terminated strings; the SDK does not copy or retain them past the call - Blocking — never blocks; returns a
pubnub_future_timmediately
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 linesThis 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);
| Parameter | Description |
|---|---|
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_msType: uint32_tDefault: 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> - Types —
pubnub_channel_group_remove_opts_t - Prerequisite — an initialized context with
subscribe_keyanduser_idset; see Add channels - Feature flag —
PUBNUB_ENABLE_CHANNEL_GROUPS - Ownership / lifetime —
channel_groupandchannelsare borrowed, NUL-terminated strings - Blocking — never blocks; returns a
pubnub_future_timmediately
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 linesThis 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);
| Parameter | Description |
|---|---|
channel_group *Type: const char*Default: — | Borrowed, NUL-terminated. Target channel group name. |
timeout_msType: uint32_tDefault: 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> - Types —
pubnub_channel_group_list_opts_t,pubnub_channel_group_list_result_t - Prerequisite — an initialized context with
subscribe_keyanduser_idset; see Add channels - Feature flag —
PUBNUB_ENABLE_CHANNEL_GROUPS - Ownership / lifetime —
channel_groupis borrowed, NUL-terminated. Everypubnub_string_view_treturned by the result accessors below aliases internal response data. That data stays valid only untilpubnub_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_timmediately
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 linesThis 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 linesDelete 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);
| Parameter | Description |
|---|---|
channel_group *Type: const char*Default: — | Borrowed, NUL-terminated. Channel group to delete. |
timeout_msType: uint32_tDefault: 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> - Types —
pubnub_channel_group_remove_group_opts_t - Prerequisite — an initialized context with
subscribe_keyanduser_idset; see Add channels - Feature flag —
PUBNUB_ENABLE_CHANNEL_GROUPS - Ownership / lifetime —
channel_groupis borrowed, NUL-terminated - Blocking — never blocks; returns a
pubnub_future_timmediately
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 linesThis 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
NULLforctxoroptson any of the four functions on this page fails immediately withPUBNUB_ERR_INVALID_ARGUMENT, readable viapubnub_future_status()without polling or awaiting first. - On the wire, an HTTP 4xx response maps to
PUBNUB_ERR_SERVERregardless of the response body, and a200response whose body contains"error":truealso maps toPUBNUB_ERR_SERVER. Callpubnub_response_service_error()for normalized detail in either case. See Retrieving server error detail.